Guest User

Untitled

a guest
May 20th, 2018
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.55 KB | None | 0 0
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3.  
  4. using UnityEngine;
  5. using System.Collections;
  6. using HoloToolkit.Unity;
  7. using System.Collections.Generic;
  8. using System.Runtime.InteropServices;
  9. using System;
  10.  
  11. namespace HoloToolkit.Examples.SpatialUnderstandingFeatureOverview
  12. {
  13. public class LevelSolver : LineDrawer
  14. {
  15. // Singleton
  16. public static LevelSolver Instance;
  17.  
  18. // Enums
  19. public enum QueryStates
  20. {
  21. None,
  22. Processing,
  23. Finished
  24. }
  25.  
  26. // Structs
  27. private struct QueryStatus
  28. {
  29. public void Reset()
  30. {
  31. State = QueryStates.None;
  32. Name = "";
  33. CountFail = 0;
  34. CountSuccess = 0;
  35. QueryResult = new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult>();
  36. }
  37.  
  38. public QueryStates State;
  39. public string Name;
  40. public int CountFail;
  41. public int CountSuccess;
  42. public List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult> QueryResult;
  43. }
  44.  
  45. private struct PlacementQuery
  46. {
  47. public PlacementQuery(
  48. SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition placementDefinition,
  49. List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule> placementRules = null,
  50. List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint> placementConstraints = null)
  51. {
  52. PlacementDefinition = placementDefinition;
  53. PlacementRules = placementRules;
  54. PlacementConstraints = placementConstraints;
  55. }
  56.  
  57. public SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition PlacementDefinition;
  58. public List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule> PlacementRules;
  59. public List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint> PlacementConstraints;
  60. }
  61.  
  62. private class PlacementResult
  63. {
  64. public PlacementResult(float timeDelay, SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult result)
  65. {
  66. Box = new AnimatedBox(timeDelay, result.Position, Quaternion.LookRotation(result.Forward, result.Up), Color.blue, result.HalfDims);
  67. Result = result;
  68. }
  69.  
  70. public LineDrawer.AnimatedBox Box;
  71. public SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult Result;
  72. }
  73.  
  74. // Properties
  75. public bool IsSolverInitialized { get; private set; }
  76.  
  77. // Privates
  78. private Queue<PlacementResult> placementResults = new Queue<PlacementResult>();
  79. private QueryStatus queryStatus = new QueryStatus();
  80.  
  81. // Functions
  82. private void Awake()
  83. {
  84. Instance = this;
  85. }
  86.  
  87. public void ClearGeometry(bool clearAll = true)
  88. {
  89. placementResults.Clear();
  90. if (SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
  91. {
  92. SpatialUnderstandingDllObjectPlacement.Solver_RemoveAllObjects();
  93. }
  94. AppState.Instance.ObjectPlacementDescription = "";
  95.  
  96. if (clearAll && (SpaceVisualizer.Instance != null))
  97. {
  98. SpaceVisualizer.Instance.ClearGeometry(false);
  99. }
  100. }
  101.  
  102. /*private bool Draw_PlacementResults()
  103. {
  104. bool needsUpdate = false;
  105.  
  106. for (int i = 0; i < placementResults.Count; ++i)
  107. {
  108. needsUpdate |= Draw_AnimatedBox(placementResults[i].Box);
  109. }
  110.  
  111. return needsUpdate;
  112. }*/
  113.  
  114. private bool PlaceObjectAsync(
  115. string placementName,
  116. SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition placementDefinition,
  117. List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule> placementRules = null,
  118. List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint> placementConstraints = null,
  119. bool clearObjectsFirst = true)
  120. {
  121. return PlaceObjectAsync(
  122. placementName,
  123. new List<PlacementQuery>() { new PlacementQuery(placementDefinition, placementRules, placementConstraints) },
  124. clearObjectsFirst);
  125. }
  126.  
  127. private bool PlaceObjectAsync(
  128. string placementName,
  129. List<PlacementQuery> placementList,
  130. bool clearObjectsFirst = true)
  131. {
  132. // If we already mid-query, reject the request
  133. if (queryStatus.State != QueryStates.None)
  134. {
  135. return false;
  136. }
  137.  
  138. // Clear geo
  139. if (clearObjectsFirst)
  140. {
  141. ClearGeometry();
  142. }
  143.  
  144. // Mark it
  145. queryStatus.Reset();
  146. queryStatus.State = QueryStates.Processing;
  147. queryStatus.Name = placementName;
  148.  
  149. // Tell user we are processing
  150. AppState.Instance.ObjectPlacementDescription = placementName + " (processing)";
  151.  
  152. // Kick off a thread to do process the queries
  153. #if UNITY_EDITOR || !UNITY_WSA
  154. new System.Threading.Thread
  155. #else
  156. System.Threading.Tasks.Task.Run
  157. #endif
  158. (() =>
  159. {
  160. // Go through the queries in the list
  161. for (int i = 0; i < placementList.Count; ++i)
  162. {
  163. // Do the query
  164. bool success = PlaceObject(
  165. placementName,
  166. placementList[i].PlacementDefinition,
  167. placementList[i].PlacementRules,
  168. placementList[i].PlacementConstraints,
  169. clearObjectsFirst,
  170. true);
  171.  
  172. // Mark the result
  173. queryStatus.CountSuccess = success ? (queryStatus.CountSuccess + 1) : queryStatus.CountSuccess;
  174. queryStatus.CountFail = !success ? (queryStatus.CountFail + 1) : queryStatus.CountFail;
  175. }
  176.  
  177. // Done
  178. queryStatus.State = QueryStates.Finished;
  179. }
  180. )
  181. #if UNITY_EDITOR || !UNITY_WSA
  182. .Start()
  183. #endif
  184. ;
  185.  
  186. return true;
  187. }
  188.  
  189. private bool PlaceObject(
  190. string placementName,
  191. SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition placementDefinition,
  192. List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule> placementRules = null,
  193. List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint> placementConstraints = null,
  194. bool clearObjectsFirst = true,
  195. bool isASync = false)
  196. {
  197. // Clear objects (if requested)
  198. if (!isASync && clearObjectsFirst)
  199. {
  200. ClearGeometry();
  201. }
  202. if (!SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
  203. {
  204. return false;
  205. }
  206.  
  207. // New query
  208. if (SpatialUnderstandingDllObjectPlacement.Solver_PlaceObject(
  209. placementName,
  210. SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(placementDefinition),
  211. (placementRules != null) ? placementRules.Count : 0,
  212. ((placementRules != null) && (placementRules.Count > 0)) ? SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(placementRules.ToArray()) : IntPtr.Zero,
  213. (placementConstraints != null) ? placementConstraints.Count : 0,
  214. ((placementConstraints != null) && (placementConstraints.Count > 0)) ? SpatialUnderstanding.Instance.UnderstandingDLL.PinObject(placementConstraints.ToArray()) : IntPtr.Zero,
  215. SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticObjectPlacementResultPtr()) > 0)
  216. {
  217. SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult placementResult = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticObjectPlacementResult();
  218. if (!isASync)
  219. {
  220. // If not running async, we can just add the results to the draw list right now
  221. AppState.Instance.ObjectPlacementDescription = placementName + " (1)";
  222. float timeDelay = (float)placementResults.Count * AnimatedBox.DelayPerItem;
  223. placementResults.Enqueue(new PlacementResult(timeDelay, placementResult.Clone() as SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult));
  224. }
  225. else
  226. {
  227. queryStatus.QueryResult.Add(placementResult.Clone() as SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult);
  228. }
  229. return true;
  230. }
  231. if (!isASync)
  232. {
  233. AppState.Instance.ObjectPlacementDescription = placementName + " (0)";
  234. }
  235. return false;
  236. }
  237.  
  238. private void ProcessPlacementResults()
  239. {
  240. // Check it
  241. if (queryStatus.State != QueryStates.Finished)
  242. {
  243. return;
  244. }
  245. if (!SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
  246. {
  247. return;
  248. }
  249.  
  250. // Clear results
  251. ClearGeometry();
  252.  
  253. // We will reject any above or below the ceiling/floor
  254. SpatialUnderstandingDll.Imports.QueryPlayspaceAlignment(SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceAlignmentPtr());
  255. SpatialUnderstandingDll.Imports.PlayspaceAlignment alignment = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceAlignment();
  256.  
  257. // Copy over the results
  258. for (int i = 0; i < queryStatus.QueryResult.Count; ++i)
  259. {
  260. if ((queryStatus.QueryResult[i].Position.y < alignment.CeilingYValue) &&
  261. (queryStatus.QueryResult[i].Position.y > alignment.FloorYValue))
  262. {
  263. float timeDelay = (float)placementResults.Count * AnimatedBox.DelayPerItem;
  264. placementResults.Enqueue(new PlacementResult(timeDelay, queryStatus.QueryResult[i].Clone() as SpatialUnderstandingDllObjectPlacement.ObjectPlacementResult));
  265. }
  266. }
  267.  
  268. // Text
  269. AppState.Instance.ObjectPlacementDescription = queryStatus.Name + " (" + placementResults.Count + "/" + (queryStatus.CountSuccess + queryStatus.CountFail) + ")";
  270.  
  271. // Mark done
  272. queryStatus.Reset();
  273. }
  274.  
  275. public void Query_OnFloor()
  276. {
  277. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  278. for (int i = 0; i < 4; ++i)
  279. {
  280. float halfDimSize = UnityEngine.Random.Range(0.15f, 0.35f);
  281. placementQuery.Add(
  282. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnFloor(new Vector3(halfDimSize, halfDimSize, halfDimSize * 2.0f)),
  283. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  284. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  285. }));
  286. }
  287. PlaceObjectAsync("OnFloor", placementQuery);
  288. }
  289.  
  290. public void Query_OnWall()
  291. {
  292. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  293. for (int i = 0; i < 6; ++i)
  294. {
  295. float halfDimSize = UnityEngine.Random.Range(0.3f, 0.6f);
  296. placementQuery.Add(
  297. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnWall(new Vector3(halfDimSize, halfDimSize * 0.5f, 0.05f), 0.5f, 3.0f),
  298. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  299. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 4.0f),
  300. }));
  301. }
  302. PlaceObjectAsync("OnWall", placementQuery);
  303. }
  304.  
  305. public void Query_OnCeiling()
  306. {
  307. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  308. for (int i = 0; i < 2; ++i)
  309. {
  310. float halfDimSize = UnityEngine.Random.Range(0.3f, 0.4f);
  311. placementQuery.Add(
  312. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnCeiling(new Vector3(halfDimSize, halfDimSize, halfDimSize)),
  313. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  314. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  315. }));
  316. }
  317. PlaceObjectAsync("OnCeiling", placementQuery);
  318. }
  319.  
  320. public void Query_OnEdge()
  321. {
  322. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  323. for (int i = 0; i < 8; ++i)
  324. {
  325. float halfDimSize = UnityEngine.Random.Range(0.05f, 0.1f);
  326. placementQuery.Add(
  327. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnEdge(new Vector3(halfDimSize, halfDimSize, halfDimSize),
  328. new Vector3(halfDimSize, halfDimSize, halfDimSize)),
  329. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  330. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  331. }));
  332. }
  333. PlaceObjectAsync("OnEdge", placementQuery);
  334. }
  335.  
  336. public void Query_OnFloorAndCeiling()
  337. {
  338. SpatialUnderstandingDll.Imports.QueryPlayspaceAlignment(SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceAlignmentPtr());
  339. SpatialUnderstandingDll.Imports.PlayspaceAlignment alignment = SpatialUnderstanding.Instance.UnderstandingDLL.GetStaticPlayspaceAlignment();
  340. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  341. for (int i = 0; i < 4; ++i)
  342. {
  343. float halfDimSize = UnityEngine.Random.Range(0.1f, 0.2f);
  344. placementQuery.Add(
  345. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnFloorAndCeiling(new Vector3(halfDimSize, (alignment.CeilingYValue - alignment.FloorYValue) * 0.5f, halfDimSize),
  346. new Vector3(halfDimSize, (alignment.CeilingYValue - alignment.FloorYValue) * 0.5f, halfDimSize)),
  347. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  348. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  349. }));
  350. }
  351. PlaceObjectAsync("OnFloorAndCeiling", placementQuery);
  352. }
  353.  
  354. public void Query_RandomInAir_AwayFromMe()
  355. {
  356. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  357. for (int i = 0; i < 8; ++i)
  358. {
  359. float halfDimSize = UnityEngine.Random.Range(0.1f, 0.2f);
  360. placementQuery.Add(
  361. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_RandomInAir(new Vector3(halfDimSize, halfDimSize, halfDimSize)),
  362. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  363. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  364. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromPosition(CameraCache.Main.transform.position, 2.5f),
  365. }));
  366. }
  367. PlaceObjectAsync("RandomInAir - AwayFromMe", placementQuery);
  368. }
  369.  
  370. public void Query_OnEdge_NearCenter()
  371. {
  372. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  373. for (int i = 0; i < 4; ++i)
  374. {
  375. float halfDimSize = UnityEngine.Random.Range(0.05f, 0.1f);
  376. placementQuery.Add(
  377. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnEdge(new Vector3(halfDimSize, halfDimSize, halfDimSize), new Vector3(halfDimSize, halfDimSize, halfDimSize)),
  378. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  379. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 2.0f),
  380. },
  381. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint>() {
  382. SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint.Create_NearCenter(),
  383. }));
  384. }
  385. PlaceObjectAsync("OnEdge - NearCenter", placementQuery);
  386.  
  387. }
  388.  
  389. public void Query_OnFloor_AwayFromMe()
  390. {
  391. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  392. for (int i = 0; i < 4; ++i)
  393. {
  394. float halfDimSize = UnityEngine.Random.Range(0.05f, 0.15f);
  395. placementQuery.Add(
  396. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnFloor(new Vector3(halfDimSize, halfDimSize, halfDimSize)),
  397. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  398. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromPosition(CameraCache.Main.transform.position, 2.0f),
  399. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  400. }));
  401. }
  402. PlaceObjectAsync("OnFloor - AwayFromMe", placementQuery);
  403. }
  404.  
  405. public void Query_OnFloor_NearMe()
  406. {
  407. List<PlacementQuery> placementQuery = new List<PlacementQuery>();
  408. for (int i = 0; i < 4; ++i)
  409. {
  410. float halfDimSize = UnityEngine.Random.Range(0.05f, 0.2f);
  411. placementQuery.Add(
  412. new PlacementQuery(SpatialUnderstandingDllObjectPlacement.ObjectPlacementDefinition.Create_OnFloor(new Vector3(halfDimSize, halfDimSize, halfDimSize)),
  413. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule>() {
  414. SpatialUnderstandingDllObjectPlacement.ObjectPlacementRule.Create_AwayFromOtherObjects(halfDimSize * 3.0f),
  415. },
  416. new List<SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint>() {
  417. SpatialUnderstandingDllObjectPlacement.ObjectPlacementConstraint.Create_NearPoint(CameraCache.Main.transform.position, 0.5f, 2.0f)
  418. }));
  419. }
  420. PlaceObjectAsync("OnFloor - NearMe", placementQuery);
  421. }
  422.  
  423. private void Update_Queries()
  424. {
  425. if (Input.GetKeyDown(KeyCode.R))
  426. {
  427. Query_OnFloor();
  428. }
  429. if (Input.GetKeyDown(KeyCode.T))
  430. {
  431. Query_OnWall();
  432. }
  433. if (Input.GetKeyDown(KeyCode.Y))
  434. {
  435. Query_OnCeiling();
  436. }
  437. if (Input.GetKeyDown(KeyCode.U))
  438. {
  439. Query_OnEdge();
  440. }
  441. if (Input.GetKeyDown(KeyCode.I))
  442. {
  443. Query_OnFloorAndCeiling();
  444. }
  445. if (Input.GetKeyDown(KeyCode.O))
  446. {
  447. Query_RandomInAir_AwayFromMe();
  448. }
  449. if (Input.GetKeyDown(KeyCode.P))
  450. {
  451. Query_OnEdge_NearCenter();
  452. }
  453. if (Input.GetKeyDown(KeyCode.LeftBracket))
  454. {
  455. Query_OnFloor_AwayFromMe();
  456. }
  457. if (Input.GetKeyDown(KeyCode.RightBracket))
  458. {
  459. Query_OnFloor_NearMe();
  460. }
  461. }
  462.  
  463. public bool InitializeSolver()
  464. {
  465. if (IsSolverInitialized ||
  466. !SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
  467. {
  468. return IsSolverInitialized;
  469. }
  470.  
  471. if (SpatialUnderstandingDllObjectPlacement.Solver_Init() == 1)
  472. {
  473. IsSolverInitialized = true;
  474. }
  475. return IsSolverInitialized;
  476. }
  477.  
  478. private void Update()
  479. {
  480. // Can't do any of this till we're done with the scanning phase
  481. if (SpatialUnderstanding.Instance.ScanState != SpatialUnderstanding.ScanStates.Done)
  482. {
  483. return;
  484. }
  485.  
  486. // Make sure the solver has been initialized
  487. if (!IsSolverInitialized &&
  488. SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
  489. {
  490. InitializeSolver();
  491. }
  492.  
  493. // Constraint queries
  494. if (SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Done)
  495. {
  496. Update_Queries();
  497. }
  498.  
  499. // Handle async query results
  500. ProcessPlacementResults();
  501.  
  502. MyProcessPlacementResults();
  503.  
  504. // Lines: Begin
  505. // LineDraw_Begin();
  506.  
  507.  
  508.  
  509. // Drawers
  510. //bool needsUpdate = false;
  511. //needsUpdate |= Draw_PlacementResults();
  512.  
  513. // Lines: Finish up
  514. //LineDraw_End(needsUpdate);
  515. }
  516.  
  517. private void MyProcessPlacementResults()
  518. {
  519. if (placementResults.Count > 0)
  520. {
  521. var toPlace = placementResults.Dequeue();
  522.  
  523. var rotation = Quaternion.LookRotation(toPlace.Result.Forward, Vector3.up);
  524. CreateCeilingObject(toPlace.Result.Position, rotation);
  525.  
  526. }
  527. }
  528.  
  529. public GameObject ceilingObject;
  530. private Vector3 TheSizeIPassedToSpatialUnderstanding = new Vector3(1, 1, 1);
  531.  
  532. public void CreateCeilingObject(Vector3 positionCenter, Quaternion rotation)
  533. {
  534. GameObject newObject = Instantiate(ceilingObject, positionCenter, rotation) as GameObject;
  535.  
  536. if (newObject != null)
  537. {
  538. // Set the parent of the new object the GameObject it was placed on
  539. newObject.transform.parent = gameObject.transform;
  540. }
  541. }
  542. }
  543.  
  544.  
  545. }
Add Comment
Please, Sign In to add comment