Guest User

Untitled

a guest
Jan 21st, 2018
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.77 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.IO;
  5.  
  6. /// <summary>
  7. /// General utilities
  8. /// </summary>
  9. public static class PopCloud
  10. {
  11. // gr: make this a more intelligent extension->loader mapping
  12. public static List<string> FileExtensions = new List<string>() {".xyz",".off"};
  13.  
  14.  
  15.  
  16.  
  17.  
  18. static void ExtractLineStarts(string Filename,ref byte[] Data,ref List<int> LineStartIndexes)
  19. {
  20. Data = System.IO.File.ReadAllBytes (Filename);
  21.  
  22. // find all line feeds
  23. LineStartIndexes = new List<int>();
  24. var NewLine = true;
  25. for (int i = 0; i < Data.Length; i++)
  26. {
  27. var c = Data [i];
  28.  
  29. // walk over delins
  30. if (c == '\n' || c == '\r') {
  31. NewLine = true;
  32. continue;
  33. }
  34.  
  35. // first valid character of a new line
  36. if (NewLine) {
  37. LineStartIndexes.Add (i);
  38. NewLine = false;
  39. }
  40. }
  41. }
  42.  
  43. struct XyzRgba
  44. {
  45. public float x;
  46. public float y;
  47. public float z;
  48.  
  49. public float r;
  50. public float g;
  51. public float b;
  52. public float a;
  53.  
  54. // gr: need to align to 4, so use int, not bool
  55. public int Valid;
  56.  
  57. public static int GetSize()
  58. {
  59. return (sizeof(float) * 7) + (sizeof(int) * 1);
  60. }
  61. };
  62.  
  63. public static void LoadXyzGpu(string Filename,System.Action<Vector3,Color> OnPointDecoded,System.Action<List<string>> OnUnhandledHeader,System.Action<string,float> UpdateProgress)
  64. {
  65. UpdateProgress.Invoke ("Parsing file lines...", 0.0f);
  66.  
  67. byte[] Data = null;
  68. List<int> LineStarts = null;
  69. ExtractLineStarts (Filename, ref Data, ref LineStarts);
  70. XyzRgba[] PosColours = new XyzRgba[LineStarts.Count];
  71.  
  72. // gr: DX REQUIRES buffer to be multiples of 4.
  73. // metal packs these bytes into int's, silently. So lets just pretend they're packed
  74. int PackSize = 4;
  75. var DataBuffer = new ComputeBuffer (Data.Length/PackSize, sizeof(byte)*PackSize, ComputeBufferType.Default );
  76.  
  77. DataBuffer.SetData (Data);
  78. var LineStartsBuffer = new ComputeBuffer (LineStarts.Count, sizeof(int));
  79. LineStartsBuffer.SetData (LineStarts.ToArray());
  80. var PositionColourBuffer = new ComputeBuffer (PosColours.Length, XyzRgba.GetSize() );
  81. PositionColourBuffer.SetData (PosColours);
  82.  
  83. var KernelName = "ParsePositionColour";
  84. var ShaderAssetName = "Assets/PopCloud/PopXyzToTexture.compute";
  85.  
  86. var Shader = UnityEditor.AssetDatabase.LoadAssetAtPath (ShaderAssetName, typeof(ComputeShader)) as ComputeShader;
  87. if (!Shader)
  88. throw new System.Exception ("Couldn't find " + ShaderAssetName);
  89.  
  90. var KernelId = Shader.FindKernel (KernelName);
  91. Shader.SetBuffer (KernelId, "Data", DataBuffer);
  92. Shader.SetBuffer (KernelId, "LineStarts", LineStartsBuffer);
  93. Shader.SetBuffer (KernelId, "PositionColours", PositionColourBuffer);
  94.  
  95. UpdateProgress.Invoke ("Executing compute parser...", 0.0f);
  96.  
  97. Shader.Dispatch(KernelId, LineStarts.Count, 1, 1);
  98.  
  99. PositionColourBuffer.GetData (PosColours);
  100.  
  101. {
  102. var v3 = new Vector3 ();
  103. var c = new Color ();
  104. int Count = 0;
  105. foreach (var Point in PosColours) {
  106.  
  107. // GUI update eats cpu time
  108. if ((Count % 1000) == 0) {
  109. var Progress = Count / (float)PosColours.Length;
  110. UpdateProgress.Invoke ("Loading points...", Progress);
  111. }
  112.  
  113. if ( Count == 0 )
  114. Debug.Log ("#" + Count + " valid=" + Point.Valid + " (" + Point.x + "," + Point.y + "," + Point.z + "," + Point.r + "," + Point.g + "," + Point.b + ")");
  115.  
  116. Count++;
  117. if (Point.Valid == 0)
  118. continue;
  119.  
  120. v3.x = Point.x;
  121. v3.y = Point.y;
  122. v3.z = Point.z;
  123. c.r = Point.r;
  124. c.g = Point.g;
  125. c.b = Point.b;
  126. c.a = Point.a;
  127. OnPointDecoded.Invoke (v3, c);
  128. }
  129. }
  130.  
  131. DataBuffer.Release ();
  132. LineStartsBuffer.Release ();
  133. PositionColourBuffer.Release ();
  134. }
  135.  
  136. public static void LoadXyz(string Filename,System.Action<Vector3,Color> OnPointDecoded,System.Action<List<string>> OnUnhandledHeader,System.Action<string,float> UpdateProgress)
  137. {
  138. var Stream = File.OpenText (Filename);
  139.  
  140. // unaccounted header strings we keep
  141. var Headers = new List<string>();
  142.  
  143. // once we parse something good, we dont keep "headers"
  144. bool PassedHeader = false;
  145.  
  146. var Pos3 = new Vector3 ();
  147. var Colour = new Color ();
  148. int LinesParsed = 0;
  149. int LinesSkipped = 0;
  150.  
  151.  
  152. System.Action<string> ParseLine = (XyzLine) =>
  153. {
  154. // parse line
  155. try
  156. {
  157. var Floats = FastParse.Floats(XyzLine);
  158. if ( Floats.Count != 6 && Floats.Count != 7 )
  159. throw new System.Exception("Expecting 6/7 values");
  160.  
  161. PassedHeader = true;
  162.  
  163. Pos3.x = Floats[0];
  164. Pos3.y = Floats[1];
  165. Pos3.z = Floats[2];
  166.  
  167. Colour.r = Floats[3] / 255.0f;
  168. Colour.g = Floats[4] / 255.0f;
  169. Colour.b = Floats[5] / 255.0f;
  170. Colour.a = ( Floats.Count > 6 ) ? Floats[6] / 255.0f : 1;
  171.  
  172. OnPointDecoded.Invoke( Pos3, Colour );
  173. LinesParsed++;
  174. }
  175. catch
  176. {
  177. // no floats in line
  178. if (!PassedHeader)
  179. Headers.Add (XyzLine);
  180. LinesSkipped++;
  181. }
  182. };
  183.  
  184.  
  185. var JobRunner = new JobPool_Action();
  186.  
  187. System.Action<string> ParseLineThreaded = (XyzLine) => {
  188. System.Action Job = () => {
  189. ParseLine (XyzLine);
  190. };
  191. JobRunner.PushJob (Job);
  192. };
  193.  
  194.  
  195. {
  196. string Line;
  197. int LineCount = 0;
  198. while ((Line = Stream.ReadLine ()) != null) {
  199. var Progress = Stream.BaseStream.Position / (float)Stream.BaseStream.Length;
  200. //Progress = JobRunner.jobProgress;
  201. LineCount++;
  202.  
  203. if (LineCount > 800000)
  204. break;
  205.  
  206. ParseLineThreaded (Line);
  207.  
  208. if ((LinesParsed + LinesSkipped) % 1000 == 0) {
  209. var ProgressName = "Parsing line " + LinesParsed + " (" + LinesSkipped + " skipped)";
  210. UpdateProgress.Invoke (ProgressName, Progress);
  211. }
  212. }
  213. }
  214.  
  215. do {
  216. var Pending = JobRunner.jobsPending;
  217. var Completed = JobRunner.jobsCompleted;
  218. var Step = "Waiting for jobs " + Completed + "/" + (Pending + Completed);
  219. UpdateProgress.Invoke (Step, JobRunner.jobProgress);
  220. JobRunner.WaitForJobs (500);
  221. } while (JobRunner.jobsPending > 0);
  222.  
  223.  
  224. OnUnhandledHeader.Invoke (Headers);
  225. }
  226. }
Add Comment
Please, Sign In to add comment