*
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
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 () {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d5e4ca31ceee884b9c22bfa4be99341
|
||||
timeCreated: 1430231056
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,108 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
|
||||
[Serializable]
|
||||
public class Plot2DChannel{
|
||||
public bool sample = true;
|
||||
public bool draw = true;
|
||||
public Color color = Color.green;
|
||||
public float cellTime = 0.2f;
|
||||
public float cellValue = 0.2f;
|
||||
public OscilloscopeSampler sampler;
|
||||
|
||||
public bool oscilloscopeMode;
|
||||
|
||||
|
||||
private float[] sampleValueBuffer;
|
||||
|
||||
public float[] SampleValueBuffer {
|
||||
get {
|
||||
return sampleValueBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private float[] sampleTimeBuffer;
|
||||
|
||||
public float[] SampleTimeBuffer {
|
||||
get {
|
||||
return sampleTimeBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private int sampleBufferPosition;
|
||||
|
||||
public int SampleBufferPosition {
|
||||
get {
|
||||
return sampleBufferPosition;
|
||||
}
|
||||
set
|
||||
{
|
||||
sampleBufferPosition = value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void ResizeBuffers(int samplesCount)
|
||||
{
|
||||
sampleTimeBuffer = new float[samplesCount];
|
||||
sampleValueBuffer = new float[samplesCount];
|
||||
}
|
||||
|
||||
public void SetSample(int id, float x, float y)
|
||||
{
|
||||
sampleTimeBuffer[id] = x;
|
||||
sampleValueBuffer[id] = y;
|
||||
}
|
||||
|
||||
public void Reset(int cellCount, int sampleRate){
|
||||
float totalTime = cellCount * cellTime;
|
||||
int maxSampleCount = Mathf.CeilToInt (totalTime * sampleRate);
|
||||
sampleTimeBuffer = new float[maxSampleCount];
|
||||
sampleValueBuffer = new float[maxSampleCount];
|
||||
}
|
||||
|
||||
public void Sample(){
|
||||
float val = sampler == null ? 0 : sampler();
|
||||
PushSample(Time.time, val);
|
||||
}
|
||||
|
||||
public void PushSample(float x, float y) {
|
||||
sampleBufferPosition = (sampleBufferPosition + 1) % sampleValueBuffer.Length;
|
||||
sampleTimeBuffer[sampleBufferPosition] = x;
|
||||
sampleValueBuffer[sampleBufferPosition] = y;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate float OscilloscopeSampler();
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class Plot2D : MonoBehaviour {
|
||||
public Vector2 pos = new Vector2(10,10);
|
||||
public Vector2 size;
|
||||
|
||||
public Plot2DChannel[] channels;
|
||||
|
||||
|
||||
private Vector3[] screenCorners;
|
||||
private const float cellSize = 40.0f;
|
||||
private const int hCellCountHalf = 6;
|
||||
private const int vCellCountHalf = 4;
|
||||
public int sampleRate = 50;
|
||||
private float lastSampleTime;
|
||||
public bool showInEditor = true;
|
||||
|
||||
public int xMatrixOffset = 0;
|
||||
public int yMatrixOffset = 0;
|
||||
private GUIStyle richLabelStyle;
|
||||
|
||||
void Start () {
|
||||
size = new Vector2 (hCellCountHalf * 2 * cellSize, vCellCountHalf * 2 * cellSize);
|
||||
screenCorners = new []{
|
||||
new Vector3(pos.x, pos.y, 0.5f),
|
||||
new Vector3(pos.x + size.x, pos.y, 0.5f),
|
||||
new Vector3(pos.x + size.x, pos.y + size.y, 0.5f),
|
||||
new Vector3(pos.x, pos.y + size.y, 0.5f)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0775eb1e62811014083b1a43665b9711
|
||||
timeCreated: 1430231054
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user