ZibraManipulatorManager.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using UnityEngine;
  5. using com.zibra.liquid.Solver;
  6. using com.zibra.common.Utilities;
  7. using com.zibra.liquid.DataStructures;
  8. using UnityEngine.Experimental.Rendering;
  9. using UnityEngine.Rendering;
  10. using com.zibra.common.SDFObjects;
  11. namespace com.zibra.liquid.Manipulators
  12. {
  13. internal class ZibraManipulatorManager : MonoBehaviour
  14. {
  15. [HideInInspector]
  16. [StructLayout(LayoutKind.Sequential)]
  17. internal struct ManipulatorParam
  18. {
  19. public Int32 Enabled;
  20. public Int32 SDFObjectID;
  21. public Int32 ParticleSpecies;
  22. public Int32 IntParameter;
  23. public Vector4 AdditionalData0;
  24. public Vector4 AdditionalData1;
  25. }
  26. [HideInInspector]
  27. [StructLayout(LayoutKind.Sequential)]
  28. internal struct SDFObjectParams
  29. {
  30. public Vector3 Position;
  31. public Single NormalSmooth;
  32. public Vector3 Velocity;
  33. public Single SurfaceValue;
  34. public Vector3 Scale;
  35. public Single DistanceScale;
  36. public Vector3 AnguralVelocity;
  37. public Int32 Type;
  38. public Quaternion Rotation;
  39. public Vector3 BBoxSize;
  40. public Single BBoxVolume;
  41. public Int32 EmbeddingTextureBlocks;
  42. public Int32 SDFTextureBlocks;
  43. public Int32 ObjectID;
  44. public Single TotalGroupVolume;
  45. public Vector3 UnusedPadding;
  46. public Int32 ManipulatorID;
  47. };
  48. [HideInInspector]
  49. [StructLayout(LayoutKind.Sequential)]
  50. internal struct ManipulatorIndices
  51. {
  52. public Int32 EmitterIndexBegin;
  53. public Int32 EmitterIndexEnd;
  54. public Int32 VoidIndexBegin;
  55. public Int32 VoidIndexEnd;
  56. public Int32 ForceFieldIndexBegin;
  57. public Int32 ForceFieldIndexEnd;
  58. public Int32 AnalyticColliderIndexBegin;
  59. public Int32 AnalyticColliderIndexEnd;
  60. public Int32 NeuralColliderIndexBegin;
  61. public Int32 NeuralColliderIndexEnd;
  62. public Int32 GroupColliderIndexBegin;
  63. public Int32 GroupColliderIndexEnd;
  64. public Int32 DetectorIndexBegin;
  65. public Int32 DetectorIndexEnd;
  66. public Int32 SpeciesModifierIndexBegin;
  67. public Int32 SpeciesModifierIndexEnd;
  68. public Int32 HeightmapColliderIndexBegin;
  69. public Int32 HeightmapColliderIndexEnd;
  70. public Vector2Int IndexPadding;
  71. }
  72. private int[] TypeIndex = new int[(int)Manipulator.ManipulatorType.TypeNum + 1];
  73. public ManipulatorIndices Indices = new ManipulatorIndices();
  74. // All data together
  75. [HideInInspector]
  76. public int Elements = 0;
  77. [HideInInspector]
  78. public List<ManipulatorParam> ManipulatorParams = new List<ManipulatorParam>();
  79. [HideInInspector]
  80. public List<SDFObjectParams> SDFObjectList = new List<SDFObjectParams>();
  81. [HideInInspector]
  82. public Color32[] Embeddings;
  83. [HideInInspector]
  84. public byte[] SDFGrid;
  85. [HideInInspector]
  86. public List<int> ConstDataID = new List<int>();
  87. [HideInInspector]
  88. public int TextureCount = 0;
  89. [HideInInspector]
  90. public int SDFTextureSize = 0;
  91. [HideInInspector]
  92. public int EmbeddingTextureSize = 0;
  93. [HideInInspector]
  94. public int SDFTextureBlocks = 0;
  95. [HideInInspector]
  96. public int EmbeddingTextureBlocks = 0;
  97. [HideInInspector]
  98. public int SDFTextureDimension = 0;
  99. [HideInInspector]
  100. public int EmbeddingTextureDimension = 0;
  101. [HideInInspector]
  102. public Vector2Int HeightmapSize;
  103. [HideInInspector]
  104. public int HeightmapCount;
  105. [HideInInspector]
  106. public int HeightmapCountSqrt;
  107. [HideInInspector]
  108. public Dictionary<ZibraHash128, NeuralSDF> NeuralSDFs = new Dictionary<ZibraHash128, NeuralSDF>();
  109. [HideInInspector]
  110. public Dictionary<ZibraHash128, int> TextureHashMap = new Dictionary<ZibraHash128, int>();
  111. private List<Manipulator> Manipulators;
  112. private Material HeightmapBlit;
  113. private Vector3 Abs(Vector3 x)
  114. {
  115. return new Vector3(Mathf.Abs(x.x), Mathf.Abs(x.y), Mathf.Abs(x.z));
  116. }
  117. protected SDFObjectParams GetSDF(SDFObject obj, Manipulator manipulator)
  118. {
  119. SDFObjectParams sdf = new SDFObjectParams();
  120. if (obj == null)
  121. {
  122. throw new Exception("Missing SDF on manipulator");
  123. }
  124. sdf.Rotation = manipulator.transform.rotation;
  125. sdf.Scale = manipulator.transform.lossyScale;
  126. sdf.Position = manipulator.transform.position;
  127. sdf.BBoxSize = 2.0f * sdf.Scale;
  128. sdf.NormalSmooth = 0.01f;
  129. sdf.Velocity = Vector3.zero;
  130. sdf.SurfaceValue = 0.0f;
  131. SDFObject main = manipulator.GetComponent<SDFObject>();
  132. if (main != null)
  133. {
  134. sdf.SurfaceValue += main.SurfaceDistance;
  135. }
  136. sdf.SurfaceValue += obj.SurfaceDistance;
  137. sdf.DistanceScale = 1.0f;
  138. sdf.AnguralVelocity = Vector3.zero;
  139. sdf.TotalGroupVolume = 0.0f;
  140. sdf.BBoxSize = 0.5f * manipulator.transform.lossyScale;
  141. if (obj is AnalyticSDF)
  142. {
  143. AnalyticSDF analyticSDF = obj as AnalyticSDF;
  144. sdf.Type = (int)analyticSDF.ChosenSDFType;
  145. sdf.DistanceScale = analyticSDF.InvertSDF ? -1.0f : 1.0f;
  146. sdf.BBoxSize = analyticSDF.GetBBoxSize();
  147. }
  148. if (obj is NeuralSDF)
  149. {
  150. NeuralSDF neuralSDF = obj as NeuralSDF;
  151. Matrix4x4 transf = obj.transform.localToWorldMatrix * neuralSDF.ObjectRepresentation.ObjectTransform;
  152. sdf.Rotation = transf.rotation;
  153. sdf.Scale = Abs(transf.lossyScale);
  154. sdf.Position = transf.MultiplyPoint(Vector3.zero);
  155. sdf.Type = (int)SDFObject.SDFObjectType.Neural;
  156. sdf.ObjectID = TextureHashMap[neuralSDF.ObjectRepresentation.GetHash()];
  157. sdf.EmbeddingTextureBlocks = EmbeddingTextureBlocks;
  158. sdf.SDFTextureBlocks = SDFTextureBlocks;
  159. sdf.DistanceScale = neuralSDF.InvertSDF ? -1.0f : 1.0f;
  160. sdf.BBoxSize = sdf.Scale;
  161. }
  162. sdf.BBoxVolume = sdf.BBoxSize.x * sdf.BBoxSize.y * sdf.BBoxSize.z;
  163. return sdf;
  164. }
  165. protected void AddTexture(NeuralSDF neuralSDF)
  166. {
  167. ZibraHash128 curHash = neuralSDF.ObjectRepresentation.GetHash();
  168. if (TextureHashMap.ContainsKey(curHash))
  169. return;
  170. SDFTextureSize +=
  171. neuralSDF.ObjectRepresentation.GridResolution / NeuralSDFRepresentation.BLOCK_SDF_APPROX_DIMENSION;
  172. EmbeddingTextureSize += NeuralSDFRepresentation.EMBEDDING_SIZE *
  173. neuralSDF.ObjectRepresentation.EmbeddingResolution /
  174. NeuralSDFRepresentation.BLOCK_EMBEDDING_GRID_DIMENSION;
  175. NeuralSDFs[curHash] = neuralSDF;
  176. int sdfID = TextureCount;
  177. TextureHashMap[curHash] = sdfID;
  178. TextureCount++;
  179. }
  180. protected void AddTextureData(NeuralSDF neuralSDF)
  181. {
  182. ZibraHash128 curHash = neuralSDF.ObjectRepresentation.GetHash();
  183. int sdfID = TextureHashMap[curHash];
  184. // Embedding texture
  185. for (int t = 0; t < NeuralSDFRepresentation.EMBEDDING_SIZE; t++)
  186. {
  187. int block = sdfID * NeuralSDFRepresentation.EMBEDDING_SIZE + t;
  188. Vector3Int blockPos = NeuralSDFRepresentation.BLOCK_EMBEDDING_GRID_DIMENSION *
  189. new Vector3Int(block % EmbeddingTextureBlocks,
  190. (block / EmbeddingTextureBlocks) % EmbeddingTextureBlocks,
  191. block / (EmbeddingTextureBlocks * EmbeddingTextureBlocks));
  192. int Size = neuralSDF.ObjectRepresentation.EmbeddingResolution;
  193. for (int i = 0; i < Size; i++)
  194. {
  195. for (int j = 0; j < Size; j++)
  196. {
  197. for (int k = 0; k < Size; k++)
  198. {
  199. Vector3Int pos = blockPos + new Vector3Int(i, j, k);
  200. int id = pos.x + EmbeddingTextureDimension * (pos.y + EmbeddingTextureDimension * pos.z);
  201. if (id >= EmbeddingTextureSize)
  202. {
  203. Debug.LogError(pos);
  204. }
  205. Embeddings[id] = neuralSDF.ObjectRepresentation.GetEmbedding(i, j, k, t);
  206. }
  207. }
  208. }
  209. }
  210. // SDF approximation texture
  211. {
  212. int block = sdfID;
  213. Vector3Int blockPos =
  214. NeuralSDFRepresentation.BLOCK_SDF_APPROX_DIMENSION *
  215. new Vector3Int(block % SDFTextureBlocks, (block / SDFTextureBlocks) % SDFTextureBlocks,
  216. block / (SDFTextureBlocks * SDFTextureBlocks));
  217. int Size = neuralSDF.ObjectRepresentation.GridResolution;
  218. for (int i = 0; i < Size; i++)
  219. {
  220. for (int j = 0; j < Size; j++)
  221. {
  222. for (int k = 0; k < Size; k++)
  223. {
  224. Vector3Int pos = blockPos + new Vector3Int(i, j, k);
  225. int id = pos.x + SDFTextureDimension * (pos.y + SDFTextureDimension * pos.z);
  226. for (int t = 0; t < 2; t++)
  227. SDFGrid[2 * id + t] = neuralSDF.ObjectRepresentation.GetSDGrid(i, j, k, t);
  228. }
  229. }
  230. }
  231. }
  232. }
  233. protected void CalculateTextureData()
  234. {
  235. SDFTextureBlocks = (int)Mathf.Ceil(Mathf.Pow(SDFTextureSize, (1.0f / 3.0f)));
  236. EmbeddingTextureBlocks = (int)Mathf.Ceil(Mathf.Pow(EmbeddingTextureSize, (1.0f / 3.0f)));
  237. SDFTextureDimension = NeuralSDFRepresentation.BLOCK_SDF_APPROX_DIMENSION * SDFTextureBlocks;
  238. EmbeddingTextureDimension = NeuralSDFRepresentation.BLOCK_EMBEDDING_GRID_DIMENSION * EmbeddingTextureBlocks;
  239. SDFTextureSize = SDFTextureDimension * SDFTextureDimension * SDFTextureDimension;
  240. EmbeddingTextureSize = EmbeddingTextureDimension * EmbeddingTextureDimension * EmbeddingTextureDimension;
  241. Array.Resize<Color32>(ref Embeddings, EmbeddingTextureSize);
  242. Array.Resize<byte>(ref SDFGrid, 2 * SDFTextureSize);
  243. foreach (var sdf in NeuralSDFs.Values)
  244. {
  245. AddTextureData(sdf);
  246. }
  247. }
  248. protected void UpdateHeightmap(CommandBuffer commandBuffer, RenderTexture heightmaps, Terrain terrain,
  249. ref int heightmapID, ref SDFObjectParams sdf)
  250. {
  251. if (terrain != null)
  252. {
  253. TerrainData terrainData = terrain.terrainData;
  254. RenderTexture heightmap = terrainData.heightmapTexture;
  255. bool singleChannel = true;
  256. switch (heightmap.format)
  257. {
  258. case RenderTextureFormat.RFloat:
  259. case RenderTextureFormat.R8:
  260. case RenderTextureFormat.R16:
  261. case RenderTextureFormat.RHalf:
  262. case RenderTextureFormat.RInt:
  263. singleChannel = true;
  264. break;
  265. default:
  266. singleChannel = false;
  267. break;
  268. }
  269. Vector2 chunkID = new Vector2(heightmapID % HeightmapCountSqrt, heightmapID / HeightmapCountSqrt);
  270. Vector4 scaling = new Vector4(chunkID.x, chunkID.y, HeightmapCountSqrt, HeightmapCountSqrt);
  271. commandBuffer.SetGlobalVector("_HeightmapScaling", scaling);
  272. commandBuffer.SetGlobalInt("_ComponentToBlit", singleChannel ? 0 : 1);
  273. commandBuffer.Blit(heightmap, heightmaps, HeightmapBlit);
  274. sdf.Type = (int)SDFObject.SDFObjectType.Heightmap;
  275. sdf.ObjectID = heightmapID;
  276. sdf.SDFTextureBlocks = HeightmapCountSqrt;
  277. sdf.Rotation = Quaternion.identity;
  278. sdf.Scale = terrainData.heightmapScale * terrainData.heightmapResolution;
  279. // heightmap is from 0 to 1, but the scales of the objects we have are from -1 to 1, so we need to
  280. // multiply by 2.0f
  281. sdf.Scale.y = terrainData.heightmapScale.y * 2.0f;
  282. heightmapID++;
  283. }
  284. }
  285. /// <summary>
  286. /// Update all arrays and lists with manipulator object data
  287. /// Should be executed every simulation frame
  288. /// </summary>
  289. /// <param name="parent">
  290. /// Instance of parent ZibraLiquid class.
  291. /// </param>
  292. /// <param name="deltaTime">
  293. /// Time difference between previous and current frame in units of simulation time.
  294. /// </param>
  295. public void UpdateDynamic(CommandBuffer commandBuffer, ZibraLiquid parent, float deltaTime = 0.0f)
  296. {
  297. int ID = 0;
  298. int heightmapID = 0;
  299. ManipulatorParams.Clear();
  300. SDFObjectList.Clear();
  301. // fill arrays
  302. foreach (var manipulator in Manipulators)
  303. {
  304. if (manipulator == null)
  305. continue;
  306. ManipulatorParam manip = new ManipulatorParam();
  307. manip.Enabled = (manipulator.isActiveAndEnabled && manipulator.gameObject.activeInHierarchy) ? 1 : 0;
  308. manip.AdditionalData0 = manipulator.AdditionalData0;
  309. manip.AdditionalData1 = manipulator.AdditionalData1;
  310. SDFObjectParams sdf = GetSDF(manipulator.GetComponent<SDFObject>(), manipulator);
  311. SDFObject sdfobj = manipulator.GetComponent<SDFObject>();
  312. if (sdfobj is TerrainSDF)
  313. {
  314. UpdateHeightmap(commandBuffer, parent.HeightmapTexture, manipulator.GetComponent<Terrain>(),
  315. ref heightmapID, ref sdf);
  316. }
  317. if (sdfobj is SkinnedMeshSDF)
  318. {
  319. float TotalVolume = 0.0f;
  320. Vector3 averageScale = Vector3.zero;
  321. Vector3 averagePosition = Vector3.zero;
  322. SkinnedMeshSDF skinnedMeshSDF = manipulator.GetComponent<SkinnedMeshSDF>();
  323. sdf.Type = (int)SDFObject.SDFObjectType.Group;
  324. sdf.ObjectID = SDFObjectList.Count;
  325. sdf.SDFTextureBlocks = skinnedMeshSDF.BoneSDFList.Count;
  326. foreach (var bone in skinnedMeshSDF.BoneSDFList)
  327. {
  328. SDFObjectParams boneSDF = GetSDF(bone, manipulator);
  329. TotalVolume += boneSDF.BBoxVolume;
  330. averageScale += boneSDF.Scale;
  331. averagePosition += boneSDF.Position;
  332. boneSDF.ManipulatorID = ID;
  333. SDFObjectList.Add(boneSDF);
  334. }
  335. sdf.Position = averagePosition / skinnedMeshSDF.BoneSDFList.Count;
  336. sdf.Scale = averageScale / skinnedMeshSDF.BoneSDFList.Count;
  337. sdf.TotalGroupVolume = TotalVolume;
  338. }
  339. if (manipulator is ZibraLiquidEmitter)
  340. manipulator.CurrentInteractionMode = Manipulator.InteractionMode.OnlySelectedParticleSpecies;
  341. switch (manipulator.CurrentInteractionMode)
  342. {
  343. case Manipulator.InteractionMode.AllParticleSpecies:
  344. manip.ParticleSpecies = 0;
  345. break;
  346. case Manipulator.InteractionMode.OnlySelectedParticleSpecies:
  347. manip.ParticleSpecies = 1 + manipulator.ParticleSpecies;
  348. break;
  349. case Manipulator.InteractionMode.ExceptSelectedParticleSpecies:
  350. manip.ParticleSpecies = -(1 + manipulator.ParticleSpecies);
  351. break;
  352. }
  353. if (manipulator is ZibraLiquidEmitter)
  354. {
  355. ZibraLiquidEmitter emitter = manipulator as ZibraLiquidEmitter;
  356. float particlesPerSec = emitter.VolumePerSimTime / parent.NodeSize / parent.NodeSize /
  357. parent.NodeSize * parent.SolverParameters.ParticleDensity;
  358. manip.AdditionalData0.x = Mathf.Floor(particlesPerSec * deltaTime);
  359. manip.ParticleSpecies = manipulator.ParticleSpecies;
  360. }
  361. if (manipulator is ZibraLiquidVoid)
  362. {
  363. ZibraLiquidVoid liquidVoid = manipulator as ZibraLiquidVoid;
  364. // Deletion percentage per frame is set in % / per "ZibraLiquid.DEFAULT_SIMULATION_TIME_SCALE" units
  365. // of simulation time. 1 real second = (parent.SimulationTimeScale) units of simulation time. For
  366. // example, deletePercentagePerDefaultSimulationTime = 0.5, parent.SimulationTimeScale = 100, then
  367. // after 1 real second there should be only (50%) ^ (100 / 40) = 17% particles left. Therefore, to
  368. // calculate percentage per frame:
  369. // percentageThatWillLeftPerFrame = pow(deletePercentage, FPS * (1 /
  370. // simulationTimeScaleDifference)),
  371. // and
  372. // deletionPercentagePerFrame = 1 - pow(1 - deletePercentage, 1/FPS *
  373. // simulationTimeScaleDifference)
  374. float simulationTimeScaleDifference =
  375. ZibraLiquid.DEFAULT_SIMULATION_TIME_SCALE / parent.SimulationTimeScale;
  376. float deltaTimeInRealSeconds = deltaTime / parent.SimulationTimeScale;
  377. float deletionPercentagePerFrame =
  378. 1.0f - Mathf.Pow(1.0f - liquidVoid.DeletePercentage,
  379. deltaTimeInRealSeconds * simulationTimeScaleDifference);
  380. manip.AdditionalData0.x = deletionPercentagePerFrame;
  381. }
  382. manip.SDFObjectID = SDFObjectList.Count;
  383. sdf.ManipulatorID = ID;
  384. SDFObjectList.Add(sdf);
  385. ManipulatorParams.Add(manip);
  386. ID++;
  387. }
  388. Elements = Manipulators.Count;
  389. }
  390. private static float INT2Float(int a)
  391. {
  392. const float MAX_INT = 2147483647.0f;
  393. const float F2I_MAX_VALUE = 5000.0f;
  394. const float F2I_SCALE = (MAX_INT / F2I_MAX_VALUE);
  395. return a / F2I_SCALE;
  396. }
  397. private int GetStatIndex(int id, int offset)
  398. {
  399. return id * Solver.ZibraLiquid.STATISTICS_PER_MANIPULATOR + offset;
  400. }
  401. private Vector3 Simulation2Local(Vector3 pos, ZibraLiquid parent)
  402. {
  403. return new Vector3(parent.ContainerSize.x * pos.x / parent.GridSize.x - parent.ContainerSize.x * 0.5f,
  404. parent.ContainerSize.y * pos.y / parent.GridSize.y - parent.ContainerSize.y * 0.5f,
  405. parent.ContainerSize.z * pos.z / parent.GridSize.z - parent.ContainerSize.z * 0.5f);
  406. }
  407. private Vector3 Simulation2World(Vector3 pos, ZibraLiquid parent)
  408. {
  409. return Simulation2Local(pos, parent) + parent.transform.position;
  410. }
  411. private Vector3 EncodedSimulationSpaceToWorldSpace(Vector3 encodedPos, ZibraLiquid parent,
  412. bool inverted = false)
  413. {
  414. Vector3 simulationPosition = Vector3.Scale(encodedPos / ((float)Int32.MaxValue), parent.GridSize);
  415. if (inverted)
  416. {
  417. simulationPosition = parent.GridSize - simulationPosition;
  418. }
  419. return Simulation2World(simulationPosition, parent);
  420. }
  421. /// <summary>
  422. /// Update manipulator statistics
  423. /// </summary>
  424. public void UpdateStatistics(ZibraLiquid parent, Int32[] data, List<Manipulator> curManipulators,
  425. DataStructures.ZibraLiquidSolverParameters solverParameters,
  426. List<ZibraLiquidCollider> sdfObjects)
  427. {
  428. int id = 0;
  429. foreach (var manipulator in Manipulators)
  430. {
  431. if (manipulator == null)
  432. continue;
  433. Vector3 Force = Mathf.Exp(4.0f * solverParameters.ForceInteractionStrength) *
  434. new Vector3(INT2Float(data[GetStatIndex(id, 0)]), INT2Float(data[GetStatIndex(id, 1)]),
  435. INT2Float(data[GetStatIndex(id, 2)]));
  436. Vector3 Torque = Mathf.Exp(4.0f * solverParameters.ForceInteractionStrength) *
  437. new Vector3(INT2Float(data[GetStatIndex(id, 3)]), INT2Float(data[GetStatIndex(id, 4)]),
  438. INT2Float(data[GetStatIndex(id, 5)]));
  439. switch (manipulator.GetManipulatorType())
  440. {
  441. default:
  442. break;
  443. case Manipulator.ManipulatorType.Emitter:
  444. ZibraLiquidEmitter emitter = manipulator as ZibraLiquidEmitter;
  445. emitter.CreatedParticlesPerFrame = data[GetStatIndex(id, 0)];
  446. emitter.CreatedParticlesTotal += emitter.CreatedParticlesPerFrame;
  447. break;
  448. case Manipulator.ManipulatorType.Void:
  449. ZibraLiquidVoid zibravoid = manipulator as ZibraLiquidVoid;
  450. zibravoid.DeletedParticleCountPerFrame = data[GetStatIndex(id, 0)];
  451. zibravoid.DeletedParticleCountTotal += zibravoid.DeletedParticleCountPerFrame;
  452. break;
  453. case Manipulator.ManipulatorType.Detector:
  454. ZibraLiquidDetector zibradetector = manipulator as ZibraLiquidDetector;
  455. zibradetector.ParticlesInside = data[GetStatIndex(id, 0)];
  456. if (zibradetector.ParticlesInside > 0)
  457. {
  458. // Decode bounding box position and convert them to world space.
  459. zibradetector.BoundingBoxMin = EncodedSimulationSpaceToWorldSpace(
  460. new Vector3(data[GetStatIndex(id, 1)], data[GetStatIndex(id, 2)],
  461. data[GetStatIndex(id, 3)]),
  462. parent,
  463. true // BoundingBoxMin is inverted to simulate atomic min in the compute shader.
  464. );
  465. zibradetector.BoundingBoxMax = EncodedSimulationSpaceToWorldSpace(
  466. new Vector3(data[GetStatIndex(id, 4)], data[GetStatIndex(id, 5)],
  467. data[GetStatIndex(id, 6)]),
  468. parent);
  469. }
  470. else
  471. {
  472. zibradetector.BoundingBoxMin = new Vector3(0.0f, 0.0f, 0.0f);
  473. zibradetector.BoundingBoxMax = new Vector3(0.0f, 0.0f, 0.0f);
  474. }
  475. break;
  476. case Manipulator.ManipulatorType.NeuralCollider:
  477. case Manipulator.ManipulatorType.AnalyticCollider:
  478. ZibraLiquidCollider collider = manipulator as ZibraLiquidCollider;
  479. collider.ApplyForceTorque(Force, Torque);
  480. break;
  481. }
  482. #if UNITY_EDITOR
  483. manipulator.NotifyChange();
  484. #endif
  485. id++;
  486. }
  487. }
  488. /// <summary>
  489. /// Update constant object data and generate and sort the current manipulator list
  490. /// Should be executed once
  491. /// </summary>
  492. public void UpdateConst(List<Manipulator> curManipulators, List<ZibraLiquidCollider> colliders)
  493. {
  494. HeightmapBlit = GetComponent<ZibraLiquidMaterialParameters>().HeightmapBlit;
  495. Manipulators = new List<Manipulator>();
  496. NeuralSDFs = new Dictionary<ZibraHash128, NeuralSDF>();
  497. TextureHashMap = new Dictionary<ZibraHash128, int>();
  498. // add all colliders to the manipulator list
  499. foreach (var manipulator in curManipulators)
  500. {
  501. if (manipulator == null)
  502. continue;
  503. var sdf = manipulator.GetComponent<SDFObject>();
  504. if (sdf == null)
  505. {
  506. Debug.LogWarning("Manipulator " + manipulator.gameObject.name + " missing sdf and is disabled.");
  507. continue;
  508. }
  509. NeuralSDF neuralSDF = sdf as NeuralSDF;
  510. if (neuralSDF != null && !neuralSDF.ObjectRepresentation.HasRepresentationV3)
  511. {
  512. Debug.LogWarning("NeuralSDF in " + manipulator.gameObject.name +
  513. " was not generated. Manipulator is disabled.");
  514. continue;
  515. }
  516. TerrainSDF terrainSDF = sdf as TerrainSDF;
  517. if (terrainSDF != null)
  518. {
  519. Debug.LogWarning("TerrainSDF was used in " + manipulator.gameObject.name +
  520. " which is not supported. TerrainSDF only supported in colliders. " +
  521. "Manipulator is disabled.");
  522. continue;
  523. }
  524. if (sdf is SkinnedMeshSDF)
  525. {
  526. SkinnedMeshSDF skinnedMeshSDF = sdf as SkinnedMeshSDF;
  527. if (!skinnedMeshSDF.HasRepresentation())
  528. {
  529. Debug.LogWarning("SkinnedMeshSDF in " + manipulator.gameObject.name +
  530. " was not generated. Manipulator is disabled.");
  531. continue;
  532. }
  533. }
  534. if (sdf is SkinnedMeshSDF)
  535. {
  536. SkinnedMeshSDF skinnedMeshSDF = sdf as SkinnedMeshSDF;
  537. if (!skinnedMeshSDF.HasRepresentation())
  538. {
  539. Debug.LogWarning("SkinnedMeshSDF in " + manipulator.gameObject.name +
  540. " was not generated. Manipulator is disabled.");
  541. continue;
  542. }
  543. }
  544. Manipulators.Add(manipulator);
  545. }
  546. // add all colliders to the manipulator list
  547. foreach (var manipulator in colliders)
  548. {
  549. if (manipulator == null)
  550. continue;
  551. var sdf = manipulator.GetComponent<SDFObject>();
  552. if (sdf == null)
  553. {
  554. Debug.LogWarning("Collider " + manipulator.gameObject.name + " missing sdf and is disabled.");
  555. continue;
  556. }
  557. if (sdf is NeuralSDF)
  558. {
  559. NeuralSDF neuralSDF = sdf as NeuralSDF;
  560. if (!neuralSDF.ObjectRepresentation.HasRepresentationV3)
  561. {
  562. Debug.LogWarning("NeuralSDF in " + manipulator.gameObject.name +
  563. " was not generated. Collider is disabled.");
  564. continue;
  565. }
  566. }
  567. if (sdf is SkinnedMeshSDF)
  568. {
  569. SkinnedMeshSDF skinnedMeshSDF = sdf as SkinnedMeshSDF;
  570. if (!skinnedMeshSDF.HasRepresentation())
  571. {
  572. Debug.LogWarning("SkinnedMeshSDF in " + manipulator.gameObject.name +
  573. " was not generated. Collider is disabled.");
  574. continue;
  575. }
  576. }
  577. TerrainSDF terrainSDF = sdf as TerrainSDF;
  578. if (terrainSDF != null)
  579. {
  580. Terrain terrain = terrainSDF.GetComponent<Terrain>();
  581. if (terrain == null)
  582. {
  583. Debug.LogWarning("TerrainSDF in " + manipulator.gameObject.name +
  584. " is missing Terrain component. Collider is disabled.");
  585. continue;
  586. }
  587. if (terrain.terrainData == null)
  588. {
  589. Debug.LogWarning("TerrainSDF in " + manipulator.gameObject.name +
  590. " is missing TerrainData in Terrain component. Collider is disabled.");
  591. continue;
  592. }
  593. }
  594. Manipulators.Add(manipulator);
  595. }
  596. // first sort the manipulators
  597. Manipulators.Sort(new ManipulatorCompare());
  598. // compute prefix sum
  599. for (int i = 0; i < (int)Manipulator.ManipulatorType.TypeNum; i++)
  600. {
  601. int id = 0;
  602. foreach (var manipulator in Manipulators)
  603. {
  604. if ((int)manipulator.GetManipulatorType() >= i)
  605. {
  606. TypeIndex[i] = id;
  607. break;
  608. }
  609. id++;
  610. }
  611. if (id == Manipulators.Count)
  612. {
  613. TypeIndex[i] = Manipulators.Count;
  614. }
  615. }
  616. // set last as the total number of manipulators
  617. TypeIndex[(int)Manipulator.ManipulatorType.TypeNum] = Manipulators.Count;
  618. Indices.EmitterIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.Emitter];
  619. Indices.EmitterIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.Emitter + 1];
  620. Indices.VoidIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.Void];
  621. Indices.VoidIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.Void + 1];
  622. Indices.ForceFieldIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.ForceField];
  623. Indices.ForceFieldIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.ForceField + 1];
  624. Indices.AnalyticColliderIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.AnalyticCollider];
  625. Indices.AnalyticColliderIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.AnalyticCollider + 1];
  626. Indices.NeuralColliderIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.NeuralCollider];
  627. Indices.NeuralColliderIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.NeuralCollider + 1];
  628. Indices.GroupColliderIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.GroupCollider];
  629. Indices.GroupColliderIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.GroupCollider + 1];
  630. Indices.DetectorIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.Detector];
  631. Indices.DetectorIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.Detector + 1];
  632. Indices.SpeciesModifierIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.SpeciesModifier];
  633. Indices.SpeciesModifierIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.SpeciesModifier + 1];
  634. Indices.HeightmapColliderIndexBegin = TypeIndex[(int)Manipulator.ManipulatorType.HeightmapCollider];
  635. Indices.HeightmapColliderIndexEnd = TypeIndex[(int)Manipulator.ManipulatorType.HeightmapCollider + 1];
  636. if (ConstDataID.Count != 0)
  637. {
  638. ConstDataID.Clear();
  639. }
  640. SDFTextureSize = 0;
  641. EmbeddingTextureSize = 0;
  642. TextureCount = 0;
  643. HeightmapCount = 0;
  644. foreach (var manipulator in Manipulators)
  645. {
  646. if (manipulator == null)
  647. continue;
  648. if (manipulator.GetComponent<NeuralSDF>() != null)
  649. {
  650. AddTexture(manipulator.GetComponent<NeuralSDF>());
  651. }
  652. if (manipulator.GetComponent<SkinnedMeshSDF>() != null)
  653. {
  654. SkinnedMeshSDF skinnedMeshSDF = manipulator.GetComponent<SkinnedMeshSDF>();
  655. foreach (var bone in skinnedMeshSDF.BoneSDFList)
  656. {
  657. if (bone is NeuralSDF neuralBone)
  658. AddTexture(neuralBone);
  659. }
  660. }
  661. if (manipulator.GetComponent<TerrainSDF>() != null)
  662. {
  663. HeightmapCount++;
  664. }
  665. }
  666. CalculateTextureData();
  667. }
  668. }
  669. }