{
  "Name": "FluidSolver",
  "_id": "d32ed613-96a4-445f-9224-56582565b9d4",
  "Namespace": "user.cynic",
  "Description": "",
  "Inputs": [
    {
      "Name": "Code",
      "MetaInstanceID": "bcfc0860-e85c-43d0-8ad5-322bbd5eefea",
      "DefaultValue": {
        "Type": "Text",
        "Value": [
          "//float2 RenderTargetSize;\r",
          "\r",
          "   \r",
          "RWTexture2D<float4> output     : register (u0);\r",
          "\r",
          "Texture3D<float4> velocity : register (t0);\r",
          "Texture3D<float4> velocityA : register (t1);    \r",
          "Texture3D<float4> velocityAR : register (t2);\r",
          "RWTexture3D<float4> velocityOut : register (u0);\r",
          "\r",
          "Texture3D<float> velocitySize : register (t0);    \r",
          "RWTexture3D<float> velocitySizeRW : register (u1);  \r",
          "\r",
          "Texture3D<float4> divergence : register (t0);  \r",
          "RWTexture3D<float4> divergenceRW : register (u0);  \r",
          "\r",
          "Texture3D<float4> pressure : register (t1);\r",
          "RWTexture3D<float4> pressureRW : register (u0);\r",
          "\r",
          "Texture3D<float4> boundriesVolume : register(t2);\r",
          "\r",
          "SamplerState samLinear : register(s0);\r",
          "\r",
          "cbuffer cbWave3D : register(b0)\r",
          "{\r",
          "  float4 dim;  // size of volume\r",
          "  \r",
          "  uint width;  // size viewport\r",
          "  uint height;\r",
          "  \r",
          "  uint viewSlice;  // slice of volume to render\r",
          "  uint viewOrientation; // 0,1,2  for xy slice, yz sice, xz slice\r",
          "  \r",
          "  float4 mouse; \r",
          "  float4 dragDirection;\r",
          "  \r",
          "  float4x4 rotation;       \r",
          "  float zoom;\r",
          "  int   smoky;  // toggle between fire or smoky simuliation\r",
          "};\r",
          "\r",
          "static const float timestep = 1.0;\r",
          "\r",
          "//>>> CSAdvection\r",
          "// advection of velocity as by stam 99\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSAdvection(uint3 groupId : SV_GroupID, uint3 threadId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID, uint groupIdx : SV_GroupIndex)\r",
          "{ \r",
          "    float3 cellVelocity = velocity[threadId];\r",
          "\r",
          "    float3 pos = threadId;\r",
          "    pos -= timestep*cellVelocity;\r",
          "    pos = (pos + 0.5)/dim; // generate texture coords\r",
          "\r",
          "    velocityOut[threadId] = velocity.SampleLevel(samLinear, pos, 0);\r",
          "}\r",
          "//<<< CSAdvection\r",
          "\r",
          "\r",
          "//>>> CSAdvectionBackwards\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSAdvectionBackwards(uint3 groupId : SV_GroupID, uint3 threadId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID, uint groupIdx : SV_GroupIndex)\r",
          "{ \r",
          "    float3 cellVelocity = velocity[threadId];\r",
          "\r",
          "    float3 pos = threadId;\r",
          "    pos += timestep*cellVelocity;\r",
          "    pos = (pos + 0.5)/dim; // generate texture coords\r",
          "\r",
          "    velocityOut[threadId] = velocity.SampleLevel(samLinear, pos, 0);\r",
          "}\r",
          "//<<< CSAdvectionBackwards\r",
          "\r",
          "\r",
          "//>>> CSAdvectionMacCormack\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSAdvectionMacCormack(uint3 groupId : SV_GroupID, uint3 threadId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID, uint groupIdx : SV_GroupIndex)\r",
          "{\r",
          "    // back trace position\r",
          "    uint3 j = (uint3) (threadId - timestep*velocity[threadId]);\r",
          "\r",
          "//    uint3 j = (uint3) pos;\r",
          "//    pos = (pos + 0.5)/dim;\r",
          "\r",
          "    // fetch neighbor velocities (point sampling)\r",
          "    float4 n[8];\r",
          "    n[0] = velocity[j + uint3(0,0,0)];\r",
          "    n[1] = velocity[j + uint3(1,0,0)];\r",
          "    n[2] = velocity[j + uint3(0,1,0)];\r",
          "    n[3] = velocity[j + uint3(1,1,0)];\r",
          "    n[4] = velocity[j + uint3(0,0,1)];\r",
          "    n[5] = velocity[j + uint3(1,0,1)];\r",
          "    n[6] = velocity[j + uint3(0,1,1)];\r",
          "    n[7] = velocity[j + uint3(1,1,1)];\r",
          "\r",
          "    float4 lmin = min(n[0], min(n[1], min(n[2], min(n[3], min(n[4], min(n[5], min(n[6], n[7])))))));\r",
          "    float4 lmax = max(n[0], max(n[1], max(n[2], max(n[3], max(n[4], max(n[5], max(n[6], n[7])))))));\r",
          "\r",
          "    // Perform final advection, combining values from intermediate advection steps\r",
          "    float4 phi_n = velocity[threadId];//velocity.SampleLevel(samLinear, sam, 0);\r",
          "    float4 phi_n_1_hat = velocityA[threadId]; //velocity.SampleLevel(samLinear, sam, 0);//\r",
          "    float4 phi_n_hat = velocityAR[threadId];\r",
          "    float4 s = phi_n_1_hat + 0.5*(phi_n - phi_n_hat);\r",
          "    s = clamp(s, lmin, lmax);\r",
          "\r",
          "    s.w = max(phi_n_1_hat.w - 0.001*timestep, 0);   // reaction coordinate\r",
          "\r",
          "    velocityOut[threadId] = s;\r",
          "}\r",
          "//<<< CSAdvectionMacCormack\r",
          "\r",
          "\r",
          "//>>> CSDrawSphere\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSDrawSphere( uint3 Gid : SV_GroupID, uint3 i : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )\r",
          "{ \r",
          "  // ray shooting through mouse position\r",
          "  float3 eye    = float3(0.0f, 0.0f, 4.0f);       \r",
          "  float3 raydir = float3( (2*mouse.xy - float2(width, height)) / min(width, height) *zoom , 0) - eye;\r",
          "  float3 viewdir  = 0                                                                          - eye;\r",
          "\r",
          "    // calc ray volume intersection, at plane through volume origin perpendicular to view direction\r",
          "  // ray = eye + t*raydir;    dot (viewdir, ray) = 0;\r",
          "  \r",
          "  float t = -dot(viewdir, eye) / dot(viewdir, raydir);\r",
          "  \r",
          "  float3 ball = eye + t*raydir;\r",
          "\r",
          "  // rotate vuew\r",
          "  ball        =  mul(              ball, rotation);\r",
          "  float3 force = mul( dragDirection.xyz, rotation)*zoom*4;\r",
          "  \r",
          "    // calc texture coordinates of intersection\r",
          "  ball  =  dim*(ball +1)/2;\r",
          "  \r",
          "  // calc volume coordinates relative to ball center\r",
          "  ball = i - ball;\r",
          "  \r",
          "  float r = dot(ball, ball);  // radius^2 square\r",
          "  \r",
          "  // draw spere\r",
          "  float g = exp( -r/(mouse.w*mouse.w));\r",
          "  velocityOut[i] = float4(velocity[i].xyz +  force* g, velocity[i].w + length(force)*g);   // put 1 in w, will serve as reaction counter    \r",
          "}\r",
          "//<<< CSDrawSphere\r",
          "\r",
          "\r",
          "//>>> CSDivergence\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSDivergence( uint3 Gid : SV_GroupID, uint3 i : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )\r",
          "{ \r",
          "    if (i.x >= dim.x/4)\r",
          "        return;\r",
          "\r",
          "//    float pxm, pxp, pym, pyp, pzm, pzp;\r",
          "    float divergence[4];\r",
          "    float4 f;\r",
          "    f[0] = 34;\r",
          "    [unroll]\r",
          "    for (int j = 0; j < 4; ++j)\r",
          "    { \r",
          "        uint3 i4 =  uint3(4*i.x+j, i.y, i.z);\r",
          "        float left  = velocity[i4 + uint3(-1, 0, 0)].x;\r",
          "        float right = velocity[i4 + uint3( 1, 0, 0)].x;\r",
          "        float bottom = velocity[i4 + uint3( 0,-1, 0)].y;\r",
          "        float top = velocity[i4 + uint3( 0, 1, 0)].y;\r",
          "        float down = velocity[i4 + uint3( 0, 0,-1)].z;\r",
          "        float up = velocity[i4 + uint3( 0, 0, 1)].z;    \r",
          "        divergence[j] =  0.5*((right - left) + (top - bottom) + (up - down));\r",
          "    }\r",
          "    divergenceRW[i] =  (float4)divergence;\r",
          "  \r",
          "}\r",
          "//<<< CSDivergence\r",
          "\r",
          "\r",
          "//>>> CSJacobi\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSJacobi( uint3 Gid : SV_GroupID, uint3 i : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )\r",
          "{ \r",
          "  if (i.x >= dim.x/4) \r",
          "    return;\r",
          "  \r",
          "  uint3 j;\r",
          "\r",
          "  j = uint3(max(i.x-1,0), i.y, i.z);\r",
          "  float4 pxm = float4(pressure[j].w, pressure[i + uint3( 0,0,0)].xyz);\r",
          "  j = uint3(min(i.x+1,dim.x-1), i.y, i.z);\r",
          "  float4 pxp = float4(pressure[i + uint3( 0,0,0)].yzw, pressure[j].x);  \r",
          " \r",
          "  j = uint3(i.x, max(i.y-1,0), i.z);\r",
          "  float4 pym = pressure[j];\r",
          "  j = uint3(i.x, min(i.y+1,dim.y-1), i.z);\r",
          "  float4 pyp = pressure[j];\r",
          "  \r",
          "  j = uint3(i.x, i.y, max(i.z-1,0));\r",
          "  float4 pzm = pressure[j];\r",
          "  j = uint3(i.x, i.y, min(i.z+1,dim.z-1));\r",
          "  float4 pzp = pressure[j];\r",
          "\r",
          "  \r",
          "  pressureRW[i] =  (pxp + pxm + pyp + pym + pzp + pzm - divergence[i])/6;\r",
          "}\r",
          "//<<< CSJacobi\r",
          "\r",
          "\r",
          "//>>> CSProjection\r",
          "[numthreads(16, 4, 4)]\r",
          "void CSProjection( uint3 Gid : SV_GroupID, uint3 i : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )\r",
          "{ \r",
          "  if (i.x >= dim.x/4) \r",
          "    return;\r",
          "\r",
          "  uint3 j;\r",
          "\r",
          "  j = uint3(max(i.x-1,0), i.y, i.z);\r",
          "  float4 pxm = float4(pressure[j].w, pressure[i + uint3( 0,0,0)].xyz);\r",
          "  j = uint3(min(i.x+1,dim.x-1), i.y, i.z);\r",
          "  float4 pxp = float4(pressure[i + uint3( 0,0,0)].yzw, pressure[j].x);  \r",
          " \r",
          "  j = uint3(i.x, max(i.y-1,0), i.z);\r",
          "  float4 pym = pressure[j];\r",
          "  j = uint3(i.x, min(i.y+1,dim.y-1), i.z);\r",
          "  float4 pyp = pressure[j];\r",
          "  \r",
          "  j = uint3(i.x, i.y, max(i.z-1,0));\r",
          "  float4 pzm = pressure[j];\r",
          "  j = uint3(i.x, i.y, min(i.z+1,dim.z-1));\r",
          "  float4 pzp = pressure[j];\r",
          "  \r",
          "  pxp -=pxm;\r",
          "  pyp -=pym;\r",
          "  pzp -=pzm;\r",
          "\r",
          "  float4 s;\r",
          "  i.x*=4;\r",
          "  bool borderyz = any(i.yz == 0 | i.yz==dim.yz-1);// || boundriesVolume[i].x > 0.1;\r",
          "  s = velocity[i] - float4(pxp.x, pyp.x, pzp.x,0)/2;  \r",
          "  velocityOut[i] =  ( i.x == 0 || borderyz ) ? -s : s;\r",
          "  velocitySizeRW[i] = smoky ? s.w : length(s.xyz);\r",
          "  i.x++;\r",
          "  s = velocity[i] - float4(pxp.y, pyp.y, pzp.y,0)/2;  \r",
          "  velocityOut[i] =  ( borderyz ) ? -s : s;\r",
          "  velocitySizeRW[i] = smoky ? s.w : length(s.xyz);\r",
          "  i.x++;\r",
          "  s = velocity[i] - float4(pxp.z, pyp.z, pzp.z,0)/2;  \r",
          "  velocityOut[i] =  ( borderyz ) ? -s : s;\r",
          "  velocitySizeRW[i] = smoky ? s.w : length(s.xyz);\r",
          "  i.x++;\r",
          "  s = velocity[i] - float4(pxp.w, pyp.w, pzp.w,0)/2;  \r",
          "  velocityOut[i] =  ( i.x == dim.x-1 || borderyz ) ? -s : s;\r",
          "  velocitySizeRW[i] = smoky ? s.w : length(s.xyz);\r",
          "\r",
          "  //velocityOut[i] =  velocity[i] - float4(pressure[i], pyp - pym, pzp -pzm,0)/2;\r",
          "}\r",
          "//<<<CSProjection\r",
          "\r",
          "\r",
          "//>>> CSRender\r",
          "[numthreads(16, 16, 1)]\r",
          "void CSRender( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )\r",
          "{ \r",
          "\r",
          "  float3 eye    = float3(0.0f, 0.0f, 4.0f);       \r",
          "  float3 raydir = float3( (2*DTid.xy - float2(width, height)) / min(width, height) *zoom , 0) - eye;\r",
          "\r",
          "  // rotate vuew\r",
          "  eye    = mul(   eye, rotation);\r",
          "  raydir = mul(raydir, rotation);\r",
          "\r",
          "  // calc ray volume intersection, volume cube centered at origin edge size 2\r",
          "  // ray = eye + t*raydir;   \r",
          "  // intersect at plane x = -1 and x = 1\r",
          "\r",
          "  float3 t1 = max((-1 - eye) / raydir, 0);\r",
          "  float3 t2 = max(( 1 - eye) / raydir, 0);\r",
          "\r",
          "  float3 front = min(t1, t2);\r",
          "  float3 back  = max(t1, t2);\r",
          "\r",
          "  float tfront = max(front.x, max(front.y, front.z));\r",
          "  float tback  = min( back.x, min( back.y,  back.z));\r",
          "\r",
          "  // calc texture coordinates of front and back intersection\r",
          "\r",
          "  float3 texf  =  (eye + tfront*raydir + 1)/2;\r",
          "  float3 texb  =  (eye + tback *raydir + 1)/2;\r",
          "\r",
          "  float steps = floor(length(texf - texb)*dim.x+0.5);\r",
          "  float3 texdir = (texb-texf)/steps;\r",
          "  \r",
          "  steps = (tfront >= tback) ? 0 : steps; // no intersection ?\r",
          "\r",
          "  float m = 0;\r",
          "  float alpha = 0;\r",
          "  for (float i=0.5; i< steps; i++)\r",
          "  {\r",
          "    float3 sam = texf + i*texdir;\r",
          "    float s = velocitySize.SampleLevel(samLinear, sam, 0);\r",
          "    float sa = s.r * 0.1;\r",
          "    float t = sa * (1.0 - alpha);\r",
          "    m += t * s.r;\r",
          "    alpha += t;    \r",
          "    //m = max(m, s);     \r",
          "  }\r",
          "\r",
          "\r",
          "  // hot metal color\r",
          "  //float4 col = saturate(lerp(float4(0,-1.41,-3, -0.4), float4(1.41,1.41,1, 1.41), m/3));\t\t \r",
          "  float4 col = float4(m,m,m,alpha );\r",
          "  output[DTid.xy] = col;\r",
          "}\r",
          "//<<< CSRender\r",
          "\r",
          "\r",
          ""
        ]
      },
      "MetaID": "c522a66e-3260-4692-b3e3-79fd0361fa3d",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "BoundryVolume",
      "MetaInstanceID": "f147537b-f949-4a65-b2b7-08e49522e717",
      "DefaultValue": {
        "Type": "Scene",
        "Value": "Framefield.Core.Scene"
      },
      "MetaID": "9848060d-fd84-45b0-b658-d0d531c61dab",
      "IsMultiInput": "False",
      "Relevance": "Relevant",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Image",
      "MetaInstanceID": "532e5049-5fbb-47ea-bb20-eaead4456b97",
      "MetaID": "9848060d-fd84-45b0-b658-d0d531c61dab"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "b521434f-93d6-4f88-921f-efaf1ac4c0b5",
      "MetaID": "a83e988e-f959-4453-8940-0bc65cd08ab7",
      "Name": "FluidSolverFunc",
      "Version": "9876a207-20bc-4158-9132-8eec3aff46d2",
      "Type": "Float",
      "IsMultiInput": "True",
      "Script": [
        "//>>> _using",
        "using System;",
        "using System.Collections.Generic;",
        "using System.Linq;",
        "using System.Text;",
        "using SharpDX;",
        "using SharpDX.Direct3D11;",
        "using SharpDX.Windows;",
        "//<<< _using",
        "",
        "using System.Runtime.InteropServices;",
        "using Framefield.Core.Rendering;",
        "using SharpDX.DXGI;",
        "using SharpDX.D3DCompiler;",
        "using Buffer = SharpDX.Direct3D11.Buffer;",
        "using System.CodeDom.Compiler;",
        "using System.Diagnostics;",
        "",
        "",
        "namespace Framefield.Core.IDa83e988e_f959_4453_8940_0bc65cd08ab7",
        "{",
        "    public class Class_FluidSolver : FXSourceCodeFunction, Framefield.Core.OperatorPartTraits.ITimeAccessor",
        "    {",
        "",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            Code = 0,",
        "            BoundryVolume = 1",
        "        }",
        "        //<<< _inputids",
        "",
        "        public override void Dispose()",
        "        {",
        "            for (int i = 0; i < 3; ++i)",
        "            {",
        "                Utilities.DisposeObj(ref _velocityVolumes[i]);",
        "                Utilities.DisposeObj(ref _velocitySRVs[i]);",
        "                Utilities.DisposeObj(ref _velocityUAVs[i]);",
        "            }",
        "",
        "            for (int i = 0; i < 2; ++i)",
        "            {",
        "                Utilities.DisposeObj(ref _pressureVolumes[i]);",
        "                Utilities.DisposeObj(ref _pressureSRVs[i]);",
        "                Utilities.DisposeObj(ref _pressureUAVs[i]);",
        "            }",
        "",
        "            Utilities.DisposeObj(ref _divergenceVolume);",
        "            Utilities.DisposeObj(ref _divergenceSRV);",
        "            Utilities.DisposeObj(ref _divergenceUAV);",
        "            Utilities.DisposeObj(ref _velocitySizeVolume);",
        "            Utilities.DisposeObj(ref _velocitySizeSRV);",
        "            Utilities.DisposeObj(ref _velocitySizeUAV);",
        "",
        "            Utilities.DisposeObj(ref _linearSamplerState);",
        "            Utilities.DisposeObj(ref _constBuffer);",
        "",
        "            Utilities.DisposeObj(ref _visuTexture);",
        "            Utilities.DisposeObj(ref _csAdvection);",
        "            Utilities.DisposeObj(ref _csAdvectionBackwards);",
        "            Utilities.DisposeObj(ref _csAdvectionMacCormack);",
        "            Utilities.DisposeObj(ref _csDrawSphere);",
        "            Utilities.DisposeObj(ref _csDivergence);",
        "            Utilities.DisposeObj(ref _csJacobi);",
        "            Utilities.DisposeObj(ref _csProjection);",
        "            Utilities.DisposeObj(ref _csRender);",
        "            Utilities.DisposeObj(ref _csVisu);",
        "            base.Dispose();",
        "        }",
        "",
        "",
        "        [StructLayout(LayoutKind.Explicit, Size = 144)]",
        "        public struct ConstBufferLayout",
        "        {",
        "            [FieldOffset(0)] ",
        "            public Vector4 Dim;",
        "            [FieldOffset(16)] ",
        "            public int width;",
        "            [FieldOffset(20)] ",
        "            public int height;",
        "            [FieldOffset(24)] ",
        "            public int viewSlice;",
        "            [FieldOffset(28)] ",
        "            public int viewOrientation;",
        "            [FieldOffset(32)] ",
        "            public Vector4 mouse;",
        "            [FieldOffset(48)] ",
        "            public Vector4 dragDirection;",
        "            [FieldOffset(64)] ",
        "            public Matrix orientation;",
        "            [FieldOffset(128)] ",
        "            public float zoom;",
        "            [FieldOffset(132)] ",
        "            public int smoky;",
        "        }",
        "",
        "        private readonly int SIZE = 256;",
        "",
        "        protected bool BuildRenderTarget(OperatorPartContext context)",
        "        {",
        "            if (_visuTexture == null ||",
        "                (int) context.Viewport.Width != _visuTexture.Description.Width ||",
        "                (int) context.Viewport.Height != _visuTexture.Description.Height)",
        "            {",
        "                var uavVisuDesc = new Texture2DDescription",
        "                                      {",
        "                                          BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess,",
        "                                          Format = Format.R8G8B8A8_UNorm,",
        "                                          Width = (int) context.Viewport.Width,",
        "                                          Height = (int) context.Viewport.Height,",
        "                                          MipLevels = 1,",
        "                                          SampleDescription = new SampleDescription(1, 0),",
        "                                          Usage = ResourceUsage.Default,",
        "                                          OptionFlags = ResourceOptionFlags.None,",
        "                                          CpuAccessFlags = CpuAccessFlags.None,",
        "                                          ArraySize = 1",
        "                                      };",
        "                Utilities.DisposeObj(ref _visuTexture);",
        "                Utilities.DisposeObj(ref _visuUAV);",
        "                _visuTexture = new Texture2D(context.D3DDevice, uavVisuDesc);",
        "                _visuUAV = new UnorderedAccessView(context.D3DDevice, _visuTexture);",
        "            }",
        "",
        "            if (_velocityVolumes[0] != null)",
        "            {",
        "                return false;",
        "            }",
        "",
        "            // generate velocity volumes   ",
        "            var volumeDesc = new Texture3DDescription",
        "                                 {",
        "                                     BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess,",
        "                                     Format = Format.R16G16B16A16_Float,",
        "                                     Width = SIZE,",
        "                                     Height = SIZE,",
        "                                     Depth = SIZE,",
        "                                     MipLevels = 1,",
        "                                     Usage = ResourceUsage.Default,",
        "                                     OptionFlags = ResourceOptionFlags.None,",
        "                                     CpuAccessFlags = CpuAccessFlags.None,",
        "                                 };",
        "",
        "            for (int i = 0; i < 4; ++i)",
        "            {",
        "                Utilities.DisposeObj(ref _velocityVolumes[i]);",
        "                Utilities.DisposeObj(ref _velocitySRVs[i]);",
        "                Utilities.DisposeObj(ref _velocityUAVs[i]);",
        "                _velocityVolumes[i] = new Texture3D(context.D3DDevice, volumeDesc);",
        "                _velocitySRVs[i] = new ShaderResourceView(context.D3DDevice, _velocityVolumes[i]);",
        "                _velocityUAVs[i] = new UnorderedAccessView(context.D3DDevice, _velocityVolumes[i]);",
        "            }",
        "",
        "            // generate pressure volumes",
        "            volumeDesc.Width = SIZE/4;",
        "",
        "            for (int i = 0; i < 2; ++i)",
        "            {",
        "                Utilities.DisposeObj(ref _pressureVolumes[i]);",
        "                Utilities.DisposeObj(ref _pressureSRVs[i]);",
        "                Utilities.DisposeObj(ref _pressureUAVs[i]);",
        "                _pressureVolumes[i] = new Texture3D(context.D3DDevice, volumeDesc);",
        "                _pressureSRVs[i] = new ShaderResourceView(context.D3DDevice, _pressureVolumes[i]);",
        "                _pressureUAVs[i] = new UnorderedAccessView(context.D3DDevice, _pressureVolumes[i]);",
        "            }",
        "",
        "            // generate divergence volume",
        "            Utilities.DisposeObj(ref _divergenceVolume);",
        "            Utilities.DisposeObj(ref _divergenceSRV);",
        "            Utilities.DisposeObj(ref _divergenceUAV);",
        "            _divergenceVolume = new Texture3D(context.D3DDevice, volumeDesc);",
        "            _divergenceSRV = new ShaderResourceView(context.D3DDevice, _divergenceVolume);",
        "            _divergenceUAV = new UnorderedAccessView(context.D3DDevice, _divergenceVolume);",
        "",
        "",
        "            // velocity size (length velocity vector)",
        "            volumeDesc.Format = Format.R16_Float;",
        "            volumeDesc.Width = SIZE;",
        "",
        "            Utilities.DisposeObj(ref _velocitySizeVolume);",
        "            Utilities.DisposeObj(ref _velocitySizeSRV);",
        "            Utilities.DisposeObj(ref _velocitySizeUAV);",
        "            _velocitySizeVolume = new Texture3D(context.D3DDevice, volumeDesc);",
        "            _velocitySizeSRV = new ShaderResourceView(context.D3DDevice, _velocitySizeVolume);",
        "            _velocitySizeUAV = new UnorderedAccessView(context.D3DDevice, _velocitySizeVolume);",
        "",
        "            // create sampler state",
        "            var samplerDesc = new SamplerStateDescription()",
        "                                  {",
        "                                      Filter = Filter.MinMagMipLinear,",
        "                                      AddressU = TextureAddressMode.Border,",
        "                                      AddressV = TextureAddressMode.Border,",
        "                                      AddressW = TextureAddressMode.Border,",
        "                                      BorderColor = new Color4(0, 0, 0, 0),",
        "                                      MipLodBias = 0,",
        "                                      ComparisonFunction = Comparison.Never,",
        "                                      MaximumAnisotropy = 16,",
        "                                      MinimumLod = 0,",
        "                                      MaximumLod = Single.MaxValue",
        "                                  };",
        "            Utilities.DisposeObj(ref _linearSamplerState);",
        "            _linearSamplerState = new SamplerState(context.D3DDevice, samplerDesc);",
        "",
        "            return true;",
        "        }",
        "",
        "        static int _counter = 0;",
        "",
        "        private void SetupConstBuffer(OperatorPartContext context)",
        "        {",
        "            var mc = new ConstBufferLayout();",
        "",
        "            mc.Dim[0] = SIZE;",
        "            mc.Dim[1] = SIZE;",
        "            mc.Dim[2] = SIZE;",
        "",
        "            mc.width  = (int) context.Viewport.Width;",
        "            mc.height = (int) context.Viewport.Height;",
        "",
        "            mc.viewSlice = SIZE/2;",
        "            mc.viewOrientation = 0;",
        "  ",
        "            var mod = _counter++ % 80;",
        "            var cos = (float)Math.Cos(_counter * 2.0f * 3.1415f / 180.0f);",
        "            var sin = (float)Math.Sin(_counter * 2.0f * 3.1415f / 180.0f);",
        "            mc.mouse[0] = mc.width/2.0f;// + cos*mc.width/6.9f;",
        "            mc.mouse[1] = mc.height/2.0f;// + sin*mc.height/6.5f;",
        "            mc.mouse[2] = SIZE/2; ",
        "            mc.mouse[3] = 10 ; // radius in voxels;",
        " ",
        "            mc.dragDirection[0] = cos;//-cos*0.5f;",
        "            mc.dragDirection[1] = sin;//(mod < 20) ? -2 : 0;",
        "            mc.dragDirection[2] = 0;",
        "            mc.orientation = Matrix.Identity;//RotationY(context.Time);",
        "            mc.zoom = 1.2f;",
        "            mc.smoky = 0;",
        "",
        "            BaseRenderer.SetupConstBufferForCS(context, mc, ref _constBuffer, 0);",
        "        }",
        "",
        "        void RunShader(DeviceContext immediateContext, ComputeShader shader, ShaderResourceView in0, ShaderResourceView in1, ShaderResourceView in2, UnorderedAccessView out0, UnorderedAccessView out1, int dx, int dy, int dz)",
        "        {",
        "            // Set volumes as textures for cached read",
        "            immediateContext.ComputeShader.SetShaderResource(0, in0);",
        "            immediateContext.ComputeShader.SetShaderResource(1, in1);",
        "            immediateContext.ComputeShader.SetShaderResource(2, in2);",
        "",
        "            // Set unordered access views for writees",
        "            immediateContext.ComputeShader.SetUnorderedAccessView(0, out0);",
        "            immediateContext.ComputeShader.SetUnorderedAccessView(1, out1);",
        "",
        "           // Set compute shader",
        "            immediateContext.ComputeShader.Set(shader);",
        "",
        "            // Run compute shader",
        "            immediateContext.Dispatch(dx, dy, dz);",
        "",
        "            immediateContext.ComputeShader.SetShaderResource(0, null);",
        "            immediateContext.ComputeShader.SetShaderResource(1, null);",
        "            immediateContext.ComputeShader.SetShaderResource(2, null);",
        "            immediateContext.ComputeShader.SetUnorderedAccessView(0, null);",
        "            immediateContext.ComputeShader.SetUnorderedAccessView(1, null);",
        "        }",
        "",
        "        private Stopwatch _stopwatch = new Stopwatch();",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx) ",
        "        {",
        "            //>>> _params",
        "            var Code = inputs[(int)InputId.Code].Eval(context).Text;",
        "            var BoundryVolume = inputs[(int)InputId.BoundryVolume].Eval(context).Volume;",
        "            //<<< __params",
        "",
        "            if (!Changed)",
        "            {",
        "                context.Image = _visuTexture;",
        "                context.Volume = _velocitySizeVolume;",
        "                return context;",
        "            }",
        "",
        "            if (_csAdvection == null)",
        "            {",
        "                Utilities.DisposeObj(ref _csAdvection);",
        "                Utilities.DisposeObj(ref _csDrawSphere);",
        "                Utilities.DisposeObj(ref _csDivergence);",
        "                Utilities.DisposeObj(ref _csJacobi);",
        "                Utilities.DisposeObj(ref _csProjection);",
        "                Utilities.DisposeObj(ref _csRender);",
        "                Utilities.DisposeObj(ref _csVisu);",
        "                var errors = new CompilerErrorCollection();",
        "                try",
        "                {",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSAdvection\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csAdvection = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSAdvectionBackwards\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csAdvectionBackwards = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSAdvectionMacCormack\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csAdvectionMacCormack = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSDrawSphere\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csDrawSphere = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSDivergence\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csDivergence = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSJacobi\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csJacobi = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSProjection\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csProjection = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.Compile(GetCode(0), \"CSRender\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csRender = new ComputeShader(D3DDevice.Device, bytecode);",
        "/*                        ",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSAdvection\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csAdvection = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    _csAdvection.DebugName = \"CSAdvection4123\";",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSAdvectionBackwards\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csAdvectionBackwards = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSAdvectionMacCormack\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csAdvectionMacCormack = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSDrawSphere\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csDrawSphere = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSDivergence\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csDivergence = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSJacobi\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csJacobi = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSProjection\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csProjection = new ComputeShader(D3DDevice.Device, bytecode);",
        "                    using (var bytecode = ShaderBytecode.CompileFromFile(\"fluidsolver.hlsl\", \"CSRender\", \"cs_5_0\", ShaderFlags.Debug))",
        "                        _csRender = new ComputeShader(D3DDevice.Device, bytecode);",
        "*/                        ",
        "                }",
        "                catch (CompilationException ex)",
        "                {",
        "                    errors = ErrorsFromString(ex.Message);",
        "                    Logger.Error(this,\"CS compile error: {0}\", ex.Message);",
        "                }",
        "            }",
        "",
        "            BuildRenderTarget(context);",
        "",
        "            //_effect.GetVariableByName(\"RenderTargetSize\").AsVector().Set(new Vector2(_usedViewport.Width, _usedViewport.Height));",
        "//            _stopwatch.Restart();",
        "",
        "            var deviceContext = context.D3DDevice.ImmediateContext;",
        "",
        "            SetupConstBuffer(context);",
        "            deviceContext.ComputeShader.SetSampler(0, _linearSamplerState);",
        "",
        "            RunShader(deviceContext, _csAdvection, _velocitySRVs[0], null, null, _velocityUAVs[1], null, (SIZE + 15) / 16, SIZE / 4, SIZE / 4);",
        "",
        "            //  second order correction",
        "            RunShader(deviceContext, _csAdvectionBackwards, _velocitySRVs[1], null, null, _velocityUAVs[2], null, (SIZE + 15) / 16, SIZE / 4, SIZE / 4);",
        "            RunShader(deviceContext, _csAdvectionMacCormack, _velocitySRVs[0], _velocitySRVs[1], _velocitySRVs[2], _velocityUAVs[3], null, (SIZE + 15) / 16, SIZE / 4, SIZE / 4);",
        "",
        "            // velocity injection",
        "            RunShader(deviceContext, _csDrawSphere, _velocitySRVs[3], null, null, _velocityUAVs[0], null, (SIZE + 15) / 16, SIZE / 4, SIZE / 4);",
        "",
        "            // calc speed divergence",
        "            RunShader(deviceContext, _csDivergence, _velocitySRVs[0], null, null, _divergenceUAV, null, (SIZE + 63) / 64, SIZE / 4, SIZE / 4);",
        "",
        "            // jacobi",
        "            for (int i = 0; i < 20; i++)",
        "            {",
        "                RunShader(deviceContext, _csJacobi, _divergenceSRV, _pressureSRVs[1], null, _pressureUAVs[0], null, (SIZE + 63) / 64, SIZE / 4, SIZE / 4);",
        "                RunShader(deviceContext, _csJacobi, _divergenceSRV, _pressureSRVs[0], null, _pressureUAVs[1], null, (SIZE + 63) / 64, SIZE / 4, SIZE / 4);",
        "            }",
        "",
        "",
        "            // project",
        "            if (BoundryVolume != null)",
        "            {",
        "                var boundriesSRV = new ShaderResourceView(context.D3DDevice, context.Volume);",
        "                deviceContext.ComputeShader.SetShaderResource(2, boundriesSRV);",
        "                RunShader(deviceContext, _csProjection, _velocitySRVs[0], _pressureSRVs[1], boundriesSRV, _velocityUAVs[1], _velocitySizeUAV, (SIZE + 63) / 64, SIZE / 4, SIZE / 4);",
        "                deviceContext.ComputeShader.SetShaderResource(2, null);",
        "                boundriesSRV.Dispose();",
        "                //Logger.Info(\"jkfldjfl\");",
        "            }",
        "            else",
        "                RunShader(deviceContext, _csProjection, _velocitySRVs[0], _pressureSRVs[1], null, _velocityUAVs[1], _velocitySizeUAV, (SIZE + 63) / 64, SIZE / 4, SIZE / 4);",
        "            ",
        "            deviceContext.PixelShader.SetShaderResource(0, null);",
        "            // render output",
        "            RunShader(deviceContext, _csRender, _velocitySizeSRV, _pressureSRVs[1], null, _visuUAV, null, ((int)context.Viewport.Width + 15) / 16, ((int)context.Viewport.Height + 15) / 16, 1);",
        "",
        "            Utilities.Swap(ref _velocityVolumes[0], ref _velocityVolumes[1]);",
        "            Utilities.Swap(ref _velocitySRVs[0], ref _velocitySRVs[1]);",
        "            Utilities.Swap(ref _velocityUAVs[0], ref _velocityUAVs[1]);",
        "",
        "",
        "            //            _stopwatch.Stop();",
        "            //            Logger.Info(this,\"update took: {0}ms\", _stopwatch.ElapsedMilliseconds);",
        "            Changed = false;",
        "            context.Image = _visuTexture;",
        "            context.Volume = _velocitySizeVolume;",
        "",
        "            return context;",
        "        }",
        "",
        "",
        "        private Texture2D _visuTexture;",
        "        private UnorderedAccessView _visuUAV;",
        "        ",
        "        private Texture3D[] _velocityVolumes = { null, null, null, null };",
        "        private ShaderResourceView[] _velocitySRVs = { null, null, null, null };",
        "        private UnorderedAccessView[] _velocityUAVs = { null, null, null, null };",
        "        private Texture3D[] _pressureVolumes = { null, null };",
        "        private ShaderResourceView[] _pressureSRVs = { null, null };",
        "        private UnorderedAccessView[] _pressureUAVs = { null, null };",
        "        private Texture3D _divergenceVolume;",
        "        private ShaderResourceView _divergenceSRV;",
        "        private UnorderedAccessView _divergenceUAV;",
        "        private Texture3D _velocitySizeVolume;",
        "        private ShaderResourceView _velocitySizeSRV;",
        "        private UnorderedAccessView _velocitySizeUAV;",
        "",
        "",
        "        private SamplerState _linearSamplerState;",
        "        private Buffer _constBuffer;",
        "",
        "        private ComputeShader _csAdvection;",
        "        private ComputeShader _csAdvectionBackwards;",
        "        private ComputeShader _csAdvectionMacCormack;",
        "        private ComputeShader _csDrawSphere;",
        "        private ComputeShader _csDivergence;",
        "        private ComputeShader _csJacobi;",
        "        private ComputeShader _csProjection;",
        "        private ComputeShader _csRender;",
        "        private ComputeShader _csVisu;",
        "    }",
        "}",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "b521434f-93d6-4f88-921f-efaf1ac4c0b5",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "532e5049-5fbb-47ea-bb20-eaead4456b97"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "bcfc0860-e85c-43d0-8ad5-322bbd5eefea",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b521434f-93d6-4f88-921f-efaf1ac4c0b5"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "f147537b-f949-4a65-b2b7-08e49522e717",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "b521434f-93d6-4f88-921f-efaf1ac4c0b5"
    }
  ]
}