{
  "Name": "FramerateGraph",
  "_id": "7de0cae2-e00a-451e-8603-870152daa5aa",
  "Namespace": "lib.3d.helper",
  "Description": "Defines a rect in the x-y plane with specific extends and color..\r\n",
  "Inputs": [
    {
      "Name": "Time.Start",
      "MetaInstanceID": "5c05cf86-a618-4da3-8acb-0cbd77d2cfe2",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Time.End",
      "MetaInstanceID": "75205250-b515-4ee8-859d-e2a8005fc29a",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Resolution",
      "MetaInstanceID": "e8910dd1-610a-415b-aa91-0ea5c8e18576",
      "DefaultValue": {
        "Type": "Float",
        "Value": "100"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "10",
      "Max": "1000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Out",
      "MetaInstanceID": "2c4467b1-0fbd-4365-b0d2-77de9e4a0f8a",
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "947fec76-f101-4f3c-9c2d-b0e87747a539",
      "MetaID": "e48d4719-589a-4a22-821e-6c01ca29ef75",
      "Name": "FramerateGraphFunc",
      "Version": "29f33576-92d1-4c97-ab30-d00e3d2d3ab5",
      "Type": "Scene",
      "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 Buffer = SharpDX.Direct3D11.Buffer;",
        "using Framefield.Core.Profiling;",
        "",
        "namespace Framefield.Core.IDe48d4719_589a_4a22_821e_6c01ca29ef75",
        "{",
        "    public class Class_FramerateGraph : OperatorPart.Function,",
        "                                        Framefield.Core.OperatorPartTraits.ITimeAccessor",
        "    {",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            TimeStart = 0,",
        "            TimeEnd = 1,",
        "            Resolution = 2",
        "        }",
        "        //<<< _inputids",
        "",
        "        public override void Dispose()",
        "        {",
        "            PlaneMesh.Dispose();",
        "        }",
        "",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)",
        "        {",
        "            //>>> _params",
        "            var TimeStart = inputs[(int)InputId.TimeStart].Eval(context).Value;",
        "            var TimeEnd = inputs[(int)InputId.TimeEnd].Eval(context).Value;",
        "            var Time = new Vector2(TimeStart, TimeEnd);",
        "            var Resolution = inputs[(int)InputId.Resolution].Eval(context).Value;",
        "            //<<< _params",
        "",
        "            try",
        "            {",
        "                var logData = TimeLogger.LogData;",
        "                if (!logData.Any())",
        "                    return context;",
        "                ",
        "                if (_lastUpdateTime != logData.Last().Value.StartTime)",
        "                    Changed = true;",
        "",
        "                if (Changed) {",
        "                    //if (logData.Count == 0)",
        "                    //    continue;",
        "",
        "                    var normal = new Vector3(0.0f, 0.0f, -1.0f);",
        "                    var color = new Vector4(0.4f, 0.9f, 0.6f, 0.6f);",
        "                    var tangent = new Vector3(1.0f, 0.0f, 0.0f);",
        "                    var binormal = new Vector3(0.0f, -1.0f, 0.0f);",
        "",
        "                    var inputElements = new InputElement[]",
        "                                            {",
        "                                                new InputElement(\"POSITION\", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 0, 0),",
        "                                                new InputElement(\"NORMAL\", 0, SharpDX.DXGI.Format.R32G32B32_Float, 16, 0),",
        "                                                new InputElement(\"COLOR\", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 28, 0),",
        "                                                new InputElement(\"TEXCOORD\", 0, SharpDX.DXGI.Format.R32G32_Float, 44, 0),",
        "                                                new InputElement(\"TANGENT\", 0, SharpDX.DXGI.Format.R32G32B32_Float, 52, 0),",
        "                                                new InputElement(\"BINORMAL\", 0, SharpDX.DXGI.Format.R32G32B32_Float, 64, 0)",
        "                                            };",
        "",
        "                    // Collect sample points for timeframe                    ",
        "                    var pointList = new List<float[]>();",
        "",
        "                    double now = logData.Last().Value.StartTime;",
        "                    _lastUpdateTime = logData.First().Value.StartTime;",
        "",
        "                    double lastTime = now;",
        "",
        "                    float sumx = 0;",
        "                    float sumy = 0;",
        "                    int countClusterPoint = 0;",
        "                    float resolutionStep = 1/Resolution;",
        "                    float nextStepThreshold = resolutionStep;",
        "",
        "                    foreach (var sample in logData)",
        "                    {",
        "                        if (sample.Value.StartTime > now - TimeEnd)",
        "                            break;",
        "                        if (sample.Value.StartTime < now - TimeStart)",
        "                            continue;",
        "",
        "                        var t = sample.Value.StartTime;",
        "                        if (t == lastTime)",
        "                            continue;",
        "",
        "                        float x = (float) ((t - (now - TimeStart))/(TimeStart - TimeEnd));",
        "                        float y = (float) (1.0f/(t - lastTime));",
        "                        lastTime = t;",
        "",
        "                        sumx += x;",
        "                        sumy += y;",
        "                        ++countClusterPoint;",
        "",
        "                        if (x > nextStepThreshold)",
        "                        {",
        "                            pointList.Add(new float[] {sumx/countClusterPoint, sumy/countClusterPoint});",
        "                            nextStepThreshold = ((float) Math.Floor(x/resolutionStep) + 1)*resolutionStep;",
        "                            sumx = 0;",
        "                            sumy = 0;",
        "                            countClusterPoint = 0;",
        "                        }",
        "                    }",
        "                    if (countClusterPoint > 0) {",
        "                        pointList.Add(new float[] {sumx/countClusterPoint, sumy/countClusterPoint});",
        "                    }",
        "",
        "",
        "                    // Generate mesh",
        "                    var attributesSize = 76;",
        "                    int numTriangles = (pointList.Count - 2)*2;",
        "                    int streamSize = Math.Max(numTriangles * 3 * attributesSize, 0);",
        "                    using (var vertexStream = new DataStream(streamSize, true, true))",
        "                    {",
        "                        float bottom = 0;",
        "                        for (int i = 0; i < pointList.Count - 2; ++i)",
        "                        {",
        "                            float left = pointList[i][0];",
        "                            float topLeft = pointList[i][1];",
        "                            float topRight = pointList[i][1];",
        "                            float right = pointList[i + 1][0];",
        "",
        "                            // tri 1 vert 1",
        "                            vertexStream.Write(new Vector4(right, topRight, 0, 1));",
        "                            vertexStream.Write(normal);",
        "                            vertexStream.Write(color);",
        "                            vertexStream.Write(new Vector2(0, 1.0f));",
        "                            vertexStream.Write(tangent);",
        "                            vertexStream.Write(binormal);",
        "",
        "                            // tri 1 vert 2",
        "                            vertexStream.Write(new Vector4(right, bottom, 0, 1));",
        "                            vertexStream.Write(normal);",
        "                            vertexStream.Write(color);",
        "                            vertexStream.Write(new Vector2(0, 1.0f));",
        "                            vertexStream.Write(tangent);",
        "                            vertexStream.Write(binormal);",
        "",
        "                            // tri 1 vert 3",
        "                            vertexStream.Write(new Vector4(left, bottom, 0, 1));",
        "                            vertexStream.Write(normal);",
        "                            vertexStream.Write(color);",
        "                            vertexStream.Write(new Vector2(0, 1.0f));",
        "                            vertexStream.Write(tangent);",
        "                            vertexStream.Write(binormal);",
        "",
        "                            // tri 2 vert 1",
        "                            vertexStream.Write(new Vector4(left, bottom, 0, 1));",
        "                            vertexStream.Write(normal);",
        "                            vertexStream.Write(color);",
        "                            vertexStream.Write(new Vector2(0, 1.0f));",
        "                            vertexStream.Write(tangent);",
        "                            vertexStream.Write(binormal);",
        "",
        "                            // tri 2 vert 2",
        "                            vertexStream.Write(new Vector4(left, topLeft, 0, 1));",
        "                            vertexStream.Write(normal);",
        "                            vertexStream.Write(color);",
        "                            vertexStream.Write(new Vector2(0, 1.0f));",
        "                            vertexStream.Write(tangent);",
        "                            vertexStream.Write(binormal);",
        "",
        "                            // tri 2 vert 3",
        "                            vertexStream.Write(new Vector4(right, topRight, 0, 1));",
        "                            vertexStream.Write(normal);",
        "                            vertexStream.Write(color);",
        "                            vertexStream.Write(new Vector2(0, 1.0f));",
        "                            vertexStream.Write(tangent);",
        "                            vertexStream.Write(binormal);",
        "                        }",
        "",
        "                        vertexStream.Position = 0;",
        "",
        "                        var vertices = new Buffer(context.D3DDevice,",
        "                                                  vertexStream,",
        "                                                  new BufferDescription()",
        "                                                      {",
        "                                                          BindFlags = BindFlags.VertexBuffer,",
        "                                                          CpuAccessFlags = CpuAccessFlags.None,",
        "                                                          OptionFlags = ResourceOptionFlags.None,",
        "                                                          SizeInBytes = streamSize,",
        "                                                          Usage = ResourceUsage.Default",
        "                                                      });",
        "",
        "                        PlaneMesh.Dispose();",
        "                        PlaneMesh = new Mesh() {InputElements = inputElements, Vertices = vertices, NumTriangles = numTriangles, AttributesSize = attributesSize};",
        "                    }",
        "                    Changed = false;",
        "                }",
        "                context.Renderer.SetupEffect(context);",
        "                context.Renderer.Render(PlaneMesh, context);",
        "",
        "            }",
        "            catch (Exception)",
        "            {",
        "                //Logger.Error(this,\"error\");",
        "            }",
        "",
        "            return context;",
        "        }",
        "",
        "        private Mesh PlaneMesh = new Mesh();",
        "        private double _lastUpdateTime = -1;",
        "    }",
        "}",
        "",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "947fec76-f101-4f3c-9c2d-b0e87747a539",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "2c4467b1-0fbd-4365-b0d2-77de9e4a0f8a"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "5c05cf86-a618-4da3-8acb-0cbd77d2cfe2",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "947fec76-f101-4f3c-9c2d-b0e87747a539"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "75205250-b515-4ee8-859d-e2a8005fc29a",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "947fec76-f101-4f3c-9c2d-b0e87747a539"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "e8910dd1-610a-415b-aa91-0ea5c8e18576",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "947fec76-f101-4f3c-9c2d-b0e87747a539"
    }
  ]
}