@ -2,287 +2,292 @@ using UnityEngine;
using System.Collections ;
using System ;
public class GLDraw
namespace Fungus
{
/ *
* Clipping code : http : //forum.unity3d.com/threads/17066-How-to-draw-a-GUI-2D-quot-line-quot?p=230386#post230386
* Thick line drawing code : http : //unifycommunity.com/wiki/index.php?title=VectorLine
* /
protected static bool clippingEnabled ;
protected static Rect clippingBounds ;
public static Material lineMaterial = null ;
/* @ Credit: "http://cs-people.bu.edu/jalon/cs480/Oct11Lab/clip.c" */
protected static bool clip_test ( float p , float q , ref float u1 , ref float u2 )
{
float r ;
bool retval = true ;
if ( p < 0.0 )
{
r = q / p ;
if ( r > u2 )
retval = false ;
else if ( r > u1 )
u1 = r ;
}
else if ( p > 0.0 )
{
r = q / p ;
if ( r < u1 )
retval = false ;
else if ( r < u2 )
u2 = r ;
}
else if ( q < 0.0 )
retval = false ;
return retval ;
}
public static bool segment_rect_intersection ( Rect bounds , ref Vector2 p1 , ref Vector2 p2 )
{
float u1 = 0.0f , u2 = 1.0f , dx = p2 . x - p1 . x , dy ;
if ( clip_test ( - dx , p1 . x - bounds . xMin , ref u1 , ref u2 ) )
{
if ( clip_test ( dx , bounds . xMax - p1 . x , ref u1 , ref u2 ) )
{
dy = p2 . y - p1 . y ;
if ( clip_test ( - dy , p1 . y - bounds . yMin , ref u1 , ref u2 ) )
{
if ( clip_test ( dy , bounds . yMax - p1 . y , ref u1 , ref u2 ) )
{
if ( u2 < 1.0 )
{
p2 . x = p1 . x + u2 * dx ;
p2 . y = p1 . y + u2 * dy ;
}
if ( u1 > 0.0 )
{
p1 . x + = u1 * dx ;
p1 . y + = u1 * dy ;
}
return true ;
}
}
}
}
return false ;
}
public static void BeginGroup ( Rect position )
{
clippingEnabled = true ;
clippingBounds = new Rect ( 0 , 0 , position . width , position . height ) ;
GUI . BeginGroup ( position ) ;
}
public static void EndGroup ( )
{
GUI . EndGroup ( ) ;
clippingBounds = new Rect ( 0 , 0 , Screen . width , Screen . height ) ;
clippingEnabled = false ;
}
public static Vector2 BeginScrollView ( Rect position , Vector2 scrollPos , Rect viewRect , Rect clipRect )
{
clippingEnabled = true ;
clippingBounds = clipRect ;
return GUI . BeginScrollView ( position , scrollPos , viewRect , GUIStyle . none , GUIStyle . none ) ;
}
public static void EndScrollView ( )
{
GUI . EndScrollView ( ) ;
clippingBounds = new Rect ( 0 , 0 , Screen . width , Screen . height ) ;
clippingEnabled = false ;
}
public static void CreateMaterial ( )
{
if ( lineMaterial ! = null )
return ;
lineMaterial = Resources . Load ( "GLLineDraw" , typeof ( Material ) ) as Material ;
}
public static void DrawLine ( Vector2 start , Vector2 end , Color color , float width )
{
if ( Event . current = = null )
return ;
if ( Event . current . type ! = EventType . repaint )
return ;
if ( clippingEnabled )
if ( ! segment_rect_intersection ( clippingBounds , ref start , ref end ) )
return ;
CreateMaterial ( ) ;
lineMaterial . SetPass ( 0 ) ;
Vector3 startPt ;
Vector3 endPt ;
if ( width = = 1 )
{
GL . Begin ( GL . LINES ) ;
GL . Color ( color ) ;
startPt = new Vector3 ( start . x , start . y , 0 ) ;
endPt = new Vector3 ( end . x , end . y , 0 ) ;
GL . Vertex ( startPt ) ;
GL . Vertex ( endPt ) ;
}
else
{
GL . Begin ( GL . QUADS ) ;
GL . Color ( color ) ;
startPt = new Vector3 ( end . y , start . x , 0 ) ;
endPt = new Vector3 ( start . y , end . x , 0 ) ;
Vector3 perpendicular = ( startPt - endPt ) . normalized * width ;
Vector3 v1 = new Vector3 ( start . x , start . y , 0 ) ;
Vector3 v2 = new Vector3 ( end . x , end . y , 0 ) ;
GL . Vertex ( v1 - perpendicular ) ;
GL . Vertex ( v1 + perpendicular ) ;
GL . Vertex ( v2 + perpendicular ) ;
GL . Vertex ( v2 - perpendicular ) ;
}
GL . End ( ) ;
}
public static void DrawRect ( Rect rect , Color color )
public class GLDraw
{
if ( Event . current = = null )
return ;
if ( Event . current . type ! = EventType . repaint )
return ;
CreateMaterial ( ) ;
// set the current material
lineMaterial . SetPass ( 0 ) ;
GL . Begin ( GL . QUADS ) ;
GL . Color ( color ) ;
GL . Vertex3 ( rect . xMin , rect . yMin , 0 ) ;
GL . Vertex3 ( rect . xMax , rect . yMin , 0 ) ;
GL . Vertex3 ( rect . xMax , rect . yMax , 0 ) ;
GL . Vertex3 ( rect . xMin , rect . yMax , 0 ) ;
GL . End ( ) ;
}
public static void DrawBox ( Rect box , Color color , float width )
{
Vector2 p1 = new Vector2 ( box . xMin , box . yMin ) ;
Vector2 p2 = new Vector2 ( box . xMax , box . yMin ) ;
Vector2 p3 = new Vector2 ( box . xMax , box . yMax ) ;
Vector2 p4 = new Vector2 ( box . xMin , box . yMax ) ;
DrawLine ( p1 , p2 , color , width ) ;
DrawLine ( p2 , p3 , color , width ) ;
DrawLine ( p3 , p4 , color , width ) ;
DrawLine ( p4 , p1 , color , width ) ;
}
public static void DrawBox ( Vector2 topLeftCorner , Vector2 bottomRightCorner , Color color , float width )
{
Rect box = new Rect ( topLeftCorner . x , topLeftCorner . y , bottomRightCorner . x - topLeftCorner . x , bottomRightCorner . y - topLeftCorner . y ) ;
DrawBox ( box , color , width ) ;
}
public static void DrawRoundedBox ( Rect box , float radius , Color color , float width )
{
Vector2 p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ;
p1 = new Vector2 ( box . xMin + radius , box . yMin ) ;
p2 = new Vector2 ( box . xMax - radius , box . yMin ) ;
p3 = new Vector2 ( box . xMax , box . yMin + radius ) ;
p4 = new Vector2 ( box . xMax , box . yMax - radius ) ;
p5 = new Vector2 ( box . xMax - radius , box . yMax ) ;
p6 = new Vector2 ( box . xMin + radius , box . yMax ) ;
p7 = new Vector2 ( box . xMin , box . yMax - radius ) ;
p8 = new Vector2 ( box . xMin , box . yMin + radius ) ;
DrawLine ( p1 , p2 , color , width ) ;
DrawLine ( p3 , p4 , color , width ) ;
DrawLine ( p5 , p6 , color , width ) ;
DrawLine ( p7 , p8 , color , width ) ;
Vector2 t1 , t2 ;
float halfRadius = radius / 2 ;
t1 = new Vector2 ( p8 . x , p8 . y + halfRadius ) ;
t2 = new Vector2 ( p1 . x - halfRadius , p1 . y ) ;
DrawBezier ( p8 , t1 , p1 , t2 , color , width ) ;
t1 = new Vector2 ( p2 . x + halfRadius , p2 . y ) ;
t2 = new Vector2 ( p3 . x , p3 . y - halfRadius ) ;
DrawBezier ( p2 , t1 , p3 , t2 , color , width ) ;
t1 = new Vector2 ( p4 . x , p4 . y + halfRadius ) ;
t2 = new Vector2 ( p5 . x + halfRadius , p5 . y ) ;
DrawBezier ( p4 , t1 , p5 , t2 , color , width ) ;
t1 = new Vector2 ( p6 . x - halfRadius , p6 . y ) ;
t2 = new Vector2 ( p7 . x , p7 . y + halfRadius ) ;
DrawBezier ( p6 , t1 , p7 , t2 , color , width ) ;
}
public static void DrawConnectingCurve ( Vector2 start , Vector2 end , Color color , float width )
{
Vector2 distance = start - end ;
Vector2 tangentA = start ;
tangentA . x - = distance . x * 0.5f ;
Vector2 tangentB = end ;
tangentB . x + = distance . x * 0.5f ;
int segments = Mathf . FloorToInt ( ( distance . magnitude / 2 0 ) * 3 ) ;
DrawBezier ( start , tangentA , end , tangentB , color , width , segments ) ;
Vector2 pA = CubeBezier ( start , tangentA , end , tangentB , 0.6f ) ;
Vector2 pB = CubeBezier ( start , tangentA , end , tangentB , 0.7f ) ;
float arrowHeadSize = 5 ;
/ *
* Clipping code : http : //forum.unity3d.com/threads/17066-How-to-draw-a-GUI-2D-quot-line-quot?p=230386#post230386
* Thick line drawing code : http : //unifycommunity.com/wiki/index.php?title=VectorLine
* /
protected static bool clippingEnabled ;
protected static Rect clippingBounds ;
public static Material lineMaterial = null ;
/* @ Credit: "http://cs-people.bu.edu/jalon/cs480/Oct11Lab/clip.c" */
protected static bool clip_test ( float p , float q , ref float u1 , ref float u2 )
{
float r ;
bool retval = true ;
if ( p < 0.0 )
{
r = q / p ;
if ( r > u2 )
retval = false ;
else if ( r > u1 )
u1 = r ;
}
else if ( p > 0.0 )
{
r = q / p ;
if ( r < u1 )
retval = false ;
else if ( r < u2 )
u2 = r ;
}
else if ( q < 0.0 )
retval = false ;
return retval ;
}
public static bool segment_rect_intersection ( Rect bounds , ref Vector2 p1 , ref Vector2 p2 )
{
float u1 = 0.0f , u2 = 1.0f , dx = p2 . x - p1 . x , dy ;
if ( clip_test ( - dx , p1 . x - bounds . xMin , ref u1 , ref u2 ) )
{
if ( clip_test ( dx , bounds . xMax - p1 . x , ref u1 , ref u2 ) )
{
dy = p2 . y - p1 . y ;
if ( clip_test ( - dy , p1 . y - bounds . yMin , ref u1 , ref u2 ) )
{
if ( clip_test ( dy , bounds . yMax - p1 . y , ref u1 , ref u2 ) )
{
if ( u2 < 1.0 )
{
p2 . x = p1 . x + u2 * dx ;
p2 . y = p1 . y + u2 * dy ;
}
if ( u1 > 0.0 )
{
p1 . x + = u1 * dx ;
p1 . y + = u1 * dy ;
}
return true ;
}
}
}
}
return false ;
}
public static void BeginGroup ( Rect position )
{
clippingEnabled = true ;
clippingBounds = new Rect ( 0 , 0 , position . width , position . height ) ;
GUI . BeginGroup ( position ) ;
}
Vector2 arrowPosA = pB ;
Vector2 arrowPosB = arrowPosA ;
Vector2 arrowPosC = arrowPosA ;
public static void EndGroup ( )
{
GUI . EndGroup ( ) ;
clippingBounds = new Rect ( 0 , 0 , Screen . width , Screen . height ) ;
clippingEnabled = false ;
}
public static Vector2 BeginScrollView ( Rect position , Vector2 scrollPos , Rect viewRect , Rect clipRect )
{
clippingEnabled = true ;
clippingBounds = clipRect ;
return GUI . BeginScrollView ( position , scrollPos , viewRect , GUIStyle . none , GUIStyle . none ) ;
}
Vector2 dir = ( pB - pA ) . normalized ;
arrowPosB . x + = dir . y * arrowHeadSize ;
arrowPosB . y - = dir . x * arrowHeadSize ;
arrowPosB - = dir * arrowHeadSize ;
arrowPosC . x - = dir . y * arrowHeadSize ;
arrowPosC . y + = dir . x * arrowHeadSize ;
arrowPosC - = dir * arrowHeadSize ;
DrawLine ( arrowPosA , arrowPosB , color , 1.025f ) ;
DrawLine ( arrowPosA , arrowPosC , color , 1.025f ) ;
public static void EndScrollView ( )
{
GUI . EndScrollView ( ) ;
clippingBounds = new Rect ( 0 , 0 , Screen . width , Screen . height ) ;
clippingEnabled = false ;
}
public static void CreateMaterial ( )
{
if ( lineMaterial ! = null )
return ;
lineMaterial = Resources . Load ( "GLLineDraw" , typeof ( Material ) ) as Material ;
}
public static void DrawLine ( Vector2 start , Vector2 end , Color color , float width )
{
if ( Event . current = = null )
return ;
if ( Event . current . type ! = EventType . repaint )
return ;
if ( clippingEnabled )
if ( ! segment_rect_intersection ( clippingBounds , ref start , ref end ) )
return ;
CreateMaterial ( ) ;
lineMaterial . SetPass ( 0 ) ;
Vector3 startPt ;
Vector3 endPt ;
if ( width = = 1 )
{
GL . Begin ( GL . LINES ) ;
GL . Color ( color ) ;
startPt = new Vector3 ( start . x , start . y , 0 ) ;
endPt = new Vector3 ( end . x , end . y , 0 ) ;
GL . Vertex ( startPt ) ;
GL . Vertex ( endPt ) ;
}
else
{
GL . Begin ( GL . QUADS ) ;
GL . Color ( color ) ;
startPt = new Vector3 ( end . y , start . x , 0 ) ;
endPt = new Vector3 ( start . y , end . x , 0 ) ;
Vector3 perpendicular = ( startPt - endPt ) . normalized * width ;
Vector3 v1 = new Vector3 ( start . x , start . y , 0 ) ;
Vector3 v2 = new Vector3 ( end . x , end . y , 0 ) ;
GL . Vertex ( v1 - perpendicular ) ;
GL . Vertex ( v1 + perpendicular ) ;
GL . Vertex ( v2 + perpendicular ) ;
GL . Vertex ( v2 - perpendicular ) ;
}
GL . End ( ) ;
}
public static void DrawRect ( Rect rect , Color color )
{
if ( Event . current = = null )
return ;
if ( Event . current . type ! = EventType . repaint )
return ;
CreateMaterial ( ) ;
// set the current material
lineMaterial . SetPass ( 0 ) ;
GL . Begin ( GL . QUADS ) ;
GL . Color ( color ) ;
GL . Vertex3 ( rect . xMin , rect . yMin , 0 ) ;
GL . Vertex3 ( rect . xMax , rect . yMin , 0 ) ;
GL . Vertex3 ( rect . xMax , rect . yMax , 0 ) ;
GL . Vertex3 ( rect . xMin , rect . yMax , 0 ) ;
GL . End ( ) ;
}
public static void DrawBox ( Rect box , Color color , float width )
{
Vector2 p1 = new Vector2 ( box . xMin , box . yMin ) ;
Vector2 p2 = new Vector2 ( box . xMax , box . yMin ) ;
Vector2 p3 = new Vector2 ( box . xMax , box . yMax ) ;
Vector2 p4 = new Vector2 ( box . xMin , box . yMax ) ;
DrawLine ( p1 , p2 , color , width ) ;
DrawLine ( p2 , p3 , color , width ) ;
DrawLine ( p3 , p4 , color , width ) ;
DrawLine ( p4 , p1 , color , width ) ;
}
public static void DrawBox ( Vector2 topLeftCorner , Vector2 bottomRightCorner , Color color , float width )
{
Rect box = new Rect ( topLeftCorner . x , topLeftCorner . y , bottomRightCorner . x - topLeftCorner . x , bottomRightCorner . y - topLeftCorner . y ) ;
DrawBox ( box , color , width ) ;
}
public static void DrawRoundedBox ( Rect box , float radius , Color color , float width )
{
Vector2 p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 ;
p1 = new Vector2 ( box . xMin + radius , box . yMin ) ;
p2 = new Vector2 ( box . xMax - radius , box . yMin ) ;
p3 = new Vector2 ( box . xMax , box . yMin + radius ) ;
p4 = new Vector2 ( box . xMax , box . yMax - radius ) ;
p5 = new Vector2 ( box . xMax - radius , box . yMax ) ;
p6 = new Vector2 ( box . xMin + radius , box . yMax ) ;
p7 = new Vector2 ( box . xMin , box . yMax - radius ) ;
p8 = new Vector2 ( box . xMin , box . yMin + radius ) ;
DrawLine ( p1 , p2 , color , width ) ;
DrawLine ( p3 , p4 , color , width ) ;
DrawLine ( p5 , p6 , color , width ) ;
DrawLine ( p7 , p8 , color , width ) ;
Vector2 t1 , t2 ;
float halfRadius = radius / 2 ;
t1 = new Vector2 ( p8 . x , p8 . y + halfRadius ) ;
t2 = new Vector2 ( p1 . x - halfRadius , p1 . y ) ;
DrawBezier ( p8 , t1 , p1 , t2 , color , width ) ;
t1 = new Vector2 ( p2 . x + halfRadius , p2 . y ) ;
t2 = new Vector2 ( p3 . x , p3 . y - halfRadius ) ;
DrawBezier ( p2 , t1 , p3 , t2 , color , width ) ;
t1 = new Vector2 ( p4 . x , p4 . y + halfRadius ) ;
t2 = new Vector2 ( p5 . x + halfRadius , p5 . y ) ;
DrawBezier ( p4 , t1 , p5 , t2 , color , width ) ;
t1 = new Vector2 ( p6 . x - halfRadius , p6 . y ) ;
t2 = new Vector2 ( p7 . x , p7 . y + halfRadius ) ;
DrawBezier ( p6 , t1 , p7 , t2 , color , width ) ;
}
public static void DrawConnectingCurve ( Vector2 start , Vector2 end , Color color , float width )
{
Vector2 distance = start - end ;
Vector2 tangentA = start ;
tangentA . x - = distance . x * 0.5f ;
Vector2 tangentB = end ;
tangentB . x + = distance . x * 0.5f ;
int segments = Mathf . FloorToInt ( ( distance . magnitude / 2 0 ) * 3 ) ;
DrawBezier ( start , tangentA , end , tangentB , color , width , segments ) ;
Vector2 pA = CubeBezier ( start , tangentA , end , tangentB , 0.6f ) ;
Vector2 pB = CubeBezier ( start , tangentA , end , tangentB , 0.7f ) ;
float arrowHeadSize = 5 ;
Vector2 arrowPosA = pB ;
Vector2 arrowPosB = arrowPosA ;
Vector2 arrowPosC = arrowPosA ;
Vector2 dir = ( pB - pA ) . normalized ;
arrowPosB . x + = dir . y * arrowHeadSize ;
arrowPosB . y - = dir . x * arrowHeadSize ;
arrowPosB - = dir * arrowHeadSize ;
arrowPosC . x - = dir . y * arrowHeadSize ;
arrowPosC . y + = dir . x * arrowHeadSize ;
arrowPosC - = dir * arrowHeadSize ;
DrawLine ( arrowPosA , arrowPosB , color , 1.025f ) ;
DrawLine ( arrowPosA , arrowPosC , color , 1.025f ) ;
}
public static void DrawBezier ( Vector2 start , Vector2 startTangent , Vector2 end , Vector2 endTangent , Color color , float width )
{
int segments = Mathf . FloorToInt ( ( start - end ) . magnitude / 2 0 ) * 3 ; // Three segments per distance of 20
DrawBezier ( start , startTangent , end , endTangent , color , width , segments ) ;
}
public static void DrawBezier ( Vector2 start , Vector2 startTangent , Vector2 end , Vector2 endTangent , Color color , float width , int segments )
{
Vector2 startVector = CubeBezier ( start , startTangent , end , endTangent , 0 ) ;
for ( int i = 1 ; i < = segments ; i + + )
{
Vector2 endVector = CubeBezier ( start , startTangent , end , endTangent , i / ( float ) segments ) ;
DrawLine ( startVector , endVector , color , width ) ;
startVector = endVector ;
}
}
private static Vector2 CubeBezier ( Vector2 s , Vector2 st , Vector2 e , Vector2 et , float t )
{
float rt = 1 - t ;
float rtt = rt * t ;
return rt * rt * rt * s + 3 * rt * rtt * st + 3 * rtt * t * et + t * t * t * e ;
}
}
public static void DrawBezier ( Vector2 start , Vector2 startTangent , Vector2 end , Vector2 endTangent , Color color , float width )
{
int segments = Mathf . FloorToInt ( ( start - end ) . magnitude / 2 0 ) * 3 ; // Three segments per distance of 20
DrawBezier ( start , startTangent , end , endTangent , color , width , segments ) ;
}
public static void DrawBezier ( Vector2 start , Vector2 startTangent , Vector2 end , Vector2 endTangent , Color color , float width , int segments )
{
Vector2 startVector = CubeBezier ( start , startTangent , end , endTangent , 0 ) ;
for ( int i = 1 ; i < = segments ; i + + )
{
Vector2 endVector = CubeBezier ( start , startTangent , end , endTangent , i / ( float ) segments ) ;
DrawLine ( startVector , endVector , color , width ) ;
startVector = endVector ;
}
}
private static Vector2 CubeBezier ( Vector2 s , Vector2 st , Vector2 e , Vector2 et , float t )
{
float rt = 1 - t ;
float rtt = rt * t ;
return rt * rt * rt * s + 3 * rt * rtt * st + 3 * rtt * t * et + t * t * t * e ;
}
}