using UnityEngine; using System.Collections; public class OscilloscopeDisplay : MonoBehaviour { public Material displayMaterial; private Texture2D diplayBackground; public Plot2D plot; public int halfXCellCount = 6; public int halfYCellCount = 4; public int cellSize = 50; public int shortLineSize = 5; public Vector2 position; public Color backgroundColor = new Color(0,0,0,0.6f); public Color linesColor = new Color(0.27f,0.57f,0.9f, 1.0f); public Material lineMaterial; // Use this for initialization void Start () { } void GenerateBackground(Texture2D tex){ if (tex == null) { return; } Color[] pixels = new Color[tex.width * tex.height]; //fill background for (int i = 0; i < pixels.Length; ++i) { pixels[i] = backgroundColor; } //draw grid //-horizontal lines for (int i = 0; i <= halfYCellCount * 2; ++i) { int y = i * cellSize; for(int x = 0; x < tex.width; ++x){ if(y != 0 && y != tex.height - 1){ if((x % 2) == 1){ continue; } } int id = y * tex.width + x; pixels[id] = linesColor; } } //-vertical lines for (int i = 0; i <= halfXCellCount * 2; ++i) { int x = i * cellSize; for(int y = 0; y < tex.height; ++y){ if(x != 0 && x != tex.width - 1){ if((y % 2) == 1){ continue; } } int id = y * tex.width + x; pixels[id] = linesColor; } } //draw helper short lines //-vertical int[] cells = new int[]{0,halfXCellCount, halfXCellCount*2}; int[] offsets = new int[]{0, -shortLineSize / 2, -shortLineSize + 1 }; for (int i = 0; i < cells.Length; ++i) { int x = cells[i] * cellSize + offsets[i]; for(int y = 0; y < tex.height; y += (cellSize / 5)){ for(int j = x; j < (x + shortLineSize); ++j){ pixels[ y * tex.width + j] = linesColor; } } } //horizontal cells = new int[]{0, halfYCellCount, halfYCellCount*2}; for (int i = 0; i < cells.Length; ++i) { int y = cells[i] * cellSize + offsets[i]; for(int x = 0; x < tex.width; x += (cellSize / 5)){ for(int j = y; j < (y + shortLineSize); ++j){ pixels[ j * tex.width + x] = linesColor; } } } tex.SetPixels (pixels); tex.Apply (); } void OnValidate(){ int texWidth = cellSize * halfXCellCount * 2 + 1; int texHeight = cellSize * halfYCellCount * 2 + 1; if (diplayBackground == null || diplayBackground.width != texWidth || diplayBackground.height != texHeight) { diplayBackground = new Texture2D(texWidth, texHeight, TextureFormat.ARGB32, false, true); } GenerateBackground (diplayBackground); } void OnDrawGizmos(){ GL.PushMatrix (); //GL.LoadPixelMatrix (); GL.LoadPixelMatrix (0, Camera.current.pixelWidth, Camera.current.pixelHeight, 0); Graphics.DrawTexture (new Rect (position.x, position.y, diplayBackground.width, diplayBackground.height), diplayBackground); if (plot != null && plot.channels != null && plot.channels.Length > 0) { Vector2 size = new Vector2 (halfXCellCount * 2 * cellSize, halfYCellCount * 2 * cellSize); //func lineMaterial.SetPass(0); GL.Begin(GL.LINES); lineMaterial.SetPass(0); float verticalOffset = halfYCellCount * cellSize; foreach (var channel in plot.channels) { if(channel == null || !channel.draw){ continue; } GL.Color(channel.color); var timeBuffer = channel.SampleTimeBuffer; var valueBuffer = channel.SampleValueBuffer; var bufferPos = channel.SampleBufferPosition; if(timeBuffer == null || timeBuffer.Length == 0 || valueBuffer == null || valueBuffer.Length == 0){ continue; } float lastTime = timeBuffer[bufferPos]; float lastX = 0; float lastY = size.y - ((valueBuffer[bufferPos] / channel.cellValue) * cellSize + verticalOffset); bool oscMode = channel.oscilloscopeMode; if (oscMode) { lastX = size.x; } else { lastX = (timeBuffer[bufferPos] / channel.cellTime) * cellSize + size.x / 2; } for (int i = 1; i < timeBuffer.Length; ++i){ if(bufferPos == 0){ bufferPos = valueBuffer.Length - 1; }else{ bufferPos = bufferPos - 1; } float timeOffset = 0; float curX = 0; if (oscMode) { timeOffset = timeBuffer[bufferPos] - lastTime; curX = size.x + (timeOffset / channel.cellTime) * cellSize; } else { timeOffset = timeBuffer[bufferPos]; curX = (timeOffset / channel.cellTime) * cellSize + size.x / 2; } float curY = size.y - ((valueBuffer[bufferPos] / channel.cellValue) * cellSize + verticalOffset); Vector2 curVector = Vector3.zero; Vector2 lastVector = Vector3.zero; if(ClipLine(lastX, lastY, curX, curY, ref curVector, ref lastVector, size)){ GL.Vertex(new Vector3(curVector.x + position.x, curVector.y + position.y, 0)); GL.Vertex(new Vector3(lastVector.x + position.x, lastVector.y + position.y, 0)); } lastY = curY; lastX = curX; } } GL.End(); } GL.PopMatrix (); } bool ClipLine(float lastX, float lastY, float curX, float curY, ref Vector2 L, ref Vector2 R, Vector2 size){ if (lastX < 0) { return false; } L.x = curX; L.y = curY; R.x = lastX; R.y = lastY; if(R.x < 0){ float kx = (L.x / (L.x - R.x)); L.y = L.y + (R.y - L.y) * kx; L.x = 0; } if (L.y > R.y) { var tmp = R; R = L; L = tmp; } //L.y always smaller if (R.y <= 0) { return false; } if (L.y >= size.y) { return false; } if (L.y < 0) { //top clamp float kx = L.y / (L.y - R.y); L.x = L.x + (R.x - L.x) * kx; L.y = 0; } if (R.y > size.y){ //bottom clamp float kx = (R.y - size.y) / (R.y - L.y); R.x = R.x + (L.x - R.x) * kx; R.y = size.y; } if (R.y > size.y || L.y > size.y) { Debug.Log("Fail"); } return true; } // Update is called once per frame void Update () { } }