NxrViewer.cs 98 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902
  1. // Copyright 2019 Nibiru. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. using UnityEngine;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Collections;
  18. using NibiruTask;
  19. using NibiruAxis;
  20. using UnityEngine.SceneManagement;
  21. namespace Nxr.Internal
  22. {
  23. /// <summary>
  24. ///
  25. /// </summary>
  26. [AddComponentMenu("NXR/NxrViewer")]
  27. public class NxrViewer : MonoBehaviour
  28. {
  29. // base 2.3.0.xxxx release
  30. public const string NXR_SDK_VERSION = "2.5.0.0_20220121";
  31. // 退出Kill Process
  32. public const bool IsAndroidKillProcess = true;
  33. // dtr or not
  34. public static bool USE_DTR = true;
  35. private static int _texture_count = 6;
  36. // 绘制前事件标识
  37. public static int kPreRenderEvent = 1;
  38. // 头部角度限制范围
  39. private float[] headEulerAnglesRange = null;
  40. private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
  41. {
  42. Debug.Log("OnSceneLoaded->" + scene.name + " , Triggered=" + Triggered);
  43. SceneManager.sceneLoaded -= OnSceneLoaded;
  44. }
  45. /// The singleton instance of the NvrViewer class.
  46. public static NxrViewer Instance
  47. {
  48. get
  49. {
  50. #if UNITY_EDITOR || UNITY_STANDALONE_WIN
  51. USE_DTR = false;
  52. if (instance == null && !Application.isPlaying)
  53. {
  54. Debug.Log("Create NxrViewer Instance !");
  55. instance = FindObjectOfType<NxrViewer>();
  56. }
  57. #endif
  58. if (instance == null)
  59. {
  60. Debug.LogError("No NxrViewer instance found. Ensure one exists in the scene, or call "
  61. + "NxrViewer.Create() at startup to generate one.\n"
  62. + "If one does exist but hasn't called Awake() yet, "
  63. + "then this error is due to order-of-initialization.\n"
  64. + "In that case, consider moving "
  65. + "your first reference to NxrViewer.Instance to a later point in time.\n"
  66. + "If exiting the scene, this indicates that the NxrViewer object has already "
  67. + "been destroyed.");
  68. }
  69. return instance;
  70. }
  71. }
  72. private static NxrViewer instance = null;
  73. public NxrEye[] eyes = new NxrEye[2];
  74. private byte[] winTypeName = new byte[]
  75. {110, 120, 114, 46, 78, 118, 114, 87, 105, 110, 66, 97, 115, 101}; //N/v/r/W/i/n/B/a/s/e
  76. /// Generate a NxrViewer instance. Takes no action if one already exists.
  77. public static void Create()
  78. {
  79. if (instance == null && FindObjectOfType<NxrViewer>() == null)
  80. {
  81. Debug.Log("Creating NxrViewerMain object");
  82. var go = new GameObject("NxrViewerMain", typeof(NxrViewer));
  83. go.transform.localPosition = Vector3.zero;
  84. // sdk will be set by Awake().
  85. }
  86. }
  87. /// The StereoController instance attached to the main camera, or null if there is none.
  88. /// @note Cached for performance.
  89. public NxrStereoController Controller
  90. {
  91. get
  92. {
  93. if (currentController == null)
  94. {
  95. currentController = FindObjectOfType<NxrStereoController>();
  96. }
  97. return currentController;
  98. }
  99. }
  100. private NxrStereoController currentController;
  101. [SerializeField] public HMD_TYPE HmdType = HMD_TYPE.NONE;
  102. /// Whether to draw directly to the output window (_true_), or to an offscreen buffer
  103. /// first and then blit (_false_). If you wish to use Deferred Rendering or any
  104. /// Image Effects in stereo, turn this option off. A common symptom that indicates
  105. /// you should do so is when one of the eyes is spread across the entire screen.
  106. [SerializeField] private bool openEffectRender = false;
  107. /// <summary>
  108. /// false-Processing after closing,true-Processing after opening
  109. /// </summary>
  110. public bool OpenEffectRender
  111. {
  112. get { return openEffectRender; }
  113. set
  114. {
  115. if (value != openEffectRender)
  116. {
  117. openEffectRender = value;
  118. }
  119. }
  120. }
  121. /// Determine whether the scene renders in stereo or mono.
  122. /// _True_ means to render in stereo, and _false_ means to render in mono.
  123. public bool SplitScreenModeEnabled
  124. {
  125. get { return splitScreenModeEnabled; }
  126. set
  127. {
  128. if (value != splitScreenModeEnabled && device != null)
  129. {
  130. device.SetSplitScreenModeEnabled(value);
  131. }
  132. splitScreenModeEnabled = value;
  133. }
  134. }
  135. [SerializeField] private bool splitScreenModeEnabled = true;
  136. /// <summary>
  137. /// Get/Set Head Control
  138. /// </summary>
  139. public HeadControl HeadControl
  140. {
  141. get { return headControlEnabled; }
  142. set
  143. {
  144. headControlEnabled = value;
  145. UpdateHeadControl();
  146. }
  147. }
  148. [SerializeField] private HeadControl headControlEnabled = HeadControl.GazeApplication;
  149. public float Duration
  150. {
  151. get { return duration; }
  152. set { duration = value; }
  153. }
  154. [SerializeField] private float duration = 2;
  155. NxrReticle mNxrReticle;
  156. public NxrReticle GetNxrReticle()
  157. {
  158. InitNxrReticleScript();
  159. return mNxrReticle;
  160. }
  161. public void DismissReticle()
  162. {
  163. GetNxrReticle().Dismiss();
  164. }
  165. public void ShowReticle()
  166. {
  167. GetNxrReticle().Show();
  168. }
  169. private void InitNxrReticleScript()
  170. {
  171. if (mNxrReticle == null)
  172. {
  173. GameObject nxrReticleObject = GameObject.Find("NxrReticle");
  174. if (nxrReticleObject != null)
  175. {
  176. mNxrReticle = nxrReticleObject.GetComponent<NxrReticle>();
  177. if (mNxrReticle == null)
  178. {
  179. Debug.LogError("Not Find NxrReticle.cs From GameObject NxrReticle !!!");
  180. }
  181. }
  182. else
  183. {
  184. Debug.LogError("Not Find NxrReticle GameObject !!!");
  185. }
  186. }
  187. }
  188. /// <summary>
  189. /// Show head control
  190. /// </summary>
  191. public void ShowHeadControl()
  192. {
  193. InitNxrReticleScript();
  194. if (mNxrReticle != null)
  195. {
  196. mNxrReticle.HeadShow();
  197. Debug.Log("ShowHeadControl");
  198. }
  199. }
  200. /// <summary>
  201. /// Hide head control
  202. /// </summary>
  203. public void HideHeadControl()
  204. {
  205. InitNxrReticleScript();
  206. if (mNxrReticle != null)
  207. {
  208. mNxrReticle.HeadDismiss();
  209. Debug.Log("HideHeadControl");
  210. }
  211. }
  212. // App自行处理Trigger按键,SDK不处理。如果SDK处理默认当做确认键使用。
  213. /// <summary>
  214. /// Is app handle trigger event
  215. /// </summary>
  216. public bool IsAppHandleTriggerEvent
  217. {
  218. get { return appHandleTriggerEvent; }
  219. set { appHandleTriggerEvent = value; }
  220. }
  221. [SerializeField] private bool appHandleTriggerEvent = false;
  222. public bool TrackerPosition
  223. {
  224. get { return trackerPosition; }
  225. set { trackerPosition = value; }
  226. }
  227. /// <summary>
  228. /// Whether to use third-party displacement data.
  229. /// </summary>
  230. public bool UseThirdPartyPosition
  231. {
  232. get { return useThirdPartyPosition; }
  233. set { useThirdPartyPosition = value; }
  234. }
  235. [SerializeField] private bool useThirdPartyPosition = false;
  236. #if UNITY_STANDALONE_WIN || ANDROID_REMOTE_NRR
  237. [SerializeField]
  238. private FrameRate targetFrameRate = FrameRate.FPS_60;
  239. public FrameRate TargetFrameRate
  240. {
  241. get
  242. {
  243. return targetFrameRate;
  244. }
  245. set
  246. {
  247. if (value != targetFrameRate)
  248. {
  249. targetFrameRate = value;
  250. }
  251. }
  252. }
  253. #endif
  254. // 纹理抗锯齿
  255. [SerializeField] public TextureMSAA textureMsaa = TextureMSAA.MSAA_2X;
  256. public TextureMSAA TextureMSAA
  257. {
  258. get { return textureMsaa; }
  259. set
  260. {
  261. if (value != textureMsaa)
  262. {
  263. textureMsaa = value;
  264. }
  265. }
  266. }
  267. [SerializeField] private bool trackerPosition = true;
  268. [Serializable]
  269. public class NxrSettings
  270. {
  271. [Tooltip("Change Timewarp Status")] public int timewarpEnabled = -1; //-1=not set,0=close,1=open
  272. [Tooltip("Change Sync Frame Status")] public bool syncFrameEnabled = false;
  273. }
  274. [SerializeField] public NxrSettings settings = new NxrViewer.NxrSettings();
  275. // Remote Debug
  276. [SerializeField] private bool remoteDebug = false;
  277. public bool RemoteDebug
  278. {
  279. get { return remoteDebug; }
  280. set
  281. {
  282. if (value != remoteDebug)
  283. {
  284. remoteDebug = value;
  285. }
  286. }
  287. }
  288. [SerializeField] private bool remoteController = false;
  289. public bool RemoteController
  290. {
  291. get { return remoteController; }
  292. set
  293. {
  294. if (value != remoteController)
  295. {
  296. remoteController = value;
  297. }
  298. }
  299. }
  300. // FPS
  301. [SerializeField] private bool showFPS = false;
  302. public bool ShowFPS
  303. {
  304. get { return showFPS; }
  305. set
  306. {
  307. if (value != showFPS)
  308. {
  309. showFPS = value;
  310. }
  311. }
  312. }
  313. // 纹理质量
  314. [SerializeField] public TextureQuality textureQuality = TextureQuality.Better;
  315. public TextureQuality TextureQuality
  316. {
  317. get { return textureQuality; }
  318. set
  319. {
  320. if (value != textureQuality)
  321. {
  322. textureQuality = value;
  323. }
  324. }
  325. }
  326. [SerializeField] private bool requestLock = false;
  327. /// <summary>
  328. /// Lock head tracker.
  329. /// </summary>
  330. public bool LockHeadTracker
  331. {
  332. get { return requestLock; }
  333. set
  334. {
  335. if (value != requestLock)
  336. {
  337. requestLock = value;
  338. }
  339. }
  340. }
  341. public bool InitialRecenter { get; set; }
  342. /// <summary>
  343. /// Lock head posture.
  344. /// </summary>
  345. public void RequestLock()
  346. {
  347. if (device != null)
  348. {
  349. device.NLockTracker();
  350. }
  351. }
  352. /// <summary>
  353. /// Unlock head posture.
  354. /// </summary>
  355. public void RequestUnLock()
  356. {
  357. if (device != null)
  358. {
  359. device.NUnLockTracker();
  360. }
  361. }
  362. private bool IsNativeGazeShow = false;
  363. /// <summary>
  364. /// Change Gaze's size/color/status
  365. /// </summary>
  366. /// <param name="tag"></param>
  367. public void GazeApi(GazeTag tag)
  368. {
  369. GazeApi(tag, "");
  370. }
  371. public void TurnOff()
  372. {
  373. device.TurnOff();
  374. }
  375. public void Reboot()
  376. {
  377. device.Reboot();
  378. }
  379. /// <summary>
  380. /// The parameter of Param behind GazeTag.Show and GazeTag.Hide is passed "".
  381. /// </summary>
  382. /// <param name="tag"></param>
  383. /// <param name="param"></param>
  384. public void GazeApi(GazeTag tag, string param)
  385. {
  386. if (device != null)
  387. {
  388. bool rslt = device.GazeApi(tag, param);
  389. if (tag == GazeTag.Show)
  390. {
  391. bool useDFT = USE_DTR && !NxrGlobal.supportDtr;
  392. IsNativeGazeShow = useDFT ? true : rslt;
  393. }
  394. else if (tag == GazeTag.Hide)
  395. {
  396. IsNativeGazeShow = false;
  397. }
  398. }
  399. }
  400. /// <summary>
  401. /// Switch to controller mode
  402. /// </summary>
  403. /// <param name="enabled"></param>
  404. public void SwitchControllerMode(bool enabled)
  405. {
  406. // Debug.LogError("SwitchControllerMode:" + enabled);
  407. if (enabled)
  408. {
  409. HeadControl = HeadControl.Controller;
  410. }
  411. else
  412. {
  413. //
  414. HeadControl = HeadControl.GazeApplication;
  415. }
  416. }
  417. /// <summary>
  418. /// Switch application reticle mode
  419. /// true-force using reticle
  420. /// false-use system reticle
  421. /// </summary>
  422. /// <param name="enabled"></param>
  423. private void SwitchApplicationReticle(bool enabled)
  424. {
  425. InitNxrReticleScript();
  426. bool IsControllerMode = HeadControl == HeadControl.Controller;
  427. if (enabled)
  428. {
  429. if (mNxrReticle != null) mNxrReticle.Show();
  430. GazeInputModule.gazePointer = mNxrReticle;
  431. }
  432. else if (!enabled && (!NxrGlobal.isVR9Platform || IsControllerMode))
  433. {
  434. if (mNxrReticle != null)
  435. {
  436. mNxrReticle.Dismiss();
  437. }
  438. GazeInputModule.gazePointer = null;
  439. }
  440. if (enabled)
  441. {
  442. GazeApi(GazeTag.Hide);
  443. }
  444. }
  445. #if UNITY_EDITOR || UNITY_STANDALONE_WIN
  446. /// The screen size to emulate when testing in the Unity Editor.
  447. public NxrProfile.ScreenSizes ScreenSize
  448. {
  449. get { return screenSize; }
  450. set
  451. {
  452. if (value != screenSize)
  453. {
  454. screenSize = value;
  455. if (device != null)
  456. {
  457. device.UpdateScreenData();
  458. }
  459. }
  460. }
  461. }
  462. [SerializeField] private NxrProfile.ScreenSizes screenSize = NxrProfile.ScreenSizes.Nexus5;
  463. /// The viewer type to emulate when testing in the Unity Editor.
  464. public NxrProfile.ViewerTypes ViewerType
  465. {
  466. get { return viewerType; }
  467. set
  468. {
  469. if (value != viewerType)
  470. {
  471. viewerType = value;
  472. if (device != null)
  473. {
  474. device.UpdateScreenData();
  475. }
  476. }
  477. }
  478. }
  479. [SerializeField] private NxrProfile.ViewerTypes viewerType = NxrProfile.ViewerTypes.CardboardMay2015;
  480. #endif
  481. // The AR device that will be providing input data.
  482. private static BaseARDevice device;
  483. public RenderTexture GetStereoScreen(int eye)
  484. {
  485. // Don't need it except for distortion correction.
  486. if (!splitScreenModeEnabled || NxrGlobal.isVR9Platform)
  487. {
  488. return null;
  489. }
  490. if (eyeStereoScreens[0] == null)
  491. {
  492. // 初始化6个纹理
  493. InitEyeStereoScreens();
  494. }
  495. if (Application.isEditor || (NxrViewer.USE_DTR && !NxrGlobal.supportDtr))
  496. {
  497. // DFT or Editor
  498. return eyeStereoScreens[0];
  499. }
  500. // 获取对应索引的纹理
  501. return eyeStereoScreens[eye + _current_texture_index];
  502. }
  503. // 初始创建6个纹理,左右各3个 【左右左右左右】
  504. public RenderTexture[] eyeStereoScreens = new RenderTexture[_texture_count];
  505. private void InitEyeStereoScreens()
  506. {
  507. InitEyeStereoScreens(-1, -1);
  508. }
  509. // 初始化
  510. private void InitEyeStereoScreens(int width, int height)
  511. {
  512. RealeaseEyeStereoScreens();
  513. #if UNITY_ANDROID || UNITY_EDITOR || UNITY_STANDALONE_WIN
  514. bool useDFT = NxrViewer.USE_DTR && !NxrGlobal.supportDtr;
  515. if (!USE_DTR || useDFT || IsWinPlatform)
  516. {
  517. // 编辑器模式 or 不支持DTR的DFT模式 只生成1个纹理
  518. RenderTexture rendetTexture = device.CreateStereoScreen(width, height);
  519. if (!rendetTexture.IsCreated())
  520. {
  521. rendetTexture.Create();
  522. }
  523. int tid = (int) rendetTexture.GetNativeTexturePtr();
  524. for (int i = 0; i < _texture_count; i++)
  525. {
  526. eyeStereoScreens[i] = rendetTexture;
  527. _texture_ids[i] = tid;
  528. }
  529. }
  530. else
  531. {
  532. for (int i = 0; i < _texture_count; i++)
  533. {
  534. eyeStereoScreens[i] = device.CreateStereoScreen(width, height);
  535. eyeStereoScreens[i].Create();
  536. _texture_ids[i] = (int) eyeStereoScreens[i].GetNativeTexturePtr();
  537. }
  538. }
  539. #endif
  540. }
  541. // 释放所有纹理
  542. private void RealeaseEyeStereoScreens()
  543. {
  544. for (int i = 0; i < _texture_count; i++)
  545. {
  546. if (eyeStereoScreens[i] != null)
  547. {
  548. eyeStereoScreens[i].Release();
  549. eyeStereoScreens[i] = null;
  550. _texture_ids[i] = 0;
  551. }
  552. }
  553. Resources.UnloadUnusedAssets();
  554. Debug.Log("RealeaseEyeStereoScreens");
  555. }
  556. /// Describes the current device, including phone screen.
  557. public NxrProfile Profile
  558. {
  559. get { return device.Profile; }
  560. }
  561. /// Distinguish the stereo eyes.
  562. public enum Eye
  563. {
  564. Left,
  565. /// The left eye
  566. Right,
  567. /// The right eye
  568. Center /// The "center" eye (unused)
  569. }
  570. /// When retrieving the #Projection and #Viewport properties, specifies
  571. /// whether you want the values as seen through the viewer's lenses (`Distorted`) or
  572. /// as if no lenses were present (`Undistorted`).
  573. public enum Distortion
  574. {
  575. Distorted,
  576. /// Viewing through the lenses
  577. Undistorted /// No lenses
  578. }
  579. /// The transformation of head from origin in the tracking system.
  580. public Pose3D HeadPose
  581. {
  582. get { return device.GetHeadPose(); }
  583. }
  584. /// The projection matrix for a given eye.
  585. /// This matrix is an off-axis perspective projection with near and far
  586. /// clipping planes of 1m and 1000m, respectively. The NxrEye script
  587. /// takes care of adjusting the matrix for its particular camera.
  588. public Matrix4x4 Projection(Eye eye, Distortion distortion = Distortion.Distorted)
  589. {
  590. return device.GetProjection(eye, distortion);
  591. }
  592. /// The screen space viewport that the camera for the specified eye should render into.
  593. /// In the _Distorted_ case, this will be either the left or right half of the `StereoScreen`
  594. /// render texture. In the _Undistorted_ case, it refers to the actual rectangle on the
  595. /// screen that the eye can see.
  596. public Rect Viewport(Eye eye, Distortion distortion = Distortion.Distorted)
  597. {
  598. return device.GetViewport(eye, distortion);
  599. }
  600. private void InitDevice()
  601. {
  602. if (device != null)
  603. {
  604. device.Destroy();
  605. }
  606. // 根据当前运行场景获取对应的设备对象
  607. device = BaseARDevice.GetDevice();
  608. device.Init();
  609. device.SetSplitScreenModeEnabled(splitScreenModeEnabled);
  610. // 更新界面数据
  611. device.UpdateScreenData();
  612. GazeApi(GazeTag.Show);
  613. GazeApi(GazeTag.Set_Size, ((int) GazeSize.Original).ToString());
  614. }
  615. // Windows Editor/Player
  616. public bool IsWinPlatform { get; set; }
  617. NxrInput nxrInput;
  618. /// @note Each scene load causes an OnDestroy of the current SDK, followed
  619. /// by and Awake of a new one. That should not cause the underlying native
  620. /// code to hiccup. Exception: developer may call Application.DontDestroyOnLoad
  621. /// on the SDK if they want it to survive across scene loads.
  622. void Awake()
  623. {
  624. Debug.Log("NxrViewer Awake");
  625. SettingsAssetConfig asset;
  626. #if UNITY_EDITOR
  627. asset = NxrSDKApi.Instance.GetSettingsAssetConfig();
  628. #else
  629. asset = Resources.Load<SettingsAssetConfig>("Config/SettingsAssetConfig");
  630. #endif
  631. sixDofMode = asset.mSixDofMode;
  632. sleepTimeoutMode = asset.mSleepTimeoutMode;
  633. headControlEnabled = asset.mHeadControl;
  634. textureQuality = asset.mTextureQuality;
  635. textureMsaa = asset.mTextureMSAA;
  636. InitialRecenter = true;
  637. nxrInput = new NxrInput();
  638. IsWinPlatform = false;
  639. Debug.Log("SettingsAssetConfig:" + asset.mSixDofMode + "--" + asset.mSleepTimeoutMode + "--" +
  640. asset.mHeadControl + "--" + asset.mTextureQuality + "--" + asset.mTextureMSAA);
  641. #if UNITY_STANDALONE_WIN || ANDROID_REMOTE_NRR
  642. IsWinPlatform = true;
  643. #endif
  644. if (instance == null)
  645. {
  646. instance = this;
  647. Loom.Initialize();
  648. if (Application.isMobilePlatform)
  649. {
  650. QualitySettings.antiAliasing = 0;
  651. Application.runInBackground = false;
  652. Input.gyro.enabled = false;
  653. Debug.Log("SleepTimeout:" + SleepMode.ToString());
  654. if (SleepMode == SleepTimeoutMode.NEVER_SLEEP)
  655. {
  656. // Disable screen dimming
  657. Screen.sleepTimeout = SleepTimeout.NeverSleep;
  658. }
  659. else
  660. {
  661. Screen.sleepTimeout = SleepTimeout.SystemSetting;
  662. }
  663. }
  664. }
  665. if (instance != this)
  666. {
  667. Debug.LogError("There must be only one NxrViewer object in a scene.");
  668. DestroyImmediate(this);
  669. return;
  670. }
  671. UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;
  672. #if !UNITY_EDITOR && UNITY_STANDALONE_WIN
  673. // 编辑器PASS
  674. nxr.NibiruXR.instance.Init(gameObject);
  675. #endif
  676. InitDevice();
  677. if (!IsWinPlatform && !NxrGlobal.supportDtr && !NxrGlobal.isVR9Platform)
  678. {
  679. // 录屏功能需要使用2个脚本 [VR9不需要]
  680. // 非DTR需要
  681. AddPrePostRenderStages();
  682. }
  683. Debug.Log("Is Windows Platform : " + IsWinPlatform + ", ScreenInfo : " + Screen.width + "*" +
  684. Screen.height + ", AntiAliasing : " + QualitySettings.antiAliasing);
  685. #if UNITY_ANDROID
  686. // 在unity20172.0f3版本使用-1相当于half vsync,所以此处设置为90fps。目前机器最高就是90
  687. int targetFrameRate = Application.platform == RuntimePlatform.Android
  688. ? ((int) NxrGlobal.refreshRate > 0 ? (int) NxrGlobal.refreshRate : 90)
  689. : 60;
  690. if (NxrGlobal.isVR9Platform)
  691. {
  692. // 参考全志官方
  693. targetFrameRate = 60;
  694. textureMsaa = TextureMSAA.NONE;
  695. }
  696. Application.targetFrameRate = targetFrameRate;
  697. #endif
  698. if (Application.platform != RuntimePlatform.Android)
  699. {
  700. NxrSDKApi.Instance.IsInXRMode = true;
  701. }
  702. // not use dtr //
  703. if (!NxrGlobal.supportDtr || NxrGlobal.isVR9Platform)
  704. {
  705. QualitySettings.vSyncCount = 1;
  706. if (NxrGlobal.offaxisDistortionEnabled)
  707. {
  708. Application.targetFrameRate = Application.platform == RuntimePlatform.Android
  709. ? (int) NxrGlobal.refreshRate
  710. : -1;
  711. Debug.Log("offaxisDistortionEnabled : Setting frame rate to " + Application.targetFrameRate);
  712. }
  713. }
  714. else
  715. {
  716. // we sync in the TimeWarp, so we don't want unity syncing elsewhere
  717. QualitySettings.vSyncCount = 0;
  718. }
  719. #if UNITY_STANDALONE_WIN || ANDROID_REMOTE_NRR
  720. if (IsWinPlatform)
  721. {
  722. QualitySettings.vSyncCount = 0;
  723. Application.targetFrameRate = (int)targetFrameRate;
  724. // don't require companion window focus
  725. Application.runInBackground = true;
  726. QualitySettings.maxQueuedFrames = -1;
  727. QualitySettings.antiAliasing = Mathf.Max(QualitySettings.antiAliasing, (int)TextureMSAA);
  728. }
  729. #endif
  730. #if UNITY_ANDROID && UNITY_EDITOR
  731. //GraphicsDeviceType[] graphicsDeviceType = UnityEditor.PlayerSettings.GetGraphicsAPIs(UnityEditor.BuildTarget.Android);
  732. // Debug.Log("GraphicsDeviceType------->" + graphicsDeviceType[0].ToString());
  733. //if (graphicsDeviceType[0] != GraphicsDeviceType.OpenGLES2)
  734. //{
  735. // string title = "Incompatible graphics API detected!";
  736. // string message = "Please set graphics API to \"OpenGL ES 2.0\" and rebuild, or Some Api may not work as expected .";
  737. // UnityEditor.EditorUtility.DisplayDialog(title, message, "OK");
  738. // Debug.LogError(title + " " + message);
  739. //}
  740. #if UNITY_EDITOR
  741. string defineSymbols =
  742. UnityEditor.PlayerSettings.GetScriptingDefineSymbolsForGroup(UnityEditor.BuildTargetGroup.Android);
  743. if (defineSymbols == null || !defineSymbols.Contains("NIBIRU_"))
  744. {
  745. string title = "Hmd Type Not Configed!";
  746. string message = "Please Choose Hmd Type in Menu \nNibiruXR->XR Settings .";
  747. UnityEditor.EditorUtility.DisplayDialog(title, message, "OK");
  748. Debug.LogError(title + " " + message);
  749. }
  750. #endif
  751. #endif
  752. device.AndroidLog("Welcome to use Unity NXR SDK , current SDK VERSION is " + NXR_SDK_VERSION + ", j " +
  753. NxrGlobal.jarVersion
  754. + ", s " + NxrGlobal.soVersion + ", u " + Application.unityVersion + ", fps " +
  755. Application.targetFrameRate + ", vsync "
  756. + QualitySettings.vSyncCount + ", hmd " + HmdType + ", antiAliasing : " +
  757. QualitySettings.antiAliasing
  758. + ", SixDofMode : " + sixDofMode.ToString());
  759. AddStereoControllerToCameras();
  760. }
  761. public delegate void NibiruConfigCallback(NxrInstantNativeApi.Nibiru_Config cfg);
  762. NibiruConfigCallback _nvrConfigCallback;
  763. void Start()
  764. {
  765. //lx changed for 5.4:在Awake中执行,不然在NxrArmModel调用之前Head还没创建
  766. //AddStereoControllerToCameras();
  767. if (IsWinPlatform)
  768. {
  769. // 初始化光学参数
  770. _nvrConfigCallback += OnNibiruConfigCallback;
  771. NxrInstantNativeApi.SetNibiruConfigCallback(_nvrConfigCallback);
  772. #if NIBIRU_DEBUG
  773. NvrInstantNativeApi.Inited = false;
  774. Debug.Log("NvrInstantNativeApi.Init.Not Called.");
  775. #else
  776. int _textureWidth = 1920, _textureHeight = 1080;
  777. NxrInstantNativeApi.NvrInitParams param;
  778. param.renderWidth = _textureWidth;
  779. param.renderHeight = _textureHeight;
  780. param.bitRate = 30;
  781. NxrInstantNativeApi.Inited = NxrInstantNativeApi.Init(param);
  782. Debug.Log("NxrInstantNativeApi.Init.Called.");
  783. NxrInstantNativeApi.GetVersionInfo(ref NxrInstantNativeApi.nativeApiVersion,
  784. ref NxrInstantNativeApi.driverVersion);
  785. Debug.Log("NxrInstantNativeApi.Version.Api." + NxrInstantNativeApi.nativeApiVersion + ",Driver." +
  786. NxrInstantNativeApi.driverVersion);
  787. if (NxrInstantNativeApi.nativeApiVersion >= 2000)
  788. {
  789. NxrInstantNativeApi.GetTextureResolution(ref _textureWidth, ref _textureHeight);
  790. if (NxrInstantNativeApi.driverVersion >= 2002)
  791. {
  792. UInt32 rateData = NxrInstantNativeApi.GetRefreshRate();
  793. Debug.Log("-------------rateData--------" + rateData);
  794. if (rateData >= 60)
  795. {
  796. Application.targetFrameRate = (int) rateData;
  797. }
  798. }
  799. }
  800. if (eyeStereoScreens[0] == null && !NxrGlobal.isVR9Platform)
  801. {
  802. // 初始化6个纹理
  803. InitEyeStereoScreens(_textureWidth, _textureHeight);
  804. }
  805. if (eyeStereoScreens[0] != null)
  806. {
  807. // 设置Texturew Native Ptr
  808. NxrInstantNativeApi.SetFrameTexture(eyeStereoScreens[0].GetNativeTexturePtr());
  809. Debug.Log("NxrInstantNativeApi.SetFrameTexture." + eyeStereoScreens[0].GetNativeTexturePtr());
  810. }
  811. #endif
  812. Debug.Log("NxrInstantNativeApi.Init. Size " + param.renderWidth + "*" + param.renderHeight + ", Bit " +
  813. param.bitRate + ", Inited " + NxrInstantNativeApi.Inited);
  814. }
  815. else
  816. {
  817. if (eyeStereoScreens[0] == null && !NxrGlobal.isVR9Platform)
  818. {
  819. // 初始化6个纹理
  820. InitEyeStereoScreens();
  821. device.SetTextureSizeNative(eyeStereoScreens[0].width, eyeStereoScreens[1].height);
  822. }
  823. }
  824. if (ShowFPS)
  825. {
  826. Transform[] father;
  827. father = GetComponentsInChildren<Transform>(true);
  828. GameObject FPS = null;
  829. foreach (Transform child in father)
  830. {
  831. if (child.gameObject.name == "NxrFPS")
  832. {
  833. FPS = child.gameObject;
  834. break;
  835. }
  836. }
  837. if (FPS != null)
  838. {
  839. FPS.SetActive(ShowFPS);
  840. }
  841. else
  842. {
  843. GameObject fpsGo = Instantiate(Resources.Load("Prefabs/NxrFPS")) as GameObject;
  844. #if UNITY_ANDROID && !UNITY_EDITOR
  845. fpsGo.GetComponent<NxrFPS>().enabled = false;
  846. fpsGo.AddComponent<FpsStatistics>();
  847. #else
  848. fpsGo.GetComponent<NxrFPS>().enabled = true;
  849. #endif
  850. }
  851. }
  852. UpdateHeadControl();
  853. NxrSDKApi.Instance.SixDofControllerPrimaryDeviceType = device.GetSixDofControllerPrimaryDeviceType();
  854. // 6dof双手柄
  855. gameObject.AddComponent<NxrControllerManager>();
  856. }
  857. public void UpdateHeadControl()
  858. {
  859. return;
  860. // Debug.LogError("UpdateHeadControl=" + HeadControl.ToString());
  861. // 已经设置强制使用Unity白点,不做处理
  862. switch (HeadControl)
  863. {
  864. case HeadControl.GazeApplication:
  865. SwitchApplicationReticle(true);
  866. GetNxrReticle().HeadDismiss();
  867. break;
  868. case HeadControl.GazeSystem:
  869. SwitchApplicationReticle(false);
  870. GetNxrReticle().HeadDismiss();
  871. GazeApi(GazeTag.Show);
  872. break;
  873. case HeadControl.Hover:
  874. GetNxrReticle().HeadShow();
  875. SwitchApplicationReticle(true);
  876. break;
  877. case HeadControl.Controller:
  878. SwitchApplicationReticle(false);
  879. GetNxrReticle().HeadDismiss();
  880. GazeApi(GazeTag.Hide);
  881. break;
  882. }
  883. }
  884. private NxrHead head;
  885. /// <summary>
  886. /// Get the NxrHead
  887. /// </summary>
  888. /// <returns></returns>
  889. public NxrHead GetHead()
  890. {
  891. if (head == null && Controller != null)
  892. {
  893. head = Controller.Head;
  894. }
  895. if (head == null)
  896. {
  897. head = FindObjectOfType<NxrHead>();
  898. }
  899. return head;
  900. }
  901. /// <summary>
  902. /// The displacement data of Third-party.
  903. /// </summary>
  904. /// <param name="position"></param>
  905. public void Update3rdPartyPosition(Vector3 position)
  906. {
  907. NxrHead mHead = GetHead();
  908. if (mHead != null)
  909. {
  910. mHead.Update3rdPartyPosition(position);
  911. }
  912. }
  913. private void OnNibiruConfigCallback(NxrInstantNativeApi.Nibiru_Config cfg)
  914. {
  915. Loom.QueueOnMainThread((param) =>
  916. {
  917. device.Profile.viewer.lenses.separation = cfg.ipd;
  918. //-0.03048, 0.03, -0.03402, 0.03402
  919. device.ComputeEyesForWin(NxrViewer.Eye.Left, cfg.near, 1000, cfg.eyeFrustumParams[0],
  920. cfg.eyeFrustumParams[3], cfg.eyeFrustumParams[1], cfg.eyeFrustumParams[2]);
  921. //-0.03, 0.03048, -0.03402, 0.03402
  922. device.ComputeEyesForWin(NxrViewer.Eye.Right, cfg.near, 1000, cfg.eyeFrustumParams[4],
  923. cfg.eyeFrustumParams[7], cfg.eyeFrustumParams[5], cfg.eyeFrustumParams[6]);
  924. // 手柄类型
  925. NxrControllerHelper.InitController((int) cfg.controllerType);
  926. device.profileChanged = true;
  927. Debug.Log("OnNibiruConfigCallback Config : Ipd " + cfg.ipd + ", Near " + cfg.near +
  928. ", FrustumLeft(LRBT) " + cfg.eyeFrustumParams[0] + ", " + cfg.eyeFrustumParams[1] + ","
  929. + cfg.eyeFrustumParams[2] + ", " + cfg.eyeFrustumParams[3] + ", ControllerType " +
  930. cfg.controllerType);
  931. TrackerPosition = true;
  932. {
  933. NxrHead head = GetHead();
  934. if (head != null)
  935. {
  936. head.SetTrackPosition(TrackerPosition);
  937. }
  938. }
  939. NxrButtonEvent mNvrButtonEvent = GameObject.FindObjectOfType<NxrButtonEvent>();
  940. if (mNvrButtonEvent != null)
  941. {
  942. mNvrButtonEvent.RefreshTrackedDevices();
  943. }
  944. device.profileChanged = true;
  945. }, cfg);
  946. }
  947. private int baseTryTimes = 1;
  948. private void Update()
  949. {
  950. UpdateState();
  951. if (!NxrGlobal.isVR9Platform)
  952. {
  953. UpdateEyeTexture();
  954. }
  955. if (GazeInputModule.gazePointer != null)
  956. {
  957. GazeInputModule.gazePointer.UpdateStatus();
  958. }
  959. #if !UNITY_EDITOR && UNITY_STANDALONE_WIN
  960. if (baseTryTimes < 5 && gameObject.GetComponent(System.Text.Encoding.Default.GetString(winTypeName)) == null)
  961. {
  962. baseTryTimes++;
  963. nxr.NibiruXR.instance.Init(gameObject);
  964. Debug.Log("Run NibiruXR Init in Update(), " + baseTryTimes);
  965. }
  966. #endif
  967. if (nxrInput != null)
  968. {
  969. nxrInput.Process();
  970. }
  971. }
  972. public BaseARDevice GetDevice()
  973. {
  974. return device;
  975. }
  976. /// <summary>
  977. /// Print log using android logcat.
  978. /// </summary>
  979. /// <param name="msg"></param>
  980. public void AndroidLog(string msg)
  981. {
  982. if (device != null)
  983. {
  984. device.AndroidLog(msg);
  985. }
  986. else
  987. {
  988. Debug.Log(msg);
  989. }
  990. }
  991. public void UpdateHeadPose()
  992. {
  993. if (device != null && NxrSDKApi.Instance.IsInXRMode)
  994. device.UpdateState();
  995. }
  996. public void UpdateEyeTexture()
  997. {
  998. // 更新左右眼目标纹理
  999. if (USE_DTR && NxrGlobal.supportDtr)
  1000. {
  1001. // 更换纹理索引
  1002. SwapBuffers();
  1003. NxrEye[] eyes = NxrViewer.Instance.eyes;
  1004. for (int i = 0; i < 2; i++)
  1005. {
  1006. NxrEye eye = eyes[i];
  1007. if (eye != null)
  1008. {
  1009. eye.UpdateTargetTexture();
  1010. }
  1011. }
  1012. }
  1013. }
  1014. void AddPrePostRenderStages()
  1015. {
  1016. var preRender = FindObjectOfType<NxrPreRender>();
  1017. if (preRender == null)
  1018. {
  1019. var go = new GameObject("PreRender", typeof(NxrPreRender));
  1020. go.SendMessage("Reset");
  1021. go.transform.parent = transform;
  1022. Debug.Log("Add NxrPreRender");
  1023. }
  1024. var postRender = FindObjectOfType<NxrPostRender>();
  1025. if (postRender == null)
  1026. {
  1027. var go = new GameObject("PostRender", typeof(NxrPostRender));
  1028. go.SendMessage("Reset");
  1029. go.transform.parent = transform;
  1030. Debug.Log("Add NxrPostRender");
  1031. }
  1032. }
  1033. /// Whether the viewer's trigger was pulled. True for exactly one complete frame
  1034. /// after each pull
  1035. public bool Triggered { get; set; }
  1036. public bool ProfileChanged { get; private set; }
  1037. // Only call device.UpdateState() once per frame.
  1038. private int updatedToFrame = 0;
  1039. /// Reads the latest tracking data from the phone. This must be
  1040. /// called before accessing any of the poses and matrices above.
  1041. ///
  1042. /// Multiple invocations per frame are OK: Subsequent calls merely yield the
  1043. /// cached results of the first call. To minimize latency, it should be first
  1044. /// called later in the frame (for example, in `LateUpdate`) if possible.
  1045. public void UpdateState()
  1046. {
  1047. if (updatedToFrame != Time.frameCount)
  1048. {
  1049. updatedToFrame = Time.frameCount;
  1050. DispatchEvents();
  1051. if (NeedUpdateNearFar && device != null && device.nibiruVRServiceId != 0)
  1052. {
  1053. float far = GetCameraFar();
  1054. float mNear = 0.0305f;
  1055. if (NxrGlobal.fovNear > -1)
  1056. {
  1057. mNear = NxrGlobal.fovNear;
  1058. }
  1059. device.SetCameraNearFar(mNear, far);
  1060. Instance.NeedUpdateNearFar = false;
  1061. for (int i = 0; i < 2; i++)
  1062. {
  1063. NxrEye eye = eyes[i];
  1064. if (eye != null)
  1065. {
  1066. if (eye.cam.farClipPlane < NxrGlobal.fovFar)
  1067. {
  1068. eye.cam.farClipPlane = NxrGlobal.fovFar;
  1069. }
  1070. }
  1071. }
  1072. }
  1073. }
  1074. }
  1075. // /// <summary>
  1076. // /// Analog all-in-one button: W-Up A-Left S-Down D-Right Space-Return Return-Confirm
  1077. // /// </summary>
  1078. // private void SimulateHeadSetKeyEvent()
  1079. // {
  1080. // if (!Application.isEditor && !(Application.platform == RuntimePlatform.WindowsPlayer))
  1081. // {
  1082. // // 编辑器 or win
  1083. // return;
  1084. // }
  1085. //
  1086. // if (Input.GetKeyDown(KeyCode.W))
  1087. // {
  1088. // TriggerKeyEvent(KeyCode.UpArrow, false);
  1089. // }
  1090. // else if (Input.GetKeyUp(KeyCode.W))
  1091. // {
  1092. // TriggerKeyEvent(KeyCode.UpArrow, true);
  1093. // }
  1094. // else if (Input.GetKeyDown(KeyCode.S))
  1095. // {
  1096. // TriggerKeyEvent(KeyCode.DownArrow, false);
  1097. // }
  1098. // else if (Input.GetKeyUp(KeyCode.S))
  1099. // {
  1100. // TriggerKeyEvent(KeyCode.DownArrow, true);
  1101. // }
  1102. // else if (Input.GetKeyDown(KeyCode.A))
  1103. // {
  1104. // TriggerKeyEvent(KeyCode.LeftArrow, false);
  1105. // }
  1106. // else if (Input.GetKeyUp(KeyCode.A))
  1107. // {
  1108. // TriggerKeyEvent(KeyCode.LeftArrow, true);
  1109. // }
  1110. // else if (Input.GetKeyDown(KeyCode.D))
  1111. // {
  1112. // TriggerKeyEvent(KeyCode.RightArrow, false);
  1113. // }
  1114. // else if (Input.GetKeyUp(KeyCode.D))
  1115. // {
  1116. // TriggerKeyEvent(KeyCode.RightArrow, true);
  1117. // }
  1118. // else if (Input.GetKeyDown(KeyCode.Space))
  1119. // {
  1120. // TriggerKeyEvent(KeyCode.Escape, false);
  1121. // }
  1122. // else if (Input.GetKeyUp(KeyCode.Space))
  1123. // {
  1124. // TriggerKeyEvent(KeyCode.Escape, true);
  1125. // }
  1126. // else if (Input.GetKeyDown(KeyCode.Return))
  1127. // {
  1128. // TriggerKeyEvent(KeyCode.JoystickButton0, false);
  1129. // }
  1130. // else if (Input.GetKeyUp(KeyCode.Return))
  1131. // {
  1132. // TriggerKeyEvent(KeyCode.JoystickButton0, true);
  1133. // }
  1134. //
  1135. // }
  1136. // List<INxrButtonListener> btnLiseners = null;
  1137. List<INxrJoystickListener> joystickListeners = null;
  1138. int[] lastKeyAction;
  1139. private void DispatchEvents()
  1140. {
  1141. // Update flags first by copying from device and other inputs.
  1142. if (device == null) return;
  1143. // if (Input.GetMouseButton(0) && !Triggered)
  1144. // {
  1145. // Triggered = Input.GetMouseButtonDown(0);
  1146. // }
  1147. ProfileChanged = device.profileChanged;
  1148. if (device.profileChanged)
  1149. {
  1150. if (NxrOverrideSettings.OnProfileChangedEvent != null) NxrOverrideSettings.OnProfileChangedEvent();
  1151. device.profileChanged = false;
  1152. }
  1153. // 模拟一体机按键
  1154. // SimulateHeadSetKeyEvent();
  1155. bool IsHasController = false;
  1156. if (Application.platform == RuntimePlatform.Android)
  1157. {
  1158. // 3dof or nolo
  1159. IsHasController = (NxrPlayerCtrl.Instance.IsQuatConn() || ControllerAndroid.IsNoloConn());
  1160. }
  1161. else if (IsWinPlatform)
  1162. {
  1163. IsHasController = NxrControllerHelper.Is3DofControllerConnected &&
  1164. NxrPlayerCtrl.Instance.GamepadEnabled;
  1165. }
  1166. if (IsHasController)
  1167. {
  1168. int[] KeyAction = null;
  1169. if (InteractionManager.IsControllerConnected())
  1170. {
  1171. KeyAction = InteractionManager.GetKeyAction();
  1172. }
  1173. else
  1174. {
  1175. KeyAction = NibiruTaskApi.GetKeyAction();
  1176. }
  1177. // if (KeyAction[CKeyEvent.KEYCODE_DPAD_CENTER] == 0)
  1178. // {
  1179. // Triggered = true;
  1180. // }
  1181. if (lastKeyAction == null)
  1182. {
  1183. lastKeyAction = KeyAction;
  1184. }
  1185. for (int i = 0; i < CKeyEvent.KeyCodeIds.Length; i++)
  1186. {
  1187. int keyCode = CKeyEvent.KeyCodeIds[i];
  1188. if (KeyAction[keyCode] == 0 && lastKeyAction[keyCode] == 1)
  1189. {
  1190. // down
  1191. // TriggerKeyEventForController(keyCode, false);
  1192. }
  1193. if (KeyAction[keyCode] == 1 && lastKeyAction[keyCode] == 0)
  1194. {
  1195. // up
  1196. // TriggerKeyEventForController(keyCode, true);
  1197. }
  1198. }
  1199. lastKeyAction = KeyAction;
  1200. }
  1201. //
  1202. // 手柄上下左右兼容处理
  1203. float leftKeyHor = Input.GetAxis("5th axis");
  1204. float leftKeyVer = Input.GetAxis("6th axis");
  1205. if (leftKeyHor == 1)
  1206. {
  1207. // 左
  1208. // TriggerKeyEvent(KeyCode.LeftArrow);
  1209. TriggerJoystickEvent(16, 0);
  1210. }
  1211. else if (leftKeyHor == -1)
  1212. {
  1213. // 右
  1214. // TriggerKeyEvent(KeyCode.RightArrow);
  1215. TriggerJoystickEvent(17, 0);
  1216. }
  1217. if (leftKeyVer == -1)
  1218. {
  1219. // 上
  1220. // TriggerKeyEvent(KeyCode.UpArrow);
  1221. TriggerJoystickEvent(14, 0);
  1222. }
  1223. else if (leftKeyVer == 1)
  1224. {
  1225. // 下
  1226. // TriggerKeyEvent(KeyCode.DownArrow);
  1227. TriggerJoystickEvent(15, 0);
  1228. }
  1229. // 左摇杆
  1230. float leftStickHor = Input.GetAxis("joystick_Horizontal");
  1231. float leftStickVer = Input.GetAxis("joystick_Vertical");
  1232. if (leftStickHor != 0)
  1233. {
  1234. TriggerJoystickEvent(10, leftStickHor);
  1235. }
  1236. if (leftStickVer != 0)
  1237. {
  1238. TriggerJoystickEvent(11, leftStickVer);
  1239. }
  1240. // 右摇杆
  1241. float rightStickHor = Input.GetAxis("3th axis");
  1242. float rightStickVer = Input.GetAxis("4th axis");
  1243. if (rightStickHor != 0)
  1244. {
  1245. TriggerJoystickEvent(12, rightStickHor);
  1246. }
  1247. if (rightStickVer != 0)
  1248. {
  1249. TriggerJoystickEvent(13, rightStickVer);
  1250. }
  1251. //
  1252. if (Application.platform == RuntimePlatform.Android && Input.anyKeyDown)
  1253. {
  1254. bool triggerDirectKey = false;
  1255. Event e = Event.current;
  1256. if (e != null && e.isKey)
  1257. {
  1258. KeyCode currentKey = e.keyCode;
  1259. Debug.Log("Current Key is : " + currentKey.ToString());
  1260. // if ((int)currentKey == 10 || currentKey == KeyCode.LeftArrow || currentKey == KeyCode.RightArrow || currentKey == KeyCode.UpArrow || currentKey == KeyCode.DownArrow || currentKey == KeyCode.Escape
  1261. // || currentKey == KeyCode.JoystickButton0)
  1262. // {
  1263. // if ((int)currentKey == 10 || currentKey == KeyCode.JoystickButton0)
  1264. // {
  1265. // // ok 键
  1266. // Triggered = true;
  1267. // }
  1268. triggerDirectKey = currentKey == KeyCode.LeftArrow || currentKey == KeyCode.RightArrow ||
  1269. currentKey == KeyCode.UpArrow || currentKey == KeyCode.DownArrow;
  1270. // TriggerKeyEvent(currentKey);
  1271. // }
  1272. // 手柄
  1273. if (currentKey == KeyCode.LeftShift)
  1274. {
  1275. TriggerJoystickEvent(0, 0);
  1276. }
  1277. else if (currentKey == KeyCode.LeftAlt)
  1278. {
  1279. TriggerJoystickEvent(1, 0);
  1280. }
  1281. else if (currentKey == KeyCode.RightShift)
  1282. {
  1283. TriggerJoystickEvent(2, 0);
  1284. }
  1285. else if (currentKey == KeyCode.RightAlt)
  1286. {
  1287. TriggerJoystickEvent(3, 0);
  1288. }
  1289. else if (currentKey == KeyCode.Pause)
  1290. {
  1291. TriggerJoystickEvent(4, 0);
  1292. }
  1293. else if (currentKey == KeyCode.Return)
  1294. {
  1295. TriggerJoystickEvent(5, 0);
  1296. }
  1297. else if (currentKey == KeyCode.JoystickButton2)
  1298. {
  1299. TriggerJoystickEvent(6, 0);
  1300. }
  1301. else if (currentKey == KeyCode.JoystickButton3)
  1302. {
  1303. TriggerJoystickEvent(7, 0);
  1304. }
  1305. else if (currentKey == KeyCode.JoystickButton1)
  1306. {
  1307. TriggerJoystickEvent(8, 0);
  1308. }
  1309. else if (currentKey == KeyCode.JoystickButton0)
  1310. {
  1311. TriggerJoystickEvent(9, 0);
  1312. }
  1313. else if (currentKey == KeyCode.JoystickButton8)
  1314. {
  1315. TriggerJoystickEvent(18, 0);
  1316. }
  1317. else if (currentKey == KeyCode.JoystickButton9)
  1318. {
  1319. TriggerJoystickEvent(19, 0);
  1320. }
  1321. }
  1322. }
  1323. // up 事件
  1324. // if (Application.platform == RuntimePlatform.Android &&
  1325. // (Input.GetKeyUp(KeyCode.JoystickButton0) || Input.GetKeyUp((KeyCode)10)))
  1326. // {
  1327. // TriggerKeyEvent(KeyCode.JoystickButton0, true);
  1328. // }
  1329. if (Application.platform == RuntimePlatform.Android && Event.current != null &&
  1330. (Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.RightArrow)
  1331. || Input.GetKeyUp(KeyCode.DownArrow) ||
  1332. Input.GetKeyUp(KeyCode.UpArrow)
  1333. || Input.GetKeyUp(KeyCode.Escape)))
  1334. {
  1335. Debug.Log("KeyUp===>" + Event.current.keyCode.ToString());
  1336. if (NibiruRemindBox.Instance.Showing())
  1337. {
  1338. NibiruRemindBox.Instance.ReleaseDestory();
  1339. }
  1340. if (NibiruShutDownBox.Instance.Showing())
  1341. {
  1342. NibiruShutDownBox.Instance.ReleaseDestory();
  1343. }
  1344. // else
  1345. // {
  1346. // TriggerKeyEvent(Event.current.keyCode, true);
  1347. // }
  1348. }
  1349. }
  1350. // private void TriggerKeyEvent(KeyCode currentKey)
  1351. // {
  1352. // TriggerKeyEvent(currentKey, false);
  1353. // }
  1354. // private void TriggerKeyEvent(KeyCode currentKey, bool isKeyUp)
  1355. // {
  1356. // if (btnLiseners == null || btnLiseners.Count == 0)
  1357. // {
  1358. // List<GameObject> allObject = GetAllObjectsInScene();
  1359. // btnLiseners = new List<INxrButtonListener>();
  1360. // foreach (GameObject obj in allObject)
  1361. // {
  1362. // Component[] comps = obj.GetComponents(typeof(INxrButtonListener));
  1363. // if (comps != null)
  1364. // {
  1365. // INxrButtonListener[] listeners = new INxrButtonListener[comps.Length];
  1366. //
  1367. // for (int p = 0; p < comps.Length; p++)
  1368. // {
  1369. // listeners[p] = (INxrButtonListener)comps[p];
  1370. // }
  1371. // // 获取所有挂载了INxrButtonListener的物体
  1372. // NotifyBtnPressed(listeners, currentKey, isKeyUp);
  1373. // foreach (Component cp in comps)
  1374. // {
  1375. // btnLiseners.Add((INxrButtonListener)cp);
  1376. // }
  1377. // }
  1378. // }
  1379. // }
  1380. // else
  1381. // {
  1382. // NotifyBtnPressed(btnLiseners.ToArray(), currentKey, isKeyUp);
  1383. // }
  1384. // }
  1385. // private void NotifyBtnPressed(INxrButtonListener[] comps, KeyCode currentKey, bool isKeyUp)
  1386. // {
  1387. // if (comps == null) return;
  1388. // for (int i = 0, length = comps.Length; i < length; i++)
  1389. // {
  1390. // INxrButtonListener btnListener = (INxrButtonListener)comps[i];
  1391. // if (btnListener == null) continue;
  1392. // if (currentKey == KeyCode.LeftArrow)
  1393. // {
  1394. // if (isKeyUp) { btnListener.OnLiftLeft(); } else { btnListener.OnPressLeft(); }
  1395. // }
  1396. // else if (currentKey == KeyCode.RightArrow)
  1397. // {
  1398. // if (isKeyUp) { btnListener.OnLiftRight(); } else { btnListener.OnPressRight(); }
  1399. // }
  1400. // else if (currentKey == KeyCode.UpArrow)
  1401. // {
  1402. // if (isKeyUp) { btnListener.OnLiftUp(); } else { btnListener.OnPressUp(); }
  1403. // }
  1404. // else if (currentKey == KeyCode.DownArrow)
  1405. // {
  1406. // if (isKeyUp) { btnListener.OnLiftDown(); } else { btnListener.OnPressDown(); }
  1407. // }
  1408. // else if (currentKey == KeyCode.Escape)
  1409. // {
  1410. // if (isKeyUp) { btnListener.OnLiftBack(); } else { btnListener.OnPressBack(); }
  1411. // }
  1412. // else if (currentKey == KeyCode.JoystickButton0 || (int)currentKey == 10)
  1413. // {
  1414. // btnListener.OnPressEnter(isKeyUp);
  1415. // }
  1416. // else if (currentKey == KeyCode.Joystick5Button18)
  1417. // {
  1418. // // 音量加
  1419. // btnListener.OnPressVolumnUp();
  1420. // }
  1421. // else if (currentKey == KeyCode.Joystick5Button19)
  1422. // {
  1423. // // 音量减
  1424. // btnListener.OnPressVolumnDown();
  1425. // }
  1426. // else if (currentKey == KeyCode.Joystick6Button1)
  1427. // {
  1428. // // Left
  1429. // if (isKeyUp)
  1430. // {
  1431. // btnListener.OnLiftFuctionKey(FunctionKeyCode.NF1);
  1432. // }
  1433. // else
  1434. // {
  1435. // btnListener.OnFuctionKeyDown(FunctionKeyCode.NF1);
  1436. // }
  1437. // }
  1438. // else if (currentKey == KeyCode.Joystick6Button2)
  1439. // {
  1440. // // Right
  1441. // if (isKeyUp)
  1442. // {
  1443. // btnListener.OnLiftFuctionKey(FunctionKeyCode.NF2);
  1444. // }
  1445. // else
  1446. // {
  1447. // btnListener.OnFuctionKeyDown(FunctionKeyCode.NF2);
  1448. // }
  1449. // }
  1450. // }
  1451. //
  1452. // }
  1453. // private void TriggerKeyEventForController(int keycode, bool isKeyUp)
  1454. // {
  1455. // if(NibiruRemindBox.Instance.Showing() && keycode == CKeyEvent.KEYCODE_BUTTON_APP && isKeyUp)
  1456. // {
  1457. // NibiruRemindBox.Instance.ReleaseDestory();
  1458. // return;
  1459. // }
  1460. //
  1461. // if (btnLiseners == null || btnLiseners.Count == 0)
  1462. // {
  1463. // List<GameObject> allObject = GetAllObjectsInScene();
  1464. // btnLiseners = new List<INxrButtonListener>();
  1465. // foreach (GameObject obj in allObject)
  1466. // {
  1467. // Component[] comps = obj.GetComponents(typeof(INxrButtonListener));
  1468. // if (comps != null)
  1469. // {
  1470. // INxrButtonListener[] listeners = new INxrButtonListener[comps.Length];
  1471. //
  1472. // for (int p = 0; p < comps.Length; p++)
  1473. // {
  1474. // listeners[p] = (INxrButtonListener)comps[p];
  1475. // }
  1476. // // 获取所有挂载了INvrButtonListener的物体
  1477. // NotifyBtnPressedForController(listeners, keycode, isKeyUp);
  1478. // foreach (Component cp in comps)
  1479. // {
  1480. // btnLiseners.Add((INxrButtonListener)cp);
  1481. // }
  1482. // }
  1483. // }
  1484. // }
  1485. // else
  1486. // {
  1487. // NotifyBtnPressedForController(btnLiseners.ToArray(), keycode, isKeyUp);
  1488. // }
  1489. // }
  1490. // private void NotifyBtnPressedForController(INxrButtonListener[] comps, int keycode, bool isKeyUp)
  1491. // {
  1492. // if (comps == null) return;
  1493. // for (int i = 0, length = comps.Length; i < length; i++)
  1494. // {
  1495. // INxrButtonListener btnListener = comps[i];
  1496. // if (btnListener == null) continue;
  1497. // if (keycode == CKeyEvent.KEYCODE_DPAD_LEFT)
  1498. // {
  1499. // if (isKeyUp) { btnListener.OnLiftLeft(); } else { btnListener.OnPressLeft(); }
  1500. // }
  1501. // else if (keycode == CKeyEvent.KEYCODE_DPAD_RIGHT)
  1502. // {
  1503. // if (isKeyUp) { btnListener.OnLiftRight(); } else { btnListener.OnPressRight(); }
  1504. // }
  1505. // else if (keycode == CKeyEvent.KEYCODE_DPAD_UP)
  1506. // {
  1507. // if (isKeyUp) { btnListener.OnLiftUp(); } else { btnListener.OnPressUp(); }
  1508. // }
  1509. // else if (keycode == CKeyEvent.KEYCODE_DPAD_DOWN)
  1510. // {
  1511. // if (isKeyUp) { btnListener.OnLiftDown(); } else { btnListener.OnPressDown(); }
  1512. // }
  1513. // else if (keycode == CKeyEvent.KEYCODE_BUTTON_APP)
  1514. // {
  1515. // // MENU
  1516. // if (isKeyUp)
  1517. // {
  1518. // btnListener.OnLiftFuctionKey(FunctionKeyCode.MENU);
  1519. // }
  1520. // else
  1521. // {
  1522. // btnListener.OnFuctionKeyDown(FunctionKeyCode.MENU);
  1523. // }
  1524. // }
  1525. // else if (keycode == CKeyEvent.KEYCODE_DPAD_CENTER)
  1526. // {
  1527. // // TOUCH PAD CLICK
  1528. // if (isKeyUp)
  1529. // {
  1530. // btnListener.OnLiftFuctionKey(FunctionKeyCode.TOUCHPAD);
  1531. // }
  1532. // else
  1533. // {
  1534. // btnListener.OnFuctionKeyDown(FunctionKeyCode.TOUCHPAD);
  1535. // }
  1536. // }
  1537. // else if (keycode == CKeyEvent.KEYCODE_VOLUME_UP)
  1538. // {
  1539. // // 音量加
  1540. // btnListener.OnPressVolumnUp();
  1541. // if (isKeyUp)
  1542. // {
  1543. // btnListener.OnLiftFuctionKey(FunctionKeyCode.VOLUMN_UP);
  1544. // }
  1545. // else
  1546. // {
  1547. // btnListener.OnFuctionKeyDown(FunctionKeyCode.VOLUMN_UP);
  1548. // }
  1549. // }
  1550. // else if (keycode == CKeyEvent.KEYCODE_VOLUME_DOWN)
  1551. // {
  1552. // // 音量减
  1553. // btnListener.OnPressVolumnDown();
  1554. // if (isKeyUp)
  1555. // {
  1556. // btnListener.OnLiftFuctionKey(FunctionKeyCode.VOLUMN_DOWN);
  1557. // }
  1558. // else
  1559. // {
  1560. // btnListener.OnFuctionKeyDown(FunctionKeyCode.VOLUMN_DOWN);
  1561. // }
  1562. // }
  1563. // else if (keycode == CKeyEvent.KEYCODE_BUTTON_R1)
  1564. // {
  1565. // // trigger
  1566. // if (isKeyUp)
  1567. // {
  1568. // btnListener.OnLiftFuctionKey(FunctionKeyCode.TRIGGER);
  1569. // }
  1570. // else
  1571. // {
  1572. // btnListener.OnFuctionKeyDown(FunctionKeyCode.TRIGGER);
  1573. // }
  1574. // }
  1575. // else if (keycode == CKeyEvent.KEYCODE_CONTROLLER_TOUCHPAD_TOUCH)
  1576. // {
  1577. // // touch pad
  1578. // if (isKeyUp)
  1579. // {
  1580. // btnListener.OnLiftFuctionKey(FunctionKeyCode.TOUCHPAD_TOUCH);
  1581. // }
  1582. // else
  1583. // {
  1584. // btnListener.OnFuctionKeyDown(FunctionKeyCode.TOUCHPAD_TOUCH);
  1585. // }
  1586. // }
  1587. // }
  1588. //
  1589. // }
  1590. /// <summary>
  1591. /// Resets the tracker so that the user's current direction becomes forward.
  1592. /// </summary>
  1593. public void Recenter()
  1594. {
  1595. device.Recenter();
  1596. if (GetHead() != null)
  1597. {
  1598. GetHead().ResetInitEulerYAngle();
  1599. }
  1600. }
  1601. /// Add a StereoController to any camera that does not have a Render Texture (meaning it is
  1602. /// rendering to the screen).
  1603. public static void AddStereoControllerToCameras()
  1604. {
  1605. for (int i = 0; i < Camera.allCameras.Length; i++)
  1606. {
  1607. Camera camera = Camera.allCameras[i];
  1608. Debug.Log("Check Camera : " + camera.name);
  1609. if (
  1610. (camera.tag == "MainCamera" || camera.tag == "NibiruCamera")
  1611. && camera.targetTexture == null &&
  1612. camera.GetComponent<NxrStereoController>() == null &&
  1613. camera.GetComponent<NxrEye>() == null &&
  1614. camera.GetComponent<NxrPreRender>() == null &&
  1615. camera.GetComponent<NxrPostRender>() == null)
  1616. {
  1617. camera.gameObject.AddComponent<NxrStereoController>();
  1618. }
  1619. }
  1620. }
  1621. void OnEnable()
  1622. {
  1623. #if UNITY_EDITOR || UNITY_STANDALONE_WIN
  1624. // This can happen if you edit code while the editor is in Play mode.
  1625. if (device == null)
  1626. {
  1627. InitDevice();
  1628. }
  1629. #endif
  1630. device.OnPause(false);
  1631. if (!NxrGlobal.isVR9Platform)
  1632. {
  1633. StartCoroutine("EndOfFrame");
  1634. }
  1635. }
  1636. void OnDisable()
  1637. {
  1638. device.OnPause(true);
  1639. Debug.Log("NxrViewer->OnDisable");
  1640. StopCoroutine("EndOfFrame");
  1641. }
  1642. private Coroutine onResume = null;
  1643. void OnPause()
  1644. {
  1645. onResume = null;
  1646. device.OnApplicationPause(true);
  1647. }
  1648. IEnumerator OnResume()
  1649. {
  1650. yield return new WaitForSeconds(1.0f);
  1651. // resume
  1652. if (!NxrGlobal.isVR9Platform && NxrGlobal.supportDtr)
  1653. {
  1654. InitNxrReticleScript();
  1655. UpdateHeadControl();
  1656. }
  1657. device.OnApplicationPause(false);
  1658. }
  1659. public void SetPause(bool pause)
  1660. {
  1661. if (pause)
  1662. {
  1663. OnPause();
  1664. }
  1665. else if (onResume == null)
  1666. {
  1667. onResume = StartCoroutine(OnResume());
  1668. }
  1669. }
  1670. void OnApplicationPause(bool pause)
  1671. {
  1672. Debug.Log("NxrViewer->OnApplicationPause," + pause + ", hasEnterXRMode=" + NxrSDKApi.Instance.IsInXRMode);
  1673. SetPause(pause);
  1674. }
  1675. void OnApplicationFocus(bool focus)
  1676. {
  1677. Debug.Log("NxrViewer->OnApplicationFocus," + focus);
  1678. device.OnFocus(focus);
  1679. }
  1680. void OnApplicationQuit()
  1681. {
  1682. if (GetNibiruService() != null && GetNibiruService().IsMarkerRecognizeRunning)
  1683. {
  1684. GetNibiruService().StopMarkerRecognize();
  1685. }
  1686. StopAllCoroutines();
  1687. device.OnApplicationQuit();
  1688. if (NxrOverrideSettings.OnApplicationQuitEvent != null)
  1689. {
  1690. NxrOverrideSettings.OnApplicationQuitEvent();
  1691. }
  1692. Debug.Log("NxrViewer->OnApplicationQuit");
  1693. #if UNITY_ANDROID && !UNITY_EDITOR
  1694. if(IsAndroidKillProcess)
  1695. {
  1696. NxrSDKApi.Instance.Destroy();
  1697. Debug.Log("NxrViewer->OnApplicationQuit.KillProcess");
  1698. System.Diagnostics.Process.GetCurrentProcess().Kill();
  1699. }
  1700. #endif
  1701. }
  1702. /// <summary>
  1703. /// Quit app
  1704. /// </summary>
  1705. public void AppQuit()
  1706. {
  1707. device.AppQuit();
  1708. }
  1709. void OnDestroy()
  1710. {
  1711. if (IsWinPlatform)
  1712. {
  1713. if (NxrInstantNativeApi.Inited)
  1714. {
  1715. _nvrConfigCallback -= OnNibiruConfigCallback;
  1716. NxrInstantNativeApi.Inited = false;
  1717. NxrInstantNativeApi.Cleanup();
  1718. NxrControllerHelper.Reset();
  1719. }
  1720. }
  1721. // if (btnLiseners != null)
  1722. // {
  1723. // btnLiseners.Clear();
  1724. // }
  1725. // btnLiseners = null;
  1726. this.SplitScreenModeEnabled = false;
  1727. InteractionManager.Reset();
  1728. if (device != null)
  1729. {
  1730. device.Destroy();
  1731. }
  1732. if (instance == this)
  1733. {
  1734. instance = null;
  1735. }
  1736. Debug.Log("NxrViewer->OnDestroy");
  1737. }
  1738. // 处理来自Android的调用
  1739. public void ResetHeadTrackerFromAndroid()
  1740. {
  1741. if (instance != null && device != null)
  1742. {
  1743. Recenter();
  1744. }
  1745. NibiruRemindBox.Instance.ReleaseDestory();
  1746. NibiruShutDownBox.Instance.ReleaseDestory();
  1747. }
  1748. void OnVolumnUp()
  1749. {
  1750. // TriggerKeyEvent(KeyCode.Joystick5Button18);
  1751. if (nxrInput != null)
  1752. {
  1753. nxrInput.OnChangeKeyEvent(CKeyEvent.KEYCODE_VOLUME_DOWN, CKeyEvent.ACTION_DOWN);
  1754. }
  1755. }
  1756. void OnVolumnDown()
  1757. {
  1758. // TriggerKeyEvent(KeyCode.Joystick5Button19);
  1759. if (nxrInput != null)
  1760. {
  1761. nxrInput.OnChangeKeyEvent(CKeyEvent.KEYCODE_VOLUME_UP, CKeyEvent.ACTION_DOWN);
  1762. }
  1763. }
  1764. void OnKeyDown(string keyCode)
  1765. {
  1766. Debug.Log("OnKeyDown=" + keyCode);
  1767. if (keyCode == NxrGlobal.KeyEvent_KEYCODE_ALT_LEFT)
  1768. {
  1769. // TriggerKeyEvent(KeyCode.Joystick6Button1, false);
  1770. if (nxrInput != null)
  1771. {
  1772. nxrInput.OnChangeKeyEvent(CKeyEvent.KEYCODE_NF_1, CKeyEvent.ACTION_DOWN);
  1773. }
  1774. }
  1775. else if (keyCode == NxrGlobal.KeyEvent_KEYCODE_MEDIA_RECORD)
  1776. {
  1777. // TriggerKeyEvent(KeyCode.Joystick6Button2, false);
  1778. if (nxrInput != null)
  1779. {
  1780. nxrInput.OnChangeKeyEvent(CKeyEvent.KEYCODE_NF_2, CKeyEvent.ACTION_DOWN);
  1781. }
  1782. }
  1783. }
  1784. void OnKeyUp(string keyCode)
  1785. {
  1786. Debug.Log("OnKeyUp=" + keyCode);
  1787. if (keyCode == NxrGlobal.KeyEvent_KEYCODE_ALT_LEFT)
  1788. {
  1789. // TriggerKeyEvent(KeyCode.Joystick6Button1, true);
  1790. if (nxrInput != null)
  1791. {
  1792. nxrInput.OnChangeKeyEvent(CKeyEvent.KEYCODE_NF_1, CKeyEvent.ACTION_UP);
  1793. }
  1794. }
  1795. else if (keyCode == NxrGlobal.KeyEvent_KEYCODE_MEDIA_RECORD)
  1796. {
  1797. // TriggerKeyEvent(KeyCode.Joystick6Button2, true);
  1798. if (nxrInput != null)
  1799. {
  1800. nxrInput.OnChangeKeyEvent(CKeyEvent.KEYCODE_NF_2, CKeyEvent.ACTION_UP);
  1801. }
  1802. }
  1803. }
  1804. void OnActivityPause()
  1805. {
  1806. Debug.Log("OnActivityPause");
  1807. }
  1808. void OnActivityResume()
  1809. {
  1810. Debug.Log("OnActivityResume");
  1811. }
  1812. /// <summary>
  1813. /// Set system split mode : 1=split by system,0=split by app
  1814. /// </summary>
  1815. public void SetSystemSplitMode(int flag)
  1816. {
  1817. device.NSetSystemSplitMode(flag);
  1818. }
  1819. private int[] _texture_ids = new int[_texture_count];
  1820. private int _current_texture_index, _next_texture_index;
  1821. public bool SwapBuffers()
  1822. {
  1823. bool ret = true;
  1824. for (int i = 0; i < _texture_count; i++)
  1825. {
  1826. if (!eyeStereoScreens[i].IsCreated())
  1827. {
  1828. eyeStereoScreens[i].Create();
  1829. _texture_ids[i] = (int) eyeStereoScreens[i].GetNativeTexturePtr();
  1830. ret = false;
  1831. }
  1832. }
  1833. _current_texture_index = _next_texture_index;
  1834. _next_texture_index = (_next_texture_index + 2) % _texture_count;
  1835. return ret;
  1836. }
  1837. public int GetEyeTextureId(int eye)
  1838. {
  1839. return _texture_ids[_current_texture_index + (int) eye];
  1840. }
  1841. public int GetTimeWarpViewNum()
  1842. {
  1843. return device.GetTimewarpViewNumber();
  1844. }
  1845. public List<GameObject> GetAllObjectsInScene()
  1846. {
  1847. GameObject[] pAllObjects = (GameObject[]) Resources.FindObjectsOfTypeAll(typeof(GameObject));
  1848. List<GameObject> pReturn = new List<GameObject>();
  1849. foreach (GameObject pObject in pAllObjects)
  1850. {
  1851. if (pObject == null || !pObject.activeInHierarchy || pObject.hideFlags == HideFlags.NotEditable ||
  1852. pObject.hideFlags == HideFlags.HideAndDontSave)
  1853. {
  1854. continue;
  1855. }
  1856. pReturn.Add(pObject);
  1857. }
  1858. return pReturn;
  1859. }
  1860. public Texture2D createTexture2D(RenderTexture renderTexture)
  1861. {
  1862. int width = renderTexture.width;
  1863. int height = renderTexture.height;
  1864. Texture2D texture2D = new Texture2D(width, height, TextureFormat.ARGB32, false);
  1865. RenderTexture.active = renderTexture;
  1866. texture2D.ReadPixels(new Rect(0, 0, width, height), 0, 0);
  1867. texture2D.Apply();
  1868. return texture2D;
  1869. }
  1870. private int frameCount = 0;
  1871. private void EndOfFrameCore()
  1872. {
  1873. if (USE_DTR && (!NxrSDKApi.Instance.IsInXRMode && frameCount < 3))
  1874. {
  1875. frameCount++;
  1876. Debug.Log("EndOfFrame->hasEnterRMode " + "" + NxrSDKApi.Instance.IsInXRMode + " or frameCount " +
  1877. frameCount);
  1878. // Call GL.clear before Enter VRMode to avoid unexpected graph breaking.
  1879. GL.Clear(false, true, Color.black);
  1880. }
  1881. else
  1882. {
  1883. frameCount++;
  1884. if (USE_DTR && NxrGlobal.supportDtr)
  1885. {
  1886. if (settings.timewarpEnabled >= 0 && frameCount > 0 && frameCount < 10)
  1887. {
  1888. device.SetTimeWarpEnable(false);
  1889. }
  1890. if (NxrGlobal.DEBUG_LOG_ENABLED) Debug.Log("EndOfFrame.TimeWarp[" + frameCount + "]");
  1891. // Debug.Log("TimeWrap." + frameCount);
  1892. }
  1893. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  1894. // Submit
  1895. if (NxrInstantNativeApi.Inited)
  1896. {
  1897. GL.IssuePluginEvent(NxrInstantNativeApi.GetRenderEventFunc(),
  1898. (int) NxrInstantNativeApi.RenderEvent.SubmitFrame);
  1899. }
  1900. #endif
  1901. }
  1902. bool IsHeadPoseUpdated = device.IsHeadPoseUpdated();
  1903. if (USE_DTR && NxrGlobal.supportDtr && IsHeadPoseUpdated)
  1904. NxrPluginEvent.IssueWithData(NibiruRenderEventType.TimeWarp, NxrViewer.Instance.GetTimeWarpViewNum());
  1905. }
  1906. IEnumerator EndOfFrame()
  1907. {
  1908. while (true)
  1909. {
  1910. yield return new WaitForEndOfFrame();
  1911. EndOfFrameCore();
  1912. }
  1913. }
  1914. public int GetFrameId()
  1915. {
  1916. return frameCount;
  1917. }
  1918. private void TriggerJoystickEvent(int index, float axisValue)
  1919. {
  1920. if (joystickListeners == null)
  1921. {
  1922. List<GameObject> allObject = GetAllObjectsInScene();
  1923. joystickListeners = new List<INxrJoystickListener>();
  1924. foreach (GameObject obj in allObject)
  1925. {
  1926. Component[] joystickcomps = obj.GetComponents(typeof(INxrJoystickListener));
  1927. if (joystickcomps != null)
  1928. {
  1929. INxrJoystickListener[] listeners = new INxrJoystickListener[joystickcomps.Length];
  1930. for (int p = 0; p < joystickcomps.Length; p++)
  1931. {
  1932. listeners[p] = (INxrJoystickListener) joystickcomps[p];
  1933. }
  1934. // INibiruJoystickListener
  1935. notifyJoystickPressed(listeners, index, axisValue);
  1936. foreach (Component cp in joystickcomps)
  1937. {
  1938. joystickListeners.Add((INxrJoystickListener) cp);
  1939. }
  1940. }
  1941. }
  1942. }
  1943. else
  1944. {
  1945. notifyJoystickPressed(joystickListeners.ToArray(), index, axisValue);
  1946. }
  1947. }
  1948. private void notifyJoystickPressed(INxrJoystickListener[] comps, int index, float axisValue)
  1949. {
  1950. if (comps == null) return;
  1951. for (int i = 0; i < comps.Length; i++)
  1952. {
  1953. INxrJoystickListener joystickListener = (INxrJoystickListener) comps[i];
  1954. if (joystickListener == null) continue;
  1955. switch (index)
  1956. {
  1957. case 0:
  1958. // l1
  1959. joystickListener.OnPressL1();
  1960. break;
  1961. case 1:
  1962. // l2
  1963. joystickListener.OnPressL2();
  1964. break;
  1965. case 2:
  1966. // r1
  1967. joystickListener.OnPressR1();
  1968. break;
  1969. case 3:
  1970. // r2
  1971. joystickListener.OnPressR2();
  1972. break;
  1973. case 4:
  1974. // select
  1975. joystickListener.OnPressSelect();
  1976. break;
  1977. case 5:
  1978. // start
  1979. joystickListener.OnPressStart();
  1980. break;
  1981. case 6:
  1982. // x
  1983. joystickListener.OnPressX();
  1984. break;
  1985. case 7:
  1986. // y
  1987. joystickListener.OnPressY();
  1988. break;
  1989. case 8:
  1990. // a
  1991. joystickListener.OnPressA();
  1992. break;
  1993. case 9:
  1994. // b
  1995. joystickListener.OnPressB();
  1996. break;
  1997. case 10:
  1998. // leftstickx
  1999. joystickListener.OnLeftStickX(axisValue);
  2000. break;
  2001. case 11:
  2002. // leftsticky
  2003. joystickListener.OnLeftStickY(axisValue);
  2004. break;
  2005. case 12:
  2006. // rightstickx
  2007. joystickListener.OnRightStickX(axisValue);
  2008. break;
  2009. case 13:
  2010. // rightsticky
  2011. joystickListener.OnRightStickY(axisValue);
  2012. break;
  2013. case 14:
  2014. // dpad-up
  2015. joystickListener.OnPressDpadUp();
  2016. break;
  2017. case 15:
  2018. // dpad-down
  2019. joystickListener.OnPressDpadDown();
  2020. break;
  2021. case 16:
  2022. // dpad-left
  2023. //joystickListener.OnPressDpadLeft();
  2024. joystickListener.OnPressDpadRight();
  2025. break;
  2026. case 17:
  2027. // dpad-right
  2028. //joystickListener.OnPressDpadRight();
  2029. joystickListener.OnPressDpadLeft();
  2030. break;
  2031. case 18:
  2032. joystickListener.OnLeftStickDown();
  2033. break;
  2034. case 19:
  2035. joystickListener.OnRightStickDown();
  2036. break;
  2037. }
  2038. }
  2039. }
  2040. private float mFar = -1;
  2041. private bool needUpdateNearFar = false;
  2042. /// <summary>
  2043. /// Update the left and right camera's farClipPlane
  2044. /// </summary>
  2045. /// <param name="far"></param>
  2046. public void UpateCameraFar(float far)
  2047. {
  2048. mFar = far;
  2049. needUpdateNearFar = true;
  2050. NxrGlobal.fovFar = far;
  2051. if (Application.isEditor || Application.platform == RuntimePlatform.WindowsPlayer)
  2052. {
  2053. // 编辑器及时生效
  2054. Camera.main.farClipPlane = far;
  2055. }
  2056. }
  2057. public float GetCameraFar()
  2058. {
  2059. return mFar;
  2060. }
  2061. public bool NeedUpdateNearFar
  2062. {
  2063. get { return needUpdateNearFar; }
  2064. set
  2065. {
  2066. if (value != needUpdateNearFar)
  2067. {
  2068. needUpdateNearFar = value;
  2069. }
  2070. }
  2071. }
  2072. private float oldFov = -1;
  2073. private Matrix4x4[] eyeOriginalProjection = null;
  2074. /// <summary>
  2075. /// Update eye camera projection
  2076. /// </summary>
  2077. /// <param name="eye"></param>
  2078. public void UpdateEyeCameraProjection(Eye eye)
  2079. {
  2080. if (oldFov != -1 && eye == Eye.Right)
  2081. {
  2082. UpdateCameraFov(oldFov);
  2083. }
  2084. if (!Application.isEditor && device != null && eye == Eye.Right)
  2085. {
  2086. if (mFar > 0)
  2087. {
  2088. float mNear = 0.0305f;
  2089. if (NxrGlobal.fovNear > -1)
  2090. {
  2091. mNear = NxrGlobal.fovNear;
  2092. }
  2093. // Debug.Log("new near : " + mNear + "," + NxrGlobal.fovNear+ ",new far : " + mFar + "," + NxrGlobal.fovFar);
  2094. // 更新camera near far
  2095. float fovLeft = mNear * Mathf.Tan(-Profile.viewer.maxFOV.outer * Mathf.Deg2Rad);
  2096. float fovTop = mNear * Mathf.Tan(Profile.viewer.maxFOV.upper * Mathf.Deg2Rad);
  2097. float fovRight = mNear * Mathf.Tan(Profile.viewer.maxFOV.inner * Mathf.Deg2Rad);
  2098. float fovBottom = mNear * Mathf.Tan(-Profile.viewer.maxFOV.lower * Mathf.Deg2Rad);
  2099. //Debug.Log("fov : " +fovLeft+","+fovRight+","+fovTop+","+fovBottom);
  2100. Matrix4x4 eyeProjection =
  2101. BaseARDevice.MakeProjection(fovLeft, fovTop, fovRight, fovBottom, mNear, mFar);
  2102. for (int i = 0; i < 2; i++)
  2103. {
  2104. NxrEye mEye = eyes[i];
  2105. if (mEye != null)
  2106. {
  2107. mEye.cam.projectionMatrix = eyeProjection;
  2108. }
  2109. }
  2110. }
  2111. }
  2112. }
  2113. /// <summary>
  2114. /// Reset the left and right camera's fov to default.
  2115. /// </summary>
  2116. public void ResetCameraFov()
  2117. {
  2118. for (int i = 0; i < 2; i++)
  2119. {
  2120. if (eyeOriginalProjection == null || eyeOriginalProjection[i] == null) return;
  2121. NxrEye eye = eyes[i];
  2122. if (eye != null)
  2123. {
  2124. eye.cam.projectionMatrix = eyeOriginalProjection[i];
  2125. }
  2126. }
  2127. oldFov = -1;
  2128. }
  2129. /// <summary>
  2130. /// Change the left and right camera's fov
  2131. /// fov range [40~90]
  2132. /// </summary>
  2133. /// <param name="fov"></param>
  2134. public void UpdateCameraFov(float fov)
  2135. {
  2136. if (fov > 90) fov = 90;
  2137. if (fov < 5) fov = 5;
  2138. // cache左右眼透视矩阵
  2139. if (eyeOriginalProjection == null && eyes[0] != null && eyes[1] != null)
  2140. {
  2141. eyeOriginalProjection = new Matrix4x4[2];
  2142. eyeOriginalProjection[0] = eyes[0].cam.projectionMatrix;
  2143. eyeOriginalProjection[1] = eyes[1].cam.projectionMatrix;
  2144. }
  2145. oldFov = fov;
  2146. float near = NxrGlobal.fovNear > 0 ? NxrGlobal.fovNear : 0.0305f;
  2147. float far = NxrGlobal.fovFar > 0 ? NxrGlobal.fovFar : 2000;
  2148. far = far > 100 ? far : 2000;
  2149. float fovLeft = near * Mathf.Tan(-fov * Mathf.Deg2Rad);
  2150. float fovTop = near * Mathf.Tan(fov * Mathf.Deg2Rad);
  2151. float fovRight = near * Mathf.Tan(fov * Mathf.Deg2Rad);
  2152. float fovBottom = near * Mathf.Tan(-fov * Mathf.Deg2Rad);
  2153. Matrix4x4 eyeProjection = BaseARDevice.MakeProjection(fovLeft, fovTop, fovRight, fovBottom, near, far);
  2154. if (device != null)
  2155. {
  2156. for (int i = 0; i < 2; i++)
  2157. {
  2158. NxrEye eye = eyes[i];
  2159. if (eye != null)
  2160. {
  2161. eye.cam.projectionMatrix = eyeProjection;
  2162. }
  2163. }
  2164. }
  2165. }
  2166. private float displacementCoefficient = 1.0f;
  2167. public float DisplacementCoefficient
  2168. {
  2169. get { return displacementCoefficient; }
  2170. set { displacementCoefficient = value; }
  2171. }
  2172. /// <summary>
  2173. /// Set horizontal angle range :mid is 0,left is less than 0,right is greater than 0
  2174. /// </summary>
  2175. /// <param name="minRange"></param>
  2176. /// <param name="maxRange"></param>
  2177. public void SetHorizontalAngleRange(float minRange, float maxRange)
  2178. {
  2179. if (headEulerAnglesRange == null)
  2180. {
  2181. headEulerAnglesRange = new float[] {0, 360, 0, 360};
  2182. }
  2183. headEulerAnglesRange[0] = minRange + 360;
  2184. headEulerAnglesRange[1] = maxRange;
  2185. }
  2186. /// <summary>
  2187. /// Set vertical angle range :mid is 0,up is less than 0,down is greater than 0
  2188. /// </summary>
  2189. /// <param name="minRange"></param>
  2190. /// <param name="maxRange"></param>
  2191. public void SetVerticalAngleRange(float minRange, float maxRange)
  2192. {
  2193. if (headEulerAnglesRange == null)
  2194. {
  2195. headEulerAnglesRange = new float[] {0, 360, 0, 360};
  2196. }
  2197. headEulerAnglesRange[2] = minRange + 360;
  2198. headEulerAnglesRange[3] = maxRange;
  2199. }
  2200. /// <summary>
  2201. /// Remove head angle limit
  2202. /// </summary>
  2203. public void RemoveAngleLimit()
  2204. {
  2205. headEulerAnglesRange = null;
  2206. }
  2207. public float[] GetHeadEulerAnglesRange()
  2208. {
  2209. return headEulerAnglesRange;
  2210. }
  2211. /// <summary>
  2212. /// open system app video player
  2213. /// </summary>
  2214. /// <param name="path">video path</param>
  2215. /// <param name="type2D3D">0=2d,1=3d mode</param>
  2216. /// <param name="mode">0=normal,1=360,2=180,3=fullmode video type</param>
  2217. /// <param name="decode">0=hardware,1=software decode mode</param>
  2218. public void OpenVideoPlayer(string path, int type2D3D, int mode, int decode)
  2219. {
  2220. device.ShowVideoPlayer(path, type2D3D, mode, decode);
  2221. }
  2222. /// <summary>
  2223. /// Get android SD Card's path(/storage/emulated/0)
  2224. /// </summary>
  2225. /// <returns>exp: /storage/emulated/0</returns>
  2226. public string GetStoragePath()
  2227. {
  2228. return device.GetStoragePath();
  2229. }
  2230. /// <summary>
  2231. /// Set the screen is always on.
  2232. /// </summary>
  2233. /// <param name="keep"></param>
  2234. public void SetIsKeepScreenOn(bool keep)
  2235. {
  2236. device.SetIsKeepScreenOn(keep);
  2237. }
  2238. private float defaultIpd = -1;
  2239. private float userIpd = -1;
  2240. /// <summary>
  2241. /// Change eye's ipd
  2242. /// </summary>
  2243. /// <param name="ipd">0.064</param>
  2244. public void SetIpd(float ipd)
  2245. {
  2246. if (defaultIpd < 0)
  2247. {
  2248. defaultIpd = GetIpd();
  2249. }
  2250. Debug.Log(" Ipd : D." + defaultIpd + "/N." + ipd);
  2251. NxrGlobal.dftProfileParams[0] = ipd; //0.063f;
  2252. userIpd = ipd;
  2253. device.SetIpd(ipd);
  2254. device.UpdateScreenData();
  2255. }
  2256. /// <summary>
  2257. /// Reset ipd's change
  2258. /// </summary>
  2259. public void ResetIpd()
  2260. {
  2261. if (defaultIpd < 0) return;
  2262. SetIpd(defaultIpd);
  2263. }
  2264. /// <summary>
  2265. /// Get eye's ipd
  2266. /// </summary>
  2267. /// <returns></returns>
  2268. public float GetIpd()
  2269. {
  2270. if (userIpd > 0) return userIpd;
  2271. return eyes[0] == null ? 0.060f : 2 * Math.Abs(eyes[0].GetComponent<Camera>().transform.localPosition.x);
  2272. }
  2273. public float GetUseIpd()
  2274. {
  2275. return userIpd;
  2276. }
  2277. public void ShowSystemMenuUI()
  2278. {
  2279. if (device != null)
  2280. {
  2281. //Player = new UnityPlayer();
  2282. AndroidJavaClass Player = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  2283. //Activity = Player.currentActivity;
  2284. AndroidJavaObject Activity = Player.GetStatic<AndroidJavaObject>("currentActivity");
  2285. //PackageManager = Activity.getPackageManager();
  2286. AndroidJavaObject PackageNameObj = Activity.Call<AndroidJavaObject>("getPackageName");
  2287. string packageName = PackageNameObj.Call<string>("toString");
  2288. Debug.Log("show_nvr_menu->" + packageName);
  2289. device.SetSystemParameters("show_nvr_menu", packageName);
  2290. }
  2291. }
  2292. public delegate void ServiceReadyUpdatedDelegate(SERVICE_TYPE serviceType, bool isConnectedSucc);
  2293. public delegate void OnSixDofPosition(float x, float y, float z);
  2294. public delegate void OnMarkerLoadStatus(MARKER_LOAD_STATUS status);
  2295. /// <summary>
  2296. /// Get the service connection status (after the service is connected, you can check the plug-in support status)
  2297. /// </summary>
  2298. public static ServiceReadyUpdatedDelegate serviceReadyUpdatedDelegate;
  2299. /// <summary>
  2300. /// hmd 6dof position' data callback
  2301. /// </summary>
  2302. public static OnSixDofPosition onSixDofPosition;
  2303. public static OnMarkerLoadStatus onMarkerLoadStatus;
  2304. /// <summary>
  2305. ///
  2306. /// Call after script's Awake
  2307. /// </summary>
  2308. /// <returns></returns>
  2309. public NibiruService GetNibiruService()
  2310. {
  2311. return device.GetNibiruService();
  2312. }
  2313. private GameObject eventReceiverVoice;
  2314. private GameObject eventReceiverGesture;
  2315. public void RegisterVoiceListener(GameObject listenerObj)
  2316. {
  2317. eventReceiverVoice = listenerObj;
  2318. }
  2319. public void RegisterGestureListener(GameObject listenerObj)
  2320. {
  2321. eventReceiverGesture = listenerObj;
  2322. }
  2323. void onHandleAndroidMsg(string msgContent)
  2324. {
  2325. // msgId_msgContent
  2326. string[] msgArr = msgContent.Split('_');
  2327. int msgId = int.Parse(msgArr[0]);
  2328. string msgData = msgArr[1];
  2329. // Debug.Log((eventReceiverVoice == null) + "-------->onHandleAndroidMsg=" + msgContent);
  2330. if (msgId == (int) MSG_ID.MSG_onServiceReady)
  2331. {
  2332. if (serviceReadyUpdatedDelegate != null)
  2333. {
  2334. SERVICE_TYPE serviceType = (SERVICE_TYPE) int.Parse(msgData);
  2335. bool connected = int.Parse(msgArr[2]) == 1;
  2336. serviceReadyUpdatedDelegate(serviceType, connected);
  2337. }
  2338. return;
  2339. }
  2340. if (msgId == (int) MSG_ID.MSG_verifyFailed)
  2341. {
  2342. NxrGlobal.verifyStatus = (VERIFY_STATUS) int.Parse(msgData);
  2343. Debug.Log("verify failed");
  2344. }
  2345. else if (msgId == (int) MSG_ID.MSG_verifySucc)
  2346. {
  2347. NxrGlobal.verifyStatus = VERIFY_STATUS.SUCC;
  2348. Debug.Log("verify succ");
  2349. }
  2350. else if (msgId == (int) MSG_ID.MSG_onKeyStoreException)
  2351. {
  2352. NxrGlobal.verifyStatus = VERIFY_STATUS.HEAD_ERROR;
  2353. Debug.Log("verify keystore exception");
  2354. }
  2355. else if (msgId == (int) MSG_ID.MSG_onHeadPosition && onSixDofPosition != null)
  2356. {
  2357. //[-0.26371408, -0.108221784, -0.05875514] [0]
  2358. string[] posStr = msgData.Substring(1, msgData.Length - 2).Split(',');
  2359. float x = (float) Math.Round(float.Parse(posStr[0]), 2);
  2360. float y = (float) Math.Round(float.Parse(posStr[1]), 2);
  2361. float z = (float) Math.Round(float.Parse(posStr[2]), 2);
  2362. // 用Loom的方法在Unity主线程中调用Text组件
  2363. if (onSixDofPosition != null)
  2364. {
  2365. onSixDofPosition(x, y, z);
  2366. }
  2367. }
  2368. else if ((MSG_ID) msgId == MSG_ID.MSG_onMarkerLoadStatus && onMarkerLoadStatus != null)
  2369. {
  2370. if (onMarkerLoadStatus != null)
  2371. {
  2372. onMarkerLoadStatus((MARKER_LOAD_STATUS) int.Parse(msgData));
  2373. }
  2374. }
  2375. if ((eventReceiverGesture != null || eventReceiverVoice != null) &&
  2376. NxrGlobal.verifyStatus == VERIFY_STATUS.SUCC)
  2377. {
  2378. object msgObj = null;
  2379. if ((MSG_ID) msgId == MSG_ID.MSG_onGestureEvent)
  2380. {
  2381. msgObj = (GESTURE_ID) int.Parse(msgData);
  2382. if (eventReceiverGesture != null)
  2383. eventReceiverGesture.BroadcastMessage(NxrGlobal.GetMethodNameById((MSG_ID) msgId), msgObj,
  2384. SendMessageOptions.DontRequireReceiver);
  2385. }
  2386. else if ((MSG_ID) msgId == MSG_ID.MSG_onVoiceVolume ||
  2387. (MSG_ID) msgId == MSG_ID.MSG_onVoiceFinishError ||
  2388. (MSG_ID) msgId == MSG_ID.MSG_onVoiceFinishResult)
  2389. {
  2390. msgObj = msgData;
  2391. if ((MSG_ID) msgId == MSG_ID.MSG_onVoiceFinishError && msgArr.Length > 1)
  2392. {
  2393. // msgId_errorcode_errormsg
  2394. msgObj = msgArr[2];
  2395. }
  2396. if (eventReceiverVoice != null)
  2397. eventReceiverVoice.BroadcastMessage(NxrGlobal.GetMethodNameById((MSG_ID) msgId), msgObj,
  2398. SendMessageOptions.DontRequireReceiver);
  2399. }
  2400. }
  2401. if ((MSG_ID) msgId == MSG_ID.MSG_onServerApiReady)
  2402. {
  2403. Loom.QueueOnMainThread((param) =>
  2404. {
  2405. bool isReady = int.Parse((string) param) == 1;
  2406. if (NibiruTaskApi.serverApiReady != null)
  2407. {
  2408. NibiruTaskApi.serverApiReady(isReady);
  2409. }
  2410. }, msgData);
  2411. }
  2412. else if ((MSG_ID) msgId == MSG_ID.MSG_onSysSleepApiReady)
  2413. {
  2414. Loom.QueueOnMainThread((param) =>
  2415. {
  2416. bool isReady = int.Parse((string) param) == 1;
  2417. if (NibiruTaskApi.sysSleepApiReady != null)
  2418. {
  2419. NibiruTaskApi.sysSleepApiReady(isReady);
  2420. }
  2421. }, msgData);
  2422. }
  2423. else if ((MSG_ID) msgId == MSG_ID.MSG_onInteractionDeviceConnectEvent)
  2424. {
  2425. InteractionManager.OnDeviceConnectState(msgContent);
  2426. }
  2427. else if ((MSG_ID) msgId == MSG_ID.MSG_onInteractionKeyEvent)
  2428. {
  2429. if (!TouchScreenKeyboard.visible)
  2430. {
  2431. InteractionManager.OnCKeyEvent(msgContent);
  2432. }
  2433. else
  2434. {
  2435. Triggered = false;
  2436. }
  2437. }
  2438. else if ((MSG_ID) msgId == MSG_ID.MSG_onInteractionTouchEvent)
  2439. {
  2440. InteractionManager.OnCTouchEvent(msgContent);
  2441. }
  2442. }
  2443. /// <summary>
  2444. /// Speech Recognition:Chinese or English
  2445. /// </summary>
  2446. public VOICE_LANGUAGE VoiceLanguage
  2447. {
  2448. get { return NxrGlobal.voiceLanguage; }
  2449. set
  2450. {
  2451. if (value != NxrGlobal.voiceLanguage)
  2452. {
  2453. NxrGlobal.voiceLanguage = value;
  2454. NibiruService nibiruService = device.GetNibiruService();
  2455. if (nibiruService != null)
  2456. {
  2457. nibiruService.UpdateVoiceLanguage();
  2458. }
  2459. }
  2460. }
  2461. }
  2462. [SerializeField] public SleepTimeoutMode sleepTimeoutMode = SleepTimeoutMode.NEVER_SLEEP;
  2463. [SerializeField] public ControllerSupportMode controllerSupportMode = ControllerSupportMode.NONE;
  2464. public SleepTimeoutMode SleepMode
  2465. {
  2466. get { return sleepTimeoutMode; }
  2467. set
  2468. {
  2469. if (value != sleepTimeoutMode)
  2470. {
  2471. sleepTimeoutMode = value;
  2472. }
  2473. }
  2474. }
  2475. [SerializeField] private SixDofMode sixDofMode = SixDofMode.Head_3Dof_Ctrl_6Dof;
  2476. public SixDofMode SixDofMode
  2477. {
  2478. get { return sixDofMode; }
  2479. set
  2480. {
  2481. if (value != sixDofMode)
  2482. {
  2483. sixDofMode = value;
  2484. }
  2485. }
  2486. }
  2487. /// <summary>
  2488. /// Get main camera
  2489. /// </summary>
  2490. /// <returns></returns>
  2491. public Camera GetMainCamera()
  2492. {
  2493. return Controller.cam;
  2494. }
  2495. /// <summary>
  2496. /// Get left eye camera
  2497. /// </summary>
  2498. /// <returns></returns>
  2499. public Camera GetLeftEyeCamera()
  2500. {
  2501. return Controller.Eyes[(int) Eye.Left].cam;
  2502. }
  2503. /// <summary>
  2504. /// Get right eye camera
  2505. /// </summary>
  2506. /// <returns></returns>
  2507. public Camera GetRightEyeCamera()
  2508. {
  2509. return Controller.Eyes[(int) Eye.Right].cam;
  2510. }
  2511. /// <summary>
  2512. /// Get main camera's quaternion
  2513. /// </summary>
  2514. /// <returns></returns>
  2515. public Quaternion GetCameraQuaternion()
  2516. {
  2517. return GetHead().transform.rotation;
  2518. }
  2519. /// <summary>
  2520. /// Get controller's quaternion
  2521. /// </summary>
  2522. /// <returns></returns>
  2523. public Quaternion GetControllerQuaternion()
  2524. {
  2525. if (IsControllerConnect())
  2526. {
  2527. return NxrPlayerCtrl.Instance.mTransform.localRotation;
  2528. }
  2529. return Quaternion.identity;
  2530. }
  2531. /// <summary>
  2532. /// Set controller's active status
  2533. /// </summary>
  2534. /// <param name="isActive"></param>
  2535. public void SetControllerActive(bool isActive)
  2536. {
  2537. NxrPlayerCtrl.Instance.ChangeControllerDisplay(isActive);
  2538. }
  2539. /// <summary>
  2540. /// Is main camera locked
  2541. /// </summary>
  2542. /// <returns></returns>
  2543. public bool IsCameraLocked()
  2544. {
  2545. return !NxrViewer.Instance.GetHead().IsTrackRotation();
  2546. }
  2547. /// <summary>
  2548. /// Is controller connect
  2549. /// </summary>
  2550. /// <returns></returns>
  2551. public bool IsControllerConnect()
  2552. {
  2553. return InteractionManager.IsControllerConnected();
  2554. }
  2555. /// <summary>
  2556. /// Lock main camera's rotation
  2557. /// </summary>
  2558. /// <param name="isLock"></param>
  2559. public void LockCamera(bool isLock)
  2560. {
  2561. NxrHead head = NxrViewer.Instance.GetHead();
  2562. head.SetTrackRotation(!isLock);
  2563. }
  2564. /// <summary>
  2565. /// Get 3dof controller's ray start point
  2566. /// </summary>
  2567. /// <returns></returns>
  2568. public Transform GetRayStartPoint()
  2569. {
  2570. return NxrPlayerCtrl.Instance.GetRayStartPoint();
  2571. }
  2572. /// <summary>
  2573. /// Get 3dof controller's ray end point
  2574. /// </summary>
  2575. /// <returns></returns>
  2576. public Transform GetRayEndPoint()
  2577. {
  2578. return NxrPlayerCtrl.Instance.GetRayEndPoint();
  2579. }
  2580. }
  2581. }