217 lines
7.7 KiB
C#
217 lines
7.7 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
public class WMG_Bezier_Band : WMG_GUI_Functions {
|
|
|
|
public GameObject bandFillSpriteGO;
|
|
public GameObject bandLineSpriteGO;
|
|
public GameObject labelParent;
|
|
public GameObject percentLabel;
|
|
public GameObject label;
|
|
// public GameObject bandBotLineSpriteGO;
|
|
|
|
private Sprite bandFillSprite;
|
|
private Sprite bandLineSprite;
|
|
private Material bandFillMat;
|
|
private Material bandLineMat;
|
|
// private Sprite bandBotLineSprite;
|
|
private Color[] bandFillColors;
|
|
private Color[] bandLineColors;
|
|
// private Color[] bandBotLineColors;
|
|
private int texSize;
|
|
private WMG_Bezier_Band_Graph graph;
|
|
public float cumulativePercent;
|
|
public float prevCumulativePercent;
|
|
private int size;
|
|
private int maxS;
|
|
private int superSamplingRate = 3;
|
|
private int xPad = 2;
|
|
|
|
public void Init(WMG_Bezier_Band_Graph graph) {
|
|
this.graph = graph;
|
|
// theGraph.setTextureMaterial(areaShadingRects[i], matToUse);
|
|
bandFillSprite = WMG_Util.createSprite(getTexture(bandFillSpriteGO));
|
|
bandLineSprite = WMG_Util.createSprite(getTexture(bandLineSpriteGO));
|
|
// bandFillSprite = WMG_Util.createAlphaSprite(1024);
|
|
// bandLineSprite = WMG_Util.createAlphaSprite(1024);
|
|
// bandBotLineSprite = WMG_Util.createSprite(getTexture(bandBotLineSpriteGO));
|
|
texSize = bandFillSprite.texture.width;
|
|
// texSize = 1024;
|
|
bandFillColors = new Color[texSize * texSize];
|
|
bandLineColors = new Color[texSize * texSize];
|
|
// bandBotLineColors = new Color[texSize * texSize];
|
|
setTexture(bandFillSpriteGO, bandFillSprite);
|
|
setTexture(bandLineSpriteGO, bandLineSprite);
|
|
// setTexture(bandBotLineSpriteGO, bandBotLineSprite);
|
|
size = Mathf.RoundToInt(Mathf.Sqrt(bandFillColors.Length));
|
|
// size = 1024;
|
|
maxS = size - 1;
|
|
// setTextureMaterial(bandFillSpriteGO, graph.uiGradient);
|
|
// setTextureMaterial(bandLineSpriteGO, graph.uiGradient);
|
|
// bandFillMat = getTextureMaterial(bandFillSpriteGO);
|
|
// bandLineMat = getTextureMaterial(bandLineSpriteGO);
|
|
}
|
|
|
|
public void setCumulativePercents(float val, float prev) {
|
|
cumulativePercent = val / graph.TotalVal;
|
|
prevCumulativePercent = prev / graph.TotalVal;
|
|
}
|
|
|
|
public void setFillColor(Color color) {
|
|
changeSpriteColor(bandFillSpriteGO, color);
|
|
// bandFillMat.SetColor("_color", color);
|
|
}
|
|
|
|
public void setLineColor(Color color) {
|
|
changeSpriteColor(bandLineSpriteGO, color);
|
|
// bandLineMat.SetColor("_color", color);
|
|
}
|
|
|
|
public void UpdateBand() {
|
|
// byte[] bandFillColors = new byte[1024*1024];
|
|
// byte[] bandLineColors = new byte[1024*1024];
|
|
updateColors (ref bandFillColors, ref bandLineColors);
|
|
bandFillSprite.texture.SetPixels(bandFillColors);
|
|
// bandFillSprite.texture.LoadRawTextureData(bandFillColors);
|
|
bandFillSprite.texture.Apply();
|
|
bandLineSprite.texture.SetPixels(bandLineColors);
|
|
// bandLineSprite.texture.LoadRawTextureData(bandLineColors);
|
|
bandLineSprite.texture.Apply();
|
|
// bandBotLineSprite.texture.SetPixels(bandBotLineColors);
|
|
// bandBotLineSprite.texture.Apply();
|
|
// bandFillMat.SetTexture("_alphaGradient", bandFillSprite.texture);
|
|
// bandLineMat.SetTexture("_alphaGradient", bandLineSprite.texture);
|
|
// bandFillMat.SetTexture("_alphaGradient", testTex);
|
|
// bandLineMat.SetTexture("_alphaGradient", testTex);
|
|
}
|
|
|
|
// \mathbf{B}(t)=(1-t)^3\mathbf{P}_0+3(1-t)^2t\mathbf{P}_1+3(1-t)t^2\mathbf{P}_2+t^3\mathbf{P}_3 \mbox{ , } 0 \le t \le 1.
|
|
void updateColors(ref Color[] bandFillColors, ref Color[] bandLineColors) {
|
|
|
|
bandFillColors = new Color[texSize * texSize];
|
|
bandLineColors = new Color[texSize * texSize];
|
|
// bandBotLineColors = new Color[texSize * texSize];
|
|
int bandWidth = Mathf.Max(0,graph.bandLineWidth-1);
|
|
|
|
int[] fillStartPoints = new int[size];
|
|
|
|
for (int k = 0; k <= 1; k++) {
|
|
|
|
float offset = graph.startHeightPercent * maxS;
|
|
float valOffset = prevCumulativePercent;
|
|
if (k == 1) {
|
|
valOffset = cumulativePercent;
|
|
}
|
|
|
|
Vector2 start = new Vector2(0, maxS/2f + (0.5f - valOffset) * offset);
|
|
Vector2 end = new Vector2(maxS, (1 - valOffset) * maxS - (k == 1 ? -graph.bandSpacing : graph.bandSpacing));
|
|
if (k == 1 && cumulativePercent == 1 && graph.bandSpacing < graph.bandLineWidth) {
|
|
end = new Vector2(end.x, end.y + (graph.bandLineWidth - graph.bandSpacing));
|
|
}
|
|
Vector2 p1 = new Vector2(graph.cubicBezierP1.x * end.x, start.y + graph.cubicBezierP1.y * (end.y - start.y));
|
|
Vector2 p2 = new Vector2((1- graph.cubicBezierP2.x) * end.x, end.y - graph.cubicBezierP2.y * (end.y - start.y));
|
|
|
|
int[] startPoints = new int[size];
|
|
// float[] slopes = new float[size];
|
|
for (int i = 0; i < size*superSamplingRate; i++) {
|
|
Vector2 pos = cubicBezier(start, p1, p2, end, i / (size*superSamplingRate-1f));
|
|
int posX = Mathf.RoundToInt(pos.x);
|
|
int posY = Mathf.RoundToInt(pos.y);
|
|
startPoints[posX] = Mathf.Max(posY, startPoints[posX]);
|
|
// Vector2 slope = cubicBezierSlope(start, p1, p2, end, i / (size*superSamplingRate-1f));
|
|
// slopes[posX] = Mathf.Max(slopes[posX], slope.y / slope.x);
|
|
}
|
|
|
|
|
|
|
|
|
|
start = new Vector2(start.x, start.y - bandWidth);
|
|
end = new Vector2(end.x, end.y - bandWidth);
|
|
p1 = new Vector2(graph.cubicBezierP1.x * end.x, start.y + graph.cubicBezierP1.y * (end.y - start.y));
|
|
p2 = new Vector2((1- graph.cubicBezierP2.x) * end.x, end.y - graph.cubicBezierP2.y * (end.y - start.y));
|
|
|
|
int[] endPoints = new int[size];
|
|
for (int i = 0; i < size; i++) {
|
|
endPoints[i] = maxS;
|
|
}
|
|
for (int i = 0; i < size*superSamplingRate; i++) {
|
|
Vector2 pos = cubicBezier(start, p1, p2, end, i / (size*superSamplingRate-1f));
|
|
int posX = Mathf.RoundToInt(pos.x);
|
|
int posY = Mathf.RoundToInt(pos.y);
|
|
endPoints[posX] = Mathf.Min(posY, endPoints[posX]);
|
|
|
|
}
|
|
|
|
for (int i = xPad; i < (size-xPad); i++) {
|
|
int width = (startPoints[i] - endPoints[i]);
|
|
width++;
|
|
|
|
// get fill start points
|
|
if (k == 0) {
|
|
fillStartPoints[i] = endPoints[i]-1;
|
|
}
|
|
|
|
for (int j = 0; j < width; j++) {
|
|
int y = (startPoints[i] -j);
|
|
float alpha = 1f - (Mathf.Abs((j - width/2f)) / (width/2f));
|
|
// if (k == 0) {
|
|
bandLineColors[i + size * y] = new Color(1, 1, 1, alpha * alpha);
|
|
// bandLineColors[i + size * y] = (byte)Mathf.RoundToInt(alpha * alpha * 255);
|
|
// }
|
|
// else {
|
|
// bandBotLineColors[i + size * y] = new Color(1, 1, 1, alpha * alpha);
|
|
// }
|
|
}
|
|
|
|
// Fill
|
|
if (k == 1) {
|
|
int bandWidth2 = (fillStartPoints[i] - startPoints[i]);
|
|
|
|
for (int j = 0; j < bandWidth2; j++) {
|
|
int y = (fillStartPoints[i] -j);
|
|
bandFillColors[i + size * y] = Color.white;
|
|
// bandFillColors[i + size * y] = (byte)255;
|
|
}
|
|
|
|
// Alias top edge of band fill
|
|
int alphaFadeWidth = Mathf.Min(bandWidth/2, bandWidth2/2);
|
|
for (int j = 0; j < alphaFadeWidth; j++) {
|
|
float alpha = (j+1f) / alphaFadeWidth;
|
|
int y = (fillStartPoints[i] -j);
|
|
bandFillColors[i + size * y] = new Color(1, 1, 1, alpha);
|
|
// bandFillColors[i + size * y] = (byte)Mathf.RoundToInt(alpha*255);
|
|
}
|
|
|
|
for (int j = 0; j < alphaFadeWidth; j++) {
|
|
float alpha = (j+1f) / alphaFadeWidth;
|
|
int y = (startPoints[i] +j);
|
|
bandFillColors[i + size * y] = new Color(1, 1, 1, alpha);
|
|
// bandFillColors[i + size * y] = (byte)Mathf.RoundToInt(alpha*255);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// B(t) = (1-t)^3 P0 + 3((1-t)^2)t P1 + 3(1-t)t^2 P2 + t^3 P3 for 0 <= t <= 1
|
|
Vector2 cubicBezier (Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t) {
|
|
float r = 1f - t;
|
|
float f0 = r * r * r;
|
|
float f1 = r * r * t * 3;
|
|
float f2 = r * t * t * 3;
|
|
float f3 = t * t * t;
|
|
return f0*p0 + f1*p1 + f2*p2 + f3*p3;
|
|
}
|
|
|
|
// // B(t) = 3(1-t)^2 (P1-P0) + 6(1-t)t (P2-P1) + 3t^2 (P3-P2) for 0 <= t <= 1
|
|
// Vector2 cubicBezierSlope (Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t) {
|
|
// float r = 1f - t;
|
|
// float f0 = r * r * 3;
|
|
// float f1 = r * t * 6;
|
|
// float f2 = t * t * 3;
|
|
// return f0*(p1-p0) + f1*(p2-p1) + f2*(p3-p2);
|
|
// }
|
|
|
|
}
|