{
  "Name": "MeshBlend",
  "_id": "470d67fc-bfee-4735-91c6-7cf56d5a7cf8",
  "Namespace": "lib.3d.modify",
  "Description": "Requires the to scenes to be of identical structure.",
  "Inputs": [
    {
      "Name": "Code",
      "MetaInstanceID": "74d1def1-5343-4eea-9e45-c35f08ea67dd",
      "DefaultValue": {
        "Type": "Text",
        "Value": [
          "float4x4 objectToWorldMatrix;\r",
          "\r",
          "//>>> _parameters\r",
          "float BlendFactor;",
          "//<<< _parameters\r",
          "\r",
          "struct InputVertex\r",
          "{\r",
          "    // mesh 1\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",
          "    // mesh 2\r",
          "    float4 pos2 : POSITION1;\r",
          "    float3 normal2 : NORMAL1;\r",
          "    float4 col2 : COLOR1;\r",
          "    float2 texCoord2 : TEXCOORD1;\r",
          "    float3 tangent2 : TANGENT1;\r",
          "    float3 binormal2 : BINORMAL1;\r",
          "};\r",
          "\r",
          "\r",
          "struct OutputVertex\r",
          "{\r",
          "    // mesh 1\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",
          "InputVertex VertexMain(InputVertex input)\r",
          "{\r",
          "    return input;\r",
          "}\r",
          "\r",
          "\r",
          "[maxvertexcount(3)]\r",
          "void GeometryMain(triangle InputVertex input[3], inout TriangleStream<OutputVertex> outputStream)\r",
          "{\r",
          "    for (int i = 0; i < 3; i++)\r",
          "\t{\r",
          "        OutputVertex vertex = (OutputVertex)0;\r",
          "        vertex.pos = lerp(input[i].pos, input[i].pos2, BlendFactor);\r",
          "        vertex.normal = normalize(lerp(input[i].normal, input[i].normal2, BlendFactor));\r",
          "        vertex.col = lerp(input[i].col, input[i].col2, BlendFactor);\r",
          "        vertex.texCoord = lerp(input[i].texCoord, input[i].texCoord2, BlendFactor);\r",
          "        vertex.tangent = input[i].tangent;\r",
          "        vertex.binormal = input[i].binormal;\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": "3130f2fc-5b8a-4f5c-9f59-99fdda8343ec",
      "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": "BlendFactor",
      "MetaInstanceID": "69f157f1-9fd7-4db5-b74a-cea4b85e6d45",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "1",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Scene",
      "MetaInstanceID": "79c87a0e-23c5-44e5-8966-26160fcab912",
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "daf81bfd-1f27-4201-8eec-80e2fb4ef836",
      "MetaID": "1fa321b6-4ad2-4ba1-8670-3ec63588e42f",
      "Name": "MeshBlendFunc",
      "Version": "67002a3c-7d1a-4b68-b377-15e6c6708de9",
      "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 SharpDX.DXGI;",
        "using Framefield.Core.OperatorPartTraits;",
        "using Framefield.Core.Rendering;",
        "using Buffer = SharpDX.Direct3D11.Buffer;",
        "",
        "namespace Framefield.Core.ID1fa321b6_4ad2_4ba1_8670_3ec63588e42f",
        "{",
        "    public class Class_MeshBlend : FXSourceCodeFunction, IFXSceneSourceCode, IMeshSupplier",
        "    {",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            Code = 0,",
        "            Scene = 1,",
        "            BlendFactor = 2",
        "        }",
        "        //<<< _inputids",
        "",
        "        public Class_MeshBlend()",
        "        {",
        "            _meshCollector = new MeshCollector(this);",
        "        }",
        "",
        "        public override void Dispose() ",
        "        {",
        "            Utilities.DisposeObj(ref _blendedMesh);",
        "            base.Dispose();",
        "        }",
        "",
        "        public void AddMeshesTo(ICollection<Mesh> meshes)",
        "        {",
        "            UpdateMesh(new OperatorPartContext(), OperatorPart.Connections);",
        "            if (_blendedMesh != null)",
        "                meshes.Add(_blendedMesh);",
        "        }",
        "",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)",
        "        {",
        "            try",
        "            {",
        "                Logger.Debug(this, \"bla\");",
        "                UpdateMesh(context, inputs);",
        "",
        "                if (_blendedMesh.Vertices != null)",
        "                {",
        "                    // render stream output to screen or whatever target is set",
        "                    context.Renderer.SetupEffect(context);",
        "                    context.Renderer.Render(_blendedMesh, 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 && _blendedMesh.Vertices != null)",
        "                return;",
        "",
        "            //>>> _params",
        "            var Code = inputs[(int)InputId.Code].Eval(context).Text;",
        "            var Scene = inputs[(int)InputId.Scene];",
        "            var BlendFactor = inputs[(int)InputId.BlendFactor].Eval(context).Value;",
        "            //<<< _params",
        "",
        "            if (Scene.Func.Changed || _blendedMesh.Vertices == null)",
        "            {",
        "                //Logger.Info(this, \"collect meshes\");",
        "                _meshCollector.Collect(Scene);",
        "                Scene.Func.Changed = false;",
        "            }",
        "",
        "            if (_meshCollector.CollectedMeshes.Count != 1)",
        "            {",
        "                Logger.Error(this, \"Found not exactly one martix mesh entry\");",
        "                return;",
        "            }",
        "",
        "            var firstEntry = _meshCollector.CollectedMeshes.First();",
        "            if (firstEntry.Value.Count != 2)",
        "            {",
        "                Logger.Error(this, \"Found not exactly 2 meshes.\");",
        "                return;",
        "            }",
        "            ",
        "            Logger.Debug(this, \"bla01\");",
        "            var meshes = new Mesh[2];",
        "            firstEntry.Value.CopyTo(meshes, 0);",
        "",
        "            var firstMesh = meshes[0];",
        "            var secondMesh = meshes[1];",
        "",
        "            _blendedMesh.NumTriangles = firstMesh.NumTriangles;",
        "            _blendedMesh.AttributesSize = firstMesh.AttributesSize;",
        "            _blendedMesh.InputElements = firstMesh.InputElements;",
        "            if (_blendedMesh.Vertices == null || _blendedMesh.Vertices.Description.SizeInBytes != firstMesh.Vertices.Description.SizeInBytes)",
        "            {",
        "                Utilities.DisposeObj(ref _blendedMesh.Vertices);",
        "                _blendedMesh.Vertices = new Buffer(D3DDevice.Device, new BufferDescription()",
        "                                                                  {",
        "                                                                      BindFlags = BindFlags.StreamOutput | BindFlags.VertexBuffer,",
        "                                                                      CpuAccessFlags = CpuAccessFlags.None,",
        "                                                                      OptionFlags = ResourceOptionFlags.None,",
        "                                                                      SizeInBytes = _blendedMesh.NumTriangles*_blendedMesh.AttributesSize*3,",
        "                                                                      Usage = ResourceUsage.Default",
        "                                                                  });",
        "            }",
        "",
        "            _effect.GetVariableByName(\"BlendFactor\").AsScalar().Set(BlendFactor);",
        "             var matrixEffectVariable = _effect.GetVariableByName(\"objectToWorldMatrix\").AsMatrix();",
        "",
        "            context.D3DDevice.ImmediateContext.OutputMerger.DepthStencilState = new DepthStencilState(context.D3DDevice,",
        "                                                                                                        new DepthStencilStateDescription()",
        "                                                                                                            {",
        "                                                                                                                IsDepthEnabled = false,",
        "                                                                                                                IsStencilEnabled = false",
        "                                                                                                            });",
        "",
        "            var technique = _effect.GetTechniqueByIndex(0);",
        "            var pass = technique.GetPassByIndex(0);",
        "            var inputElements = new[]",
        "                                    {",
        "                                        new InputElement(\"POSITION\", 0, Format.R32G32B32A32_Float, 0, 0),",
        "                                        new InputElement(\"NORMAL\", 0, Format.R32G32B32_Float, 16, 0),",
        "                                        new InputElement(\"COLOR\", 0, Format.R32G32B32A32_Float, 28, 0),",
        "                                        new InputElement(\"TEXCOORD\", 0, Format.R32G32_Float, 44, 0),",
        "                                        new InputElement(\"TANGENT\", 0, Format.R32G32B32_Float, 52, 0),",
        "                                        new InputElement(\"BINORMAL\", 0, Format.R32G32B32_Float, 64, 0),",
        "                                        new InputElement(\"POSITION\", 1, Format.R32G32B32A32_Float, 0, 1),",
        "                                        new InputElement(\"NORMAL\", 1, Format.R32G32B32_Float, 16, 1),",
        "                                        new InputElement(\"COLOR\", 1, Format.R32G32B32A32_Float, 28, 1),",
        "                                        new InputElement(\"TEXCOORD\", 1, Format.R32G32_Float, 44, 1),",
        "                                        new InputElement(\"TANGENT\", 1, Format.R32G32B32_Float, 52, 1),",
        "                                        new InputElement(\"BINORMAL\", 1, Format.R32G32B32_Float, 64, 1)",
        "                                    };",
        "            var _inputLayout = new InputLayout(D3DDevice.Device, pass.Description.Signature, inputElements);",
        "",
        "            context.D3DDevice.ImmediateContext.InputAssembler.InputLayout = _inputLayout;",
        "            context.D3DDevice.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;",
        "            context.D3DDevice.ImmediateContext.PixelShader.Set(null);",
        "            const int streamOutputOffset = 0;",
        "",
        "            context.D3DDevice.ImmediateContext.InputAssembler.SetVertexBuffers(0, new [] { firstMesh.Vertices, secondMesh.Vertices}, new [] {76, 76}, new [] {0,0} );",
        "            context.D3DDevice.ImmediateContext.StreamOutput.SetTargets(new [] { new StreamOutputBufferBinding(_blendedMesh.Vertices, streamOutputOffset) });",
        "                                                                                          ",
        "//                    var technique = _effect.GetTechniqueByIndex(0);",
        "            technique.GetPassByIndex(0).Apply(context.D3DDevice.ImmediateContext);",
        "            context.D3DDevice.ImmediateContext.Draw(firstMesh.NumTriangles*3, 0);",
        "",
        "            _inputLayout.Dispose();",
        "            context.D3DDevice.ImmediateContext.InputAssembler.SetVertexBuffers(0, new Buffer[] {null, null}, new[]{0,0}, new[]{0,0});",
        "            context.D3DDevice.ImmediateContext.StreamOutput.SetTargets(new [] { new StreamOutputBufferBinding(null, 0) });",
        "",
        "            Changed = false;",
        "        }",
        "",
        "        private Mesh _blendedMesh = new Mesh();",
        "        private MeshCollector _meshCollector;",
        "    }",
        "}",
        "",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "daf81bfd-1f27-4201-8eec-80e2fb4ef836",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "79c87a0e-23c5-44e5-8966-26160fcab912"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "74d1def1-5343-4eea-9e45-c35f08ea67dd",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "daf81bfd-1f27-4201-8eec-80e2fb4ef836"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "3130f2fc-5b8a-4f5c-9f59-99fdda8343ec",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "daf81bfd-1f27-4201-8eec-80e2fb4ef836"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "69f157f1-9fd7-4db5-b74a-cea4b85e6d45",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "daf81bfd-1f27-4201-8eec-80e2fb4ef836"
    }
  ]
}