Merge branch 'dev'

This commit is contained in:
faiface 2017-06-11 01:19:57 +02:00
commit 12df203229
3 changed files with 49 additions and 35 deletions

View File

@ -65,6 +65,14 @@ func (u Vec) Sub(v Vec) Vec {
} }
} }
// To returns the vector from u to v. Equivalent to v.Sub(u).
func (u Vec) To(v Vec) Vec {
return Vec{
v.X - u.X,
v.Y - u.Y,
}
}
// Scaled returns the vector u multiplied by c. // Scaled returns the vector u multiplied by c.
func (u Vec) Scaled(c float64) Vec { func (u Vec) Scaled(c float64) Vec {
return Vec{u.X * c, u.Y * c} return Vec{u.X * c, u.Y * c}
@ -102,6 +110,11 @@ func (u Vec) Rotated(angle float64) Vec {
} }
} }
// Normal returns a vector normal to u. Equivalent to u.Rotated(math.Pi / 2), but faster.
func (u Vec) Normal() Vec {
return Vec{X: u.Y, Y: -u.X}
}
// Dot returns the dot product of vectors u and v. // Dot returns the dot product of vectors u and v.
func (u Vec) Dot(v Vec) float64 { func (u Vec) Dot(v Vec) float64 {
return u.X*v.X + u.Y*v.Y return u.X*v.X + u.Y*v.Y

View File

@ -128,7 +128,9 @@ func (imd *IMDraw) Draw(t pixel.Target) {
// Push adds some points to the IM queue. All Pushed points will have the same properties except for // Push adds some points to the IM queue. All Pushed points will have the same properties except for
// the position. // the position.
func (imd *IMDraw) Push(pts ...pixel.Vec) { func (imd *IMDraw) Push(pts ...pixel.Vec) {
imd.Color = pixel.ToRGBA(imd.Color) if _, ok := imd.Color.(pixel.RGBA); !ok {
imd.Color = pixel.ToRGBA(imd.Color)
}
opts := point{ opts := point{
col: imd.Color.(pixel.RGBA), col: imd.Color.(pixel.RGBA),
pic: imd.Picture, pic: imd.Picture,
@ -495,12 +497,12 @@ func (imd *IMDraw) outlineEllipseArc(radius pixel.Vec, low, high, thickness floa
thick := pixel.V(thickness/2, 0).Rotated(normalLow) thick := pixel.V(thickness/2, 0).Rotated(normalLow)
imd.pushPt(lowCenter.Add(thick), pt) imd.pushPt(lowCenter.Add(thick), pt)
imd.pushPt(lowCenter.Sub(thick), pt) imd.pushPt(lowCenter.Sub(thick), pt)
imd.pushPt(lowCenter.Sub(thick.Rotated(math.Pi/2*orientation)), pt) imd.pushPt(lowCenter.Sub(thick.Normal().Scaled(orientation)), pt)
imd.fillPolygon() imd.fillPolygon()
thick = pixel.V(thickness/2, 0).Rotated(normalHigh) thick = pixel.V(thickness/2, 0).Rotated(normalHigh)
imd.pushPt(highCenter.Add(thick), pt) imd.pushPt(highCenter.Add(thick), pt)
imd.pushPt(highCenter.Sub(thick), pt) imd.pushPt(highCenter.Sub(thick), pt)
imd.pushPt(highCenter.Add(thick.Rotated(math.Pi/2*orientation)), pt) imd.pushPt(highCenter.Add(thick.Normal().Scaled(orientation)), pt)
imd.fillPolygon() imd.fillPolygon()
case RoundEndShape: case RoundEndShape:
imd.pushPt(lowCenter, pt) imd.pushPt(lowCenter, pt)
@ -528,29 +530,27 @@ func (imd *IMDraw) polyline(thickness float64, closed bool) {
// first point // first point
j, i := 0, 1 j, i := 0, 1
normal := points[i].pos.Sub(points[j].pos).Rotated(math.Pi / 2).Unit().Scaled(thickness / 2) ijNormal := points[0].pos.To(points[1].pos).Normal().Unit().Scaled(thickness / 2)
if !closed { if !closed {
switch points[j].endshape { switch points[j].endshape {
case NoEndShape: case NoEndShape:
// nothing // nothing
case SharpEndShape: case SharpEndShape:
imd.pushPt(points[j].pos.Add(normal), points[j]) imd.pushPt(points[j].pos.Add(ijNormal), points[j])
imd.pushPt(points[j].pos.Sub(normal), points[j]) imd.pushPt(points[j].pos.Sub(ijNormal), points[j])
imd.pushPt(points[j].pos.Add(normal.Rotated(math.Pi/2)), points[j]) imd.pushPt(points[j].pos.Add(ijNormal.Normal()), points[j])
imd.fillPolygon() imd.fillPolygon()
case RoundEndShape: case RoundEndShape:
imd.pushPt(points[j].pos, points[j]) imd.pushPt(points[j].pos, points[j])
imd.fillEllipseArc(pixel.V(thickness/2, thickness/2), normal.Angle(), normal.Angle()+math.Pi) imd.fillEllipseArc(pixel.V(thickness/2, thickness/2), ijNormal.Angle(), ijNormal.Angle()+math.Pi)
} }
} }
imd.pushPt(points[j].pos.Add(normal), points[j]) imd.pushPt(points[j].pos.Add(ijNormal), points[j])
imd.pushPt(points[j].pos.Sub(normal), points[j]) imd.pushPt(points[j].pos.Sub(ijNormal), points[j])
// middle points // middle points
// compute "previous" normal:
ijNormal := points[1].pos.Sub(points[0].pos).Rotated(math.Pi / 2).Unit().Scaled(thickness / 2)
for i := 0; i < len(points); i++ { for i := 0; i < len(points); i++ {
j, k := i+1, i+2 j, k := i+1, i+2
@ -566,7 +566,7 @@ func (imd *IMDraw) polyline(thickness float64, closed bool) {
k %= len(points) k %= len(points)
} }
jkNormal := points[k].pos.Sub(points[j].pos).Rotated(math.Pi / 2).Unit().Scaled(thickness / 2) jkNormal := points[j].pos.To(points[k].pos).Normal().Unit().Scaled(thickness / 2)
orientation := 1.0 orientation := 1.0
if ijNormal.Cross(jkNormal) > 0 { if ijNormal.Cross(jkNormal) > 0 {
@ -602,10 +602,10 @@ func (imd *IMDraw) polyline(thickness float64, closed bool) {
// last point // last point
i, j = len(points)-2, len(points)-1 i, j = len(points)-2, len(points)-1
normal = points[j].pos.Sub(points[i].pos).Rotated(math.Pi / 2).Unit().Scaled(thickness / 2) ijNormal = points[i].pos.To(points[j].pos).Normal().Unit().Scaled(thickness / 2)
imd.pushPt(points[j].pos.Sub(normal), points[j]) imd.pushPt(points[j].pos.Sub(ijNormal), points[j])
imd.pushPt(points[j].pos.Add(normal), points[j]) imd.pushPt(points[j].pos.Add(ijNormal), points[j])
imd.fillPolygon() imd.fillPolygon()
if !closed { if !closed {
@ -613,13 +613,13 @@ func (imd *IMDraw) polyline(thickness float64, closed bool) {
case NoEndShape: case NoEndShape:
// nothing // nothing
case SharpEndShape: case SharpEndShape:
imd.pushPt(points[j].pos.Add(normal), points[j]) imd.pushPt(points[j].pos.Add(ijNormal), points[j])
imd.pushPt(points[j].pos.Sub(normal), points[j]) imd.pushPt(points[j].pos.Sub(ijNormal), points[j])
imd.pushPt(points[j].pos.Add(normal.Rotated(-math.Pi/2)), points[j]) imd.pushPt(points[j].pos.Add(ijNormal.Normal().Scaled(-1)), points[j])
imd.fillPolygon() imd.fillPolygon()
case RoundEndShape: case RoundEndShape:
imd.pushPt(points[j].pos, points[j]) imd.pushPt(points[j].pos, points[j])
imd.fillEllipseArc(pixel.V(thickness/2, thickness/2), normal.Angle(), normal.Angle()-math.Pi) imd.fillEllipseArc(pixel.V(thickness/2, thickness/2), ijNormal.Angle(), ijNormal.Angle()-math.Pi)
} }
} }

View File

@ -101,16 +101,17 @@ func (gt *GLTriangles) updateData(t pixel.Triangles) {
} }
// TrianglesData short path // TrianglesData short path
stride := gt.vs.Stride()
length := gt.Len()
if t, ok := t.(*pixel.TrianglesData); ok { if t, ok := t.(*pixel.TrianglesData); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < length; i++ {
var ( var (
px, py = (*t)[i].Position.XY() px, py = (*t)[i].Position.XY()
col = (*t)[i].Color col = (*t)[i].Color
tx, ty = (*t)[i].Picture.XY() tx, ty = (*t)[i].Picture.XY()
in = (*t)[i].Intensity in = (*t)[i].Intensity
) )
s := gt.vs.Stride() d := gt.data[i*stride : i*stride+9]
d := gt.data[i*s : i*s+9]
d[0] = float32(px) d[0] = float32(px)
d[1] = float32(py) d[1] = float32(py)
d[2] = float32(col.R) d[2] = float32(col.R)
@ -125,27 +126,27 @@ func (gt *GLTriangles) updateData(t pixel.Triangles) {
} }
if t, ok := t.(pixel.TrianglesPosition); ok { if t, ok := t.(pixel.TrianglesPosition); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < length; i++ {
px, py := t.Position(i).XY() px, py := t.Position(i).XY()
gt.data[i*gt.vs.Stride()+0] = float32(px) gt.data[i*stride+0] = float32(px)
gt.data[i*gt.vs.Stride()+1] = float32(py) gt.data[i*stride+1] = float32(py)
} }
} }
if t, ok := t.(pixel.TrianglesColor); ok { if t, ok := t.(pixel.TrianglesColor); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < length; i++ {
col := t.Color(i) col := t.Color(i)
gt.data[i*gt.vs.Stride()+2] = float32(col.R) gt.data[i*stride+2] = float32(col.R)
gt.data[i*gt.vs.Stride()+3] = float32(col.G) gt.data[i*stride+3] = float32(col.G)
gt.data[i*gt.vs.Stride()+4] = float32(col.B) gt.data[i*stride+4] = float32(col.B)
gt.data[i*gt.vs.Stride()+5] = float32(col.A) gt.data[i*stride+5] = float32(col.A)
} }
} }
if t, ok := t.(pixel.TrianglesPicture); ok { if t, ok := t.(pixel.TrianglesPicture); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < length; i++ {
pic, intensity := t.Picture(i) pic, intensity := t.Picture(i)
gt.data[i*gt.vs.Stride()+6] = float32(pic.X) gt.data[i*stride+6] = float32(pic.X)
gt.data[i*gt.vs.Stride()+7] = float32(pic.Y) gt.data[i*stride+7] = float32(pic.Y)
gt.data[i*gt.vs.Stride()+8] = float32(intensity) gt.data[i*stride+8] = float32(intensity)
} }
} }
} }