{
  "Name": "BakeMeshes",
  "_id": "5e68016f-c1db-42e9-a70e-d532a81e8e64",
  "Namespace": "lib.3d.modify",
  "Description": "Combines the geometry of its sub-graph into a new geometry. Material and other state flags are discarded. \r\nWarning: Animations below [BakeGeometry] are not evaluated.",
  "Inputs": [
    {
      "Name": "Code",
      "MetaInstanceID": "ab0e63a5-8d3d-4d11-b02d-5ebf7a2a6b96",
      "DefaultValue": {
        "Type": "Text",
        "Value": [
          "float4x4 objectToWorldMatrix;\r",
          "\r",
          "//>>> _parameters\r",
          "float Value;",
          "//<<< _parameters\r",
          "\r",
          "struct Vertex\r",
          "{\r",
          "    float4 pos : POSITION;\r",
          "    float3 normal : NORMAL;\r",
          "    float4 col : COLOR;\r",
          "    float2 texCoord : TEXCOORD0;\r",
          "    float3 tangent : TANGENT0;\r",
          "    float3 binormal : BINORMAL0;\r",
          "};\r",
          "\r",
          "\r",
          "Vertex VertexMain(Vertex input)\r",
          "{\r",
          "    return input;\r",
          "}\r",
          "\r",
          "\r",
          "[maxvertexcount(3)]\r",
          "void GeometryMain(triangle Vertex input[3], inout TriangleStream<Vertex> outputStream)\r",
          "{\r",
          "    for (int i = 0; i < 3; i++)\r",
          "\t{\r",
          "        Vertex vertex = input[i];\r",
          "        vertex.pos.xyz = mul(vertex.pos, objectToWorldMatrix).xyz + input[i].normal*Value;\r",
          "        vertex.normal.xyz = mul(vertex.normal, objectToWorldMatrix).xyz;\r",
          "        outputStream.Append(vertex);\r",
          "    }\r",
          "    outputStream.RestartStrip();\r",
          "};\r",
          "\r",
          "\r",
          "GeometryShader pGSComp = CompileShader(gs_5_0, GeometryMain());\r",
          "GeometryShader pGSwSO = ConstructGSWithSO(pGSComp, \"POSITION; NORMAL.xyz; COLOR; TEXCOORD0.xy; TANGENT0.xyz; BINORMAL0.xyz\", NULL, NULL, NULL, 0);\r",
          "\r",
          "\r",
          "technique11 Render\r",
          "{\r",
          "    pass \r",
          "    {\r",
          "        SetVertexShader(CompileShader(vs_5_0, VertexMain()));\r",
          "        SetGeometryShader(pGSwSO);\r",
          "        SetPixelShader(NULL);\r",
          "    }\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": "Scene",
      "MetaInstanceID": "2f681168-732f-4fb7-8b4e-7916a51bc705",
      "DefaultValue": {
        "Type": "Scene",
        "Value": "Framefield.Core.Scene"
      },
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248",
      "IsMultiInput": "False",
      "Relevance": "Required",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Value",
      "MetaInstanceID": "1746c981-90d0-4c97-873a-e9b544a3e027",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Scene",
      "MetaInstanceID": "7f82a3bb-88c9-4680-9fc6-5ca4c84d90d4",
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "fb03b42e-6907-4d88-b488-1c50a9ebef8b",
      "MetaID": "6a6b89c5-0e1b-44fa-9fe8-23ca15cb94dc",
      "Name": "BakeMeshesFunc",
      "Version": "627a8b26-3904-4921-9acc-31c5b1e8746f",
      "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 SharpDX.Direct3D;",
        "using Framefield.Core.OperatorPartTraits;",
        "using Framefield.Core.Rendering;",
        "using Buffer = SharpDX.Direct3D11.Buffer;",
        "",
        "namespace Framefield.Core.ID6a6b89c5_0e1b_44fa_9fe8_23ca15cb94dc",
        "{",
        "    public class Class_BakeMeshes : FXSourceCodeFunction, IFXSceneSourceCode, IMeshSupplier",
        "    {",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            Code = 0,",
        "            Scene = 1,",
        "            Value = 2",
        "        }",
        "        //<<< _inputids",
        "",
        "        public Class_BakeMeshes()",
        "        {",
        "            _meshCollector = new MeshCollector(this);",
        "        }",
        "",
        "        public override void Dispose() ",
        "        {",
        "            Utilities.DisposeObj(ref _bakedMesh);",
        "            base.Dispose();",
        "        }",
        "",
        "        public void AddMeshesTo(ICollection<Mesh> meshes)",
        "        {",
        "            UpdateMesh(new OperatorPartContext(), OperatorPart.Connections);",
        "            if (_bakedMesh != null)",
        "                meshes.Add(_bakedMesh);",
        "        }",
        "",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)",
        "        {",
        "            try",
        "            {",
        "                UpdateMesh(context, inputs);",
        "",
        "                if (_bakedMesh.Vertices != null)",
        "                {",
        "                    // render stream output to screen or whatever target is set",
        "                    context.Renderer.SetupEffect(context);",
        "                    context.Renderer.Render(_bakedMesh, context);",
        "                }",
        "            }",
        "            catch (Exception exception)",
        "            {",
        "                Logger.Error(this, \"Load Effect error: {0}\", exception.Message);",
        "            }",
        "",
        "            return context;",
        "        }",
        "",
        "        bool _firstEval = true;",
        "        private void UpdateMesh(OperatorPartContext context, List<OperatorPart> inputs)",
        "        {",
        "            if (_firstEval) ",
        "            {",
        "                for (int i = 0; i < NumCodes(); ++i)",
        "                    Compile(i);",
        "                _firstEval = false;",
        "                Changed = true;",
        "            }",
        "",
        "",
        "            //if (!Changed && _bakedMesh.Vertices != null)",
        "            //    return;",
        "",
        "            //>>> _params",
        "            var Code = inputs[(int)InputId.Code].Eval(context).Text;",
        "            var Scene = inputs[(int)InputId.Scene];",
        "            var Value = inputs[(int)InputId.Value].Eval(context).Value;",
        "            //<<< _params",
        "",
        "            if (Scene.Func.Changed || _bakedMesh.Vertices == null)",
        "            {",
        "                //Logger.Info(this, \"collect meshes\");",
        "                _meshCollector.Collect(Scene);",
        "                Scene.Func.Changed = false;",
        "            }",
        "",
        "            var inputMesh = _meshCollector.FirstMeshOrDefault;",
        "            if (inputMesh == null)",
        "            {",
        "                Utilities.DisposeObj(ref _bakedMesh.Vertices);",
        "                return;",
        "            }",
        "",
        "            _bakedMesh.NumTriangles = (from meshesWithtransform in _meshCollector.CollectedMeshes",
        "                                  from mesh in meshesWithtransform.Value",
        "                                  select mesh.NumTriangles).Sum();",
        "",
        "            _bakedMesh.AttributesSize = inputMesh.AttributesSize;",
        "            _bakedMesh.InputElements = inputMesh.InputElements;",
        "            if (_bakedMesh.Vertices == null || _bakedMesh.Vertices.Description.SizeInBytes != inputMesh.Vertices.Description.SizeInBytes)",
        "            {",
        "                Utilities.DisposeObj(ref _bakedMesh.Vertices);",
        "                _bakedMesh.Vertices = new Buffer(D3DDevice.Device, new BufferDescription()",
        "                                                                  {",
        "                                                                      BindFlags = BindFlags.StreamOutput | BindFlags.VertexBuffer,",
        "                                                                      CpuAccessFlags = CpuAccessFlags.None,",
        "                                                                      OptionFlags = ResourceOptionFlags.None,",
        "                                                                      SizeInBytes = _bakedMesh.NumTriangles*_bakedMesh.AttributesSize*3,",
        "                                                                      Usage = ResourceUsage.Default",
        "                                                                  });",
        "            }",
        "",
        "            _effect.GetVariableByName(\"Value\").AsScalar().Set(Value);",
        "             var matrixEffectVariable = _effect.GetVariableByName(\"objectToWorldMatrix\").AsMatrix();",
        "",
        "            context.D3DDevice.ImmediateContext.OutputMerger.DepthStencilState = new DepthStencilState(context.D3DDevice,",
        "                                                                                                        new DepthStencilStateDescription()",
        "                                                                                                            {",
        "                                                                                                                IsDepthEnabled = false,",
        "                                                                                                                IsStencilEnabled = false",
        "                                                                                                            });",
        "            context.D3DDevice.ImmediateContext.InputAssembler.InputLayout = context.InputLayout;",
        "            context.D3DDevice.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;",
        "",
        "            int streamOutputOffset = 0;",
        "",
        "            foreach (var meshesWithTransform in _meshCollector.CollectedMeshes)",
        "            {",
        "                if (matrixEffectVariable != null && matrixEffectVariable.IsValid)",
        "                {",
        "                    matrixEffectVariable.SetMatrix(meshesWithTransform.Key);",
        "                }",
        "",
        "                foreach (var mesh in meshesWithTransform.Value)",
        "                {",
        "                    context.D3DDevice.ImmediateContext.StreamOutput.SetTargets(new [] { new StreamOutputBufferBinding(_bakedMesh.Vertices, streamOutputOffset) });",
        "                    context.D3DDevice.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(mesh.Vertices, inputMesh.AttributesSize, 0));",
        "                    var technique = _effect.GetTechniqueByIndex(0);",
        "                    technique.GetPassByIndex(0).Apply(context.D3DDevice.ImmediateContext);",
        "                    context.D3DDevice.ImmediateContext.Draw(mesh.NumTriangles*3, 0);",
        "                    streamOutputOffset += mesh.AttributesSize*mesh.NumTriangles*3;",
        "                }",
        "            }",
        "",
        "            context.D3DDevice.ImmediateContext.StreamOutput.SetTargets(new [] { new StreamOutputBufferBinding(null, 0) });",
        "",
        "            Changed = false;",
        "        }",
        "",
        "        private Mesh _bakedMesh = new Mesh();",
        "        private MeshCollector _meshCollector;",
        "    }",
        "}",
        "",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "fb03b42e-6907-4d88-b488-1c50a9ebef8b",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "7f82a3bb-88c9-4680-9fc6-5ca4c84d90d4"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "ab0e63a5-8d3d-4d11-b02d-5ebf7a2a6b96",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "fb03b42e-6907-4d88-b488-1c50a9ebef8b"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "2f681168-732f-4fb7-8b4e-7916a51bc705",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "fb03b42e-6907-4d88-b488-1c50a9ebef8b"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "1746c981-90d0-4c97-873a-e9b544a3e027",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "fb03b42e-6907-4d88-b488-1c50a9ebef8b"
    }
  ]
}