feat: starting implementing collisions.
This commit is contained in:
parent
7dcf0eeca8
commit
f910d4f99b
17 changed files with 349 additions and 195 deletions
|
@ -33,7 +33,7 @@ func NewTri() *Tri {
|
||||||
|
|
||||||
func (t *Tri) Update(c *Context) {
|
func (t *Tri) Update(c *Context) {
|
||||||
dt := c.Dt().Seconds()
|
dt := c.Dt().Seconds()
|
||||||
if t.ContainsPoint(c.AbsCursorPosition()) {
|
if !t.ContainedPoints(gg.Points{c.AbsCursorPosition()}).Empty() {
|
||||||
t.Color = gg.Rgba(0, 1, 0, 1)
|
t.Color = gg.Rgba(0, 1, 0, 1)
|
||||||
} else {
|
} else {
|
||||||
t.Color = gg.Rgba(1, 0, 1, 1)
|
t.Color = gg.Rgba(1, 0, 1, 1)
|
||||||
|
|
80
collider.go
80
collider.go
|
@ -6,19 +6,25 @@ package gg
|
||||||
// if the the bigger collider that
|
// if the the bigger collider that
|
||||||
// contains more complicated (accurate) structure
|
// contains more complicated (accurate) structure
|
||||||
// do collide.
|
// do collide.
|
||||||
type ColliderSimplifier interface {
|
//type ColliderSimplifier interface {
|
||||||
ColliderSimplify() Triangle
|
//ColliderSimplify() Triangle
|
||||||
}
|
//}
|
||||||
|
|
||||||
// The structure represents all
|
type CollisionType int
|
||||||
// information on collisions.
|
const (
|
||||||
|
CollisionTypePhys CollisionType = iota
|
||||||
|
CollisionTypeTrigger
|
||||||
|
)
|
||||||
|
|
||||||
|
// The structure contains collision information.
|
||||||
type Collision struct {
|
type Collision struct {
|
||||||
Current, With any
|
Type CollisionType
|
||||||
|
What, With Objecter
|
||||||
|
// Points of Self contained in
|
||||||
|
Points Points
|
||||||
|
Crosses []LineCross
|
||||||
}
|
}
|
||||||
|
|
||||||
type PointContainer interface {
|
|
||||||
ContainsPoint(Point) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementing the interface lets the engine
|
// Implementing the interface lets the engine
|
||||||
// to determine if the object collides with anything.
|
// to determine if the object collides with anything.
|
||||||
|
@ -26,8 +32,60 @@ type PointContainer interface {
|
||||||
// inner structure field as first argument.
|
// inner structure field as first argument.
|
||||||
// The Collide method will be called on collisions.
|
// The Collide method will be called on collisions.
|
||||||
type Collider interface {
|
type Collider interface {
|
||||||
Collides(Collider) *Collision
|
// Checks whether the object is collidable
|
||||||
Collide(*Collision)
|
IsCollidable() bool
|
||||||
|
Verticer
|
||||||
|
Edger
|
||||||
|
PointContainer
|
||||||
|
}
|
||||||
|
type Collidability struct {
|
||||||
|
Collidable bool
|
||||||
|
}
|
||||||
|
func (c Collidability) IsCollidable() bool {
|
||||||
|
return c.Collidable
|
||||||
|
}
|
||||||
|
type PointContainer interface {
|
||||||
|
ContainedPoints(Points) Points
|
||||||
|
}
|
||||||
|
type Verticer interface {
|
||||||
|
Vertices() Vertices
|
||||||
|
}
|
||||||
|
type Edger interface {
|
||||||
|
Edges() Edges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implementing the type provides way
|
||||||
|
// to resolve collisions and other problems.
|
||||||
|
// The Resolve() is called right after the Update() of Updater.
|
||||||
|
type Resolver interface {
|
||||||
|
IsResolvable() bool
|
||||||
|
Resolve(c *Context)
|
||||||
|
Collider
|
||||||
|
}
|
||||||
|
type Resolvability struct {
|
||||||
|
Resolvable bool
|
||||||
|
}
|
||||||
|
func (r Resolvability) IsResolvable() bool {
|
||||||
|
return r.Resolvable
|
||||||
|
}
|
||||||
|
|
||||||
|
func Collide(c1, c2 Collider) (Collision, bool) {
|
||||||
|
vertices := c1.Vertices()
|
||||||
|
es1, es2 := c1.Edges(), c2.Edges()
|
||||||
|
crosses, doCross := es1.LineCrossWith(es2)
|
||||||
|
pts := c2.ContainedPoints(vertices)
|
||||||
|
return Collision{
|
||||||
|
Points: pts,
|
||||||
|
Crosses: crosses,
|
||||||
|
}, len(pts) != 0 || doCross
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCollisions(c Collider, cs []Collider) []Collision {
|
||||||
|
ret := []Collision{}
|
||||||
|
for _, ic := range cs {
|
||||||
|
if !ic.IsCollidable() || ic == c {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ type contextType int
|
||||||
const (
|
const (
|
||||||
startContext contextType = iota
|
startContext contextType = iota
|
||||||
updateContext
|
updateContext
|
||||||
|
resolveContext
|
||||||
eventContext
|
eventContext
|
||||||
drawContext
|
drawContext
|
||||||
deleteContext
|
deleteContext
|
||||||
|
@ -12,6 +13,7 @@ const (
|
||||||
type Context struct {
|
type Context struct {
|
||||||
typ contextType
|
typ contextType
|
||||||
Events []any
|
Events []any
|
||||||
|
Collisions []Collision
|
||||||
*Engine
|
*Engine
|
||||||
*Image
|
*Image
|
||||||
}
|
}
|
||||||
|
|
78
edge.go
Normal file
78
edge.go
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package gg
|
||||||
|
|
||||||
|
type Edges []Edge
|
||||||
|
// Get crosses of edges.
|
||||||
|
func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) {
|
||||||
|
ret := []LineCross{}
|
||||||
|
for i := range what {
|
||||||
|
for j := range with {
|
||||||
|
cross, doCross := LinersCross(what[i], with[j])
|
||||||
|
if doCross {
|
||||||
|
ret = append(ret, cross)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The type represents a line segment. The name is for short.
|
||||||
|
type Edge [2]Vector
|
||||||
|
|
||||||
|
// Returns corresponding to the segment Line.
|
||||||
|
func (l Edge) Line() Line {
|
||||||
|
p0 := l[0]
|
||||||
|
p1 := l[1]
|
||||||
|
|
||||||
|
k := (p0.Y - p1.Y) / (p0.X - p1.X)
|
||||||
|
c := p0.Y - p0.X*k
|
||||||
|
|
||||||
|
return Line{k, c}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Edge) ContainedPoints(pts Points) (Points) {
|
||||||
|
ret := Points{}
|
||||||
|
for i := range pts {
|
||||||
|
if l.ContainsPoint(pts[i]) {
|
||||||
|
ret = append(ret, pts[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the edge contains the specified point.
|
||||||
|
func (l Edge) ContainsPoint(p Point) bool {
|
||||||
|
line := l.Line()
|
||||||
|
if !line.ContainsPoint(p) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
xMax := Max(l[0].X, l[1].X)
|
||||||
|
xMin := Min(l[0].X, l[1].X)
|
||||||
|
|
||||||
|
yMax := Max(l[0].Y, l[1].Y)
|
||||||
|
yMin := Min(l[0].Y, l[1].Y)
|
||||||
|
|
||||||
|
if !(xMin < p.X && p.X < xMax) ||
|
||||||
|
!(yMin < p.Y && p.Y < yMax) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get square of length of line segment (for performance sometimes).
|
||||||
|
func (ls Edge) LenSqr() Float {
|
||||||
|
return Sqr(ls[0].X - ls[1].X) +
|
||||||
|
Sqr(ls[0].Y - ls[1].Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get length of the line segment.
|
||||||
|
func (ls Edge) Len() Float {
|
||||||
|
return Sqrt(ls.LenSqr())
|
||||||
|
}
|
||||||
|
|
50
engine.go
50
engine.go
|
@ -232,14 +232,9 @@ func (e *Engine) Runes() []rune {
|
||||||
return e.runes
|
return e.runes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) Update() error {
|
func (e *engine) UpdateEvents() []any {
|
||||||
|
|
||||||
eng := (*Engine)(e)
|
eng := (*Engine)(e)
|
||||||
e.dt = time.Since(e.lastTime)
|
|
||||||
|
|
||||||
e.runes = ebiten.AppendInputChars(e.runes[:0])
|
|
||||||
fmt.Println("runes:", e.runes)
|
|
||||||
// Buffering the context for faster.
|
|
||||||
|
|
||||||
e.prevKeys = e.keys
|
e.prevKeys = e.keys
|
||||||
e.keys = inpututil.
|
e.keys = inpututil.
|
||||||
AppendPressedKeys(e.keys[:0])
|
AppendPressedKeys(e.keys[:0])
|
||||||
|
@ -261,10 +256,10 @@ func (e *engine) Update() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
x, y := ebiten.Wheel()
|
x, y := ebiten.Wheel()
|
||||||
eng.wheel = V(x, y)
|
e.wheel = V(x, y)
|
||||||
if !(eng.wheel.Eq(ZV)) {
|
if !(e.wheel.Eq(ZV)) {
|
||||||
events = append(events, &WheelChange{
|
events = append(events, &WheelChange{
|
||||||
Offset: eng.wheel,
|
Offset: e.wheel,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,22 +279,34 @@ func (e *engine) Update() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
realPos := eng.cursorPosition()
|
realPos := eng.cursorPosition()
|
||||||
if !realPos.Eq(eng.cursorPos) {
|
if !realPos.Eq(e.cursorPos) {
|
||||||
absM := eng.Camera.AbsMatrix()
|
absM := eng.Camera.AbsMatrix()
|
||||||
|
|
||||||
absPrevPos :=eng.cursorPos.Apply(absM)
|
absPrevPos := e.cursorPos.Apply(absM)
|
||||||
absPos := realPos.Apply(absM)
|
absPos := realPos.Apply(absM)
|
||||||
|
|
||||||
events = append(events, &MouseMove{
|
events = append(events, &MouseMove{
|
||||||
Real: realPos.Sub(eng.cursorPos),
|
Real: realPos.Sub(e.cursorPos),
|
||||||
Abs: absPos.Sub(absPrevPos),
|
Abs: absPos.Sub(absPrevPos),
|
||||||
})
|
})
|
||||||
eng.cursorPos = realPos
|
e.cursorPos = realPos
|
||||||
}
|
}
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *engine) Update() error {
|
||||||
|
|
||||||
|
eng := (*Engine)(e)
|
||||||
|
e.dt = time.Since(e.lastTime)
|
||||||
|
|
||||||
|
e.runes = ebiten.AppendInputChars(e.runes[:0])
|
||||||
|
fmt.Println("runes:", e.runes)
|
||||||
|
// Buffering the context for faster.
|
||||||
// Providing the events to the objects.
|
// Providing the events to the objects.
|
||||||
// Maybe should think of the better way,
|
// Maybe should think of the better way,
|
||||||
// but for it is simple enough.
|
// but for it is simple enough.
|
||||||
|
|
||||||
|
events := e.UpdateEvents()
|
||||||
c := &Context{
|
c := &Context{
|
||||||
Engine: eng,
|
Engine: eng,
|
||||||
typ: updateContext,
|
typ: updateContext,
|
||||||
|
@ -310,11 +317,26 @@ func (e *engine) Update() error {
|
||||||
object.Input() <- c
|
object.Input() <- c
|
||||||
}
|
}
|
||||||
e.wg.Wait()
|
e.wg.Wait()
|
||||||
|
e.Resolve()
|
||||||
|
|
||||||
e.lastTime = time.Now()
|
e.lastTime = time.Now()
|
||||||
e.frame++
|
e.frame++
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *engine) Resolve() {
|
||||||
|
colliders := []Collider{}
|
||||||
|
resolvers := []Resolver{}
|
||||||
|
for _, object := range e.Objects.store {
|
||||||
|
if object.IsCollidable() {
|
||||||
|
colliders = append(colliders, object)
|
||||||
|
}
|
||||||
|
if object.IsResolvable() {
|
||||||
|
resolvers = append(resolvers, object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fullPageIndexes = func() [MaxVertices]uint16 {
|
fullPageIndexes = func() [MaxVertices]uint16 {
|
||||||
ret := [MaxVertices]uint16{}
|
ret := [MaxVertices]uint16{}
|
||||||
|
|
120
line.go
120
line.go
|
@ -1,88 +1,15 @@
|
||||||
package gg
|
package gg
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
//"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The type represents mathematical equation of line and line itself.
|
// The type represents mathematical equation of line and line itself.
|
||||||
type Line struct {
|
type Line struct {
|
||||||
K, C Float
|
K, C Float
|
||||||
}
|
}
|
||||||
|
|
||||||
type Liner interface {
|
|
||||||
Line() Line
|
|
||||||
}
|
|
||||||
|
|
||||||
type LinerPointContainer interface {
|
|
||||||
Liner
|
|
||||||
PointContainer
|
|
||||||
}
|
|
||||||
|
|
||||||
// The type represents a line segment.
|
|
||||||
type LineSegment [2]Point
|
|
||||||
|
|
||||||
// The type represents multiple line segments.
|
|
||||||
type LineSegments []LineSegment
|
|
||||||
|
|
||||||
type Edge = LineSegment
|
|
||||||
type Edges = LineSegments
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Check if two LinerPointContainers do cross and return the
|
|
||||||
// crossing point.
|
|
||||||
func LinersCross(lp1, lp2 LinerPointContainer) (Point, bool) {
|
|
||||||
l1 := lp1.Line()
|
|
||||||
l2 := lp2.Line()
|
|
||||||
|
|
||||||
p, crosses := l1.crossesLine(l2)
|
|
||||||
if !crosses ||
|
|
||||||
!lp1.ContainsPoint(p) ||
|
|
||||||
!lp2.ContainsPoint(p) {
|
|
||||||
return Point{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the liner is parallel to the other liner.
|
|
||||||
func LinersParallel(first, second Liner) bool {
|
|
||||||
l1 := first.Line()
|
|
||||||
l2 := second.Line()
|
|
||||||
|
|
||||||
return l1.K == l2.K
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns angle between liners in radians.
|
|
||||||
// The value fits the -Pi < Value < Pi condition.
|
|
||||||
func LinersAngle(first, second Liner) Float {
|
|
||||||
l1 := first.Line()
|
|
||||||
l2 := second.Line()
|
|
||||||
|
|
||||||
if l1.K == l2.K {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return math.Atan(l1.K/l2.K)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the line itself. Made to implement the Liner interface.
|
// Returns the line itself. Made to implement the Liner interface.
|
||||||
func (l Line) Line() Line {
|
func (l Line) Line() Line {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns corresponding to the segment line line.
|
|
||||||
func (l LineSegment) Line() Line {
|
|
||||||
p0 := l[0]
|
|
||||||
p1 := l[1]
|
|
||||||
|
|
||||||
k := (p0.Y - p1.Y) / (p0.X - p1.X)
|
|
||||||
c := p0.Y - p0.X*k
|
|
||||||
|
|
||||||
return Line{k, c}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Line) ContainsPoint(p Point) bool {
|
func (l Line) ContainsPoint(p Point) bool {
|
||||||
buf := Line{0, p.Y}
|
buf := Line{0, p.Y}
|
||||||
pc, ok := l.crossesLine(buf)
|
pc, ok := l.crossesLine(buf)
|
||||||
|
@ -93,26 +20,6 @@ func (l Line) ContainsPoint(p Point) bool {
|
||||||
return pc == p
|
return pc == p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) ContainsPoint(p Point) bool {
|
|
||||||
line := l.Line()
|
|
||||||
if !line.ContainsPoint(p) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
xMax := Max(l[0].X, l[1].X)
|
|
||||||
xMin := Min(l[0].X, l[1].X)
|
|
||||||
|
|
||||||
yMax := Max(l[0].Y, l[1].Y)
|
|
||||||
yMin := Min(l[0].Y, l[1].Y)
|
|
||||||
|
|
||||||
if !(xMin < p.X && p.X < xMax) ||
|
|
||||||
!(yMin < p.Y && p.Y < yMax) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l1 Line) crossesLine(l2 Line) (Point, bool) {
|
func (l1 Line) crossesLine(l2 Line) (Point, bool) {
|
||||||
if LinersParallel(l1, l2) {
|
if LinersParallel(l1, l2) {
|
||||||
return Point{}, false
|
return Point{}, false
|
||||||
|
@ -124,30 +31,3 @@ func (l1 Line) crossesLine(l2 Line) (Point, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get square of length of line segment.
|
|
||||||
func (ls LineSegment) LenSqr() Float {
|
|
||||||
return Sqr(ls[0].X - ls[1].X) +
|
|
||||||
Sqr(ls[0].Y - ls[1].Y)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get length of the line segment.
|
|
||||||
func (ls LineSegment) Len() Float {
|
|
||||||
return math.Sqrt(ls.LenSqr())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (what LineSegments) Cross(with LineSegments) ([][2]int, Points) {
|
|
||||||
indexes := [][2]int{}
|
|
||||||
points := Points{}
|
|
||||||
for i := range what {
|
|
||||||
for j := range with {
|
|
||||||
p, cross := LinersCross(what[i], with[j])
|
|
||||||
if cross {
|
|
||||||
points = append(points, p)
|
|
||||||
indexes = append(indexes, [2]int{i, j})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return indexes, points
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
56
liner.go
Normal file
56
liner.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package gg
|
||||||
|
|
||||||
|
type Liner interface {
|
||||||
|
Line() Line
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinerPointContainer interface {
|
||||||
|
Liner
|
||||||
|
PointContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
// The type represents the cross of 2 Liners.
|
||||||
|
type LineCross struct {
|
||||||
|
Pair [2]Line
|
||||||
|
Point Point
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if two LinerPointContainers do cross and return the
|
||||||
|
// crossing point.
|
||||||
|
func LinersCross(lp1, lp2 LinerPointContainer) (LineCross, bool) {
|
||||||
|
l1 := lp1.Line()
|
||||||
|
l2 := lp2.Line()
|
||||||
|
|
||||||
|
crossPt, doCross := l1.crossesLine(l2)
|
||||||
|
if !doCross ||
|
||||||
|
len(lp1.ContainedPoints([]Point{crossPt}))==0 ||
|
||||||
|
len(lp2.ContainedPoints([]Point{crossPt}))==0 {
|
||||||
|
return LineCross{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return LineCross{
|
||||||
|
Pair: [2]Line{l1, l2},
|
||||||
|
Point: crossPt,
|
||||||
|
}, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the liner is parallel to the other liner.
|
||||||
|
func LinersParallel(first, second Liner) bool {
|
||||||
|
l1 := first.Line()
|
||||||
|
l2 := second.Line()
|
||||||
|
|
||||||
|
return l1.K == l2.K
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns angle between liners in radians.
|
||||||
|
// The value fits the -Pi < Value < Pi condition.
|
||||||
|
func LinersAngle(first, second Liner) Float {
|
||||||
|
l1 := first.Line()
|
||||||
|
l2 := second.Line()
|
||||||
|
|
||||||
|
if l1.K == l2.K {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return Atan(l1.K/l2.K)
|
||||||
|
}
|
4
math.go
4
math.go
|
@ -24,6 +24,10 @@ func Sqr(v Float) Float {
|
||||||
return v * v
|
return v * v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Sqrt(v Float) Float {
|
||||||
|
return math.Sqrt(v)
|
||||||
|
}
|
||||||
|
|
||||||
func Asin(v Float) Float {
|
func Asin(v Float) Float {
|
||||||
return math.Asin(v)
|
return math.Asin(v)
|
||||||
}
|
}
|
||||||
|
|
13
object.go
13
object.go
|
@ -54,14 +54,19 @@ type Objecter interface {
|
||||||
Input() chan *Context
|
Input() chan *Context
|
||||||
Starter
|
Starter
|
||||||
Updater
|
Updater
|
||||||
|
Collider
|
||||||
|
Resolver
|
||||||
Drawer
|
Drawer
|
||||||
Deleter
|
Deleter
|
||||||
}
|
}
|
||||||
|
|
||||||
// The type for embedding into engine-in types.
|
// The type for embedding into engine-in types.
|
||||||
type Object struct {
|
type Object struct {
|
||||||
|
Collidability
|
||||||
|
Resolvability
|
||||||
Layer
|
Layer
|
||||||
Visibility
|
Visibility
|
||||||
|
|
||||||
input chan *Context
|
input chan *Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +74,15 @@ func (o *Object) GetObject() *Object { return o }
|
||||||
func (o *Object) Input() chan *Context { return o.input }
|
func (o *Object) Input() chan *Context { return o.input }
|
||||||
|
|
||||||
func (o *Object) Start(c *Context) {}
|
func (o *Object) Start(c *Context) {}
|
||||||
|
|
||||||
func (o *Object) Update(c *Context) {}
|
func (o *Object) Update(c *Context) {}
|
||||||
|
|
||||||
|
func (o *Object) ContainedPoints(Points) Points {return Points{}}
|
||||||
|
func (o *Object) Vertices() Vertices {return Vertices{}}
|
||||||
|
func (o *Object) Edges() Edges {return Edges{}}
|
||||||
|
|
||||||
|
func (o *Object) Resolve(c *Context) {}
|
||||||
|
|
||||||
func (o *Object) Draw(c *Context) []EVertex { return nil}
|
func (o *Object) Draw(c *Context) []EVertex { return nil}
|
||||||
func (o *Object) Delete(c *Context) {}
|
func (o *Object) Delete(c *Context) {}
|
||||||
|
|
||||||
|
|
8
point.go
Normal file
8
point.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package gg
|
||||||
|
|
||||||
|
type Point = Vector
|
||||||
|
type Points []Point
|
||||||
|
|
||||||
|
func (pts Points) Empty() bool {
|
||||||
|
return len(pts) == 0
|
||||||
|
}
|
21
polygon.go
21
polygon.go
|
@ -10,17 +10,8 @@ type Polygon struct {
|
||||||
Triangles
|
Triangles
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Polygon) ContainsPoint(pnt Point) bool {
|
func (p Polygon) ContainedPoints(pts Points) (Points) {
|
||||||
return p.MakeTriangles().ContainsPoint(pnt)
|
return p.MakeTriangles().ContainedPoints(pts)
|
||||||
}
|
|
||||||
|
|
||||||
// Polygon that can be drawn.
|
|
||||||
type DrawablePolygon struct {
|
|
||||||
Polygon
|
|
||||||
|
|
||||||
ShaderOptions
|
|
||||||
Visibility
|
|
||||||
Colority
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Polygon) MakeTriangles() Triangles {
|
func (p Polygon) MakeTriangles() Triangles {
|
||||||
|
@ -37,6 +28,14 @@ func (p Polygon) MakeTriangles() Triangles {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Polygon that can be drawn.
|
||||||
|
type DrawablePolygon struct {
|
||||||
|
Polygon
|
||||||
|
ShaderOptions
|
||||||
|
Visibility
|
||||||
|
Colority
|
||||||
|
}
|
||||||
|
|
||||||
func (p *DrawablePolygon) Draw(c *Context) []EVertex {
|
func (p *DrawablePolygon) Draw(c *Context) []EVertex {
|
||||||
return (&DrawableTriangles{
|
return (&DrawableTriangles{
|
||||||
Colority: p.Colority,
|
Colority: p.Colority,
|
||||||
|
|
49
rect.go
49
rect.go
|
@ -7,28 +7,16 @@ import (
|
||||||
//"image"
|
//"image"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The type describes rectangle geometry.
|
// The type describes rectangle geometry with
|
||||||
|
// way to move, rotate and scale it.
|
||||||
type Rectangle struct {
|
type Rectangle struct {
|
||||||
Object
|
Object
|
||||||
Transform
|
Transform
|
||||||
}
|
Width, Height Float
|
||||||
|
|
||||||
// The type describes rectangle that can be drawn.
|
|
||||||
type DrawableRectangle struct {
|
|
||||||
Rectangle
|
|
||||||
ShaderOptions
|
|
||||||
|
|
||||||
// Solid color of the rectangle.
|
|
||||||
// Will be ignored if the Shader
|
|
||||||
// field is not nil.
|
|
||||||
Colority
|
|
||||||
|
|
||||||
// Should be draw or not.
|
|
||||||
Visibility
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return points of vertices of the rectangle.
|
// Return points of vertices of the rectangle.
|
||||||
func (r Rectangle) Vertices() Points {
|
func (r Rectangle) Vertices() Vertices {
|
||||||
m := r.Matrix()
|
m := r.Matrix()
|
||||||
p1 := V(0, 0).Apply(m)
|
p1 := V(0, 0).Apply(m)
|
||||||
p2 := V(1, 0).Apply(m)
|
p2 := V(1, 0).Apply(m)
|
||||||
|
@ -39,11 +27,11 @@ func (r Rectangle) Vertices() Points {
|
||||||
|
|
||||||
func (r Rectangle) Edges() Edges {
|
func (r Rectangle) Edges() Edges {
|
||||||
vs := r.Vertices()
|
vs := r.Vertices()
|
||||||
return LineSegments{
|
return Edges{
|
||||||
LineSegment{vs[0], vs[1]},
|
Edge{vs[0], vs[1]},
|
||||||
LineSegment{vs[1], vs[2]},
|
Edge{vs[1], vs[2]},
|
||||||
LineSegment{vs[2], vs[3]},
|
Edge{vs[2], vs[3]},
|
||||||
LineSegment{vs[3], vs[0]},
|
Edge{vs[3], vs[0]},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +50,23 @@ func (r Rectangle) MakeTriangles() Triangles {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the rectangle contains the point.
|
// Check whether the rectangle contains the point.
|
||||||
func (r Rectangle) ContainsPoint(p Point) bool {
|
func (r Rectangle) ContainedPoints(pts Points) (Points) {
|
||||||
return r.MakeTriangles().ContainsPoint(p)
|
return r.MakeTriangles().ContainedPoints(pts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The type describes rectangle that can be drawn.
|
||||||
|
type DrawableRectangle struct {
|
||||||
|
Rectangle
|
||||||
|
ShaderOptions
|
||||||
|
|
||||||
|
// Solid color of the rectangle.
|
||||||
|
// Will be ignored if the Shader
|
||||||
|
// field is not nil.
|
||||||
|
Colority
|
||||||
|
|
||||||
|
// Should be draw or not.
|
||||||
|
Visibility
|
||||||
|
Collidability
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the drawable rectangle should be drawn.
|
// Check whether the drawable rectangle should be drawn.
|
||||||
|
|
12
size.go
Normal file
12
size.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package gg
|
||||||
|
|
||||||
|
// The type describes a simple
|
||||||
|
// rectangle without transformations.
|
||||||
|
type Size struct {
|
||||||
|
// The upper left corner position point.
|
||||||
|
Position Point
|
||||||
|
// Absolute width and height.
|
||||||
|
Width, Height Float
|
||||||
|
}
|
||||||
|
|
||||||
|
//type (s Size) ContainsPoint
|
|
@ -11,6 +11,8 @@ type Sprite struct {
|
||||||
ShaderOptions
|
ShaderOptions
|
||||||
Floating bool
|
Floating bool
|
||||||
Visibility
|
Visibility
|
||||||
|
Collidability
|
||||||
|
Resolvability
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
34
triangle.go
34
triangle.go
|
@ -15,7 +15,6 @@ type Vertex struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Triangle [3]Vector
|
type Triangle [3]Vector
|
||||||
type Triangles []Triangle
|
|
||||||
type DrawableTriangles struct {
|
type DrawableTriangles struct {
|
||||||
Triangles
|
Triangles
|
||||||
Colority
|
Colority
|
||||||
|
@ -53,9 +52,9 @@ func sqr(v Float) Float {
|
||||||
// Return squares of lengths of sides of the triangle.
|
// Return squares of lengths of sides of the triangle.
|
||||||
func (t Triangle) SideLengthSquares() ([3]Float) {
|
func (t Triangle) SideLengthSquares() ([3]Float) {
|
||||||
|
|
||||||
l1 := LineSegment{t[0], t[1]}.LenSqr()
|
l1 := Edge{t[0], t[1]}.LenSqr()
|
||||||
l2 := LineSegment{t[1], t[2]}.LenSqr()
|
l2 := Edge{t[1], t[2]}.LenSqr()
|
||||||
l3 := LineSegment{t[2], t[0]}.LenSqr()
|
l3 := Edge{t[2], t[0]}.LenSqr()
|
||||||
|
|
||||||
return [3]Float{l1, l2, l3}
|
return [3]Float{l1, l2, l3}
|
||||||
}
|
}
|
||||||
|
@ -72,19 +71,36 @@ func (t Triangle) ContainsPoint(p Point) bool {
|
||||||
return !(neg && pos)
|
return !(neg && pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t Triangle) ContainedPoints(pts Points) []Point {
|
||||||
|
ret := []Point{}
|
||||||
|
for i := range pts {
|
||||||
|
if t.ContainsPoint(pts[i]) {
|
||||||
|
ret = append(ret, pts[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (t Triangle) Sgn() Float {
|
func (t Triangle) Sgn() Float {
|
||||||
return (t[0].X - t[2].X) * (t[1].Y - t[2].Y) -
|
return (t[0].X - t[2].X) * (t[1].Y - t[2].Y) -
|
||||||
(t[1].X - t[2].X) * (t[0].Y - t[2].Y)
|
(t[1].X - t[2].X) * (t[0].Y - t[2].Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts Triangles) ContainsPoint(p Point) bool {
|
func (t Triangle) Vertices() Vertices {
|
||||||
for _, t := range ts {
|
return Vertices{
|
||||||
if t.ContainsPoint(p) {
|
t[0], t[1], t[2],
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
type Triangles []Triangle
|
||||||
|
|
||||||
|
func (ts Triangles) ContainedPoints(pts Points) (Points) {
|
||||||
|
ret := []Point{}
|
||||||
|
for _, t := range ts {
|
||||||
|
ps := t.ContainedPoints(pts)
|
||||||
|
ret = append(ret, ps...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex {
|
func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex {
|
||||||
|
|
|
@ -15,11 +15,7 @@ type Vector struct {
|
||||||
func (v Vector) XY() (Float, Float) {
|
func (v Vector) XY() (Float, Float) {
|
||||||
return v.X, v.Y
|
return v.X, v.Y
|
||||||
}
|
}
|
||||||
type Point = Vector
|
|
||||||
//type Vertex = Vector
|
|
||||||
|
|
||||||
type Vectors []Vector
|
type Vectors []Vector
|
||||||
type Points []Point
|
|
||||||
|
|
||||||
func V(x, y Float) Vector {
|
func V(x, y Float) Vector {
|
||||||
return Vector{x, y}
|
return Vector{x, y}
|
||||||
|
@ -94,11 +90,11 @@ func (v Vector) Norm() Vector {
|
||||||
return V(v.X / l, v.Y / l)
|
return V(v.X / l, v.Y / l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pts Points) Contained(c PointContainer) Points {
|
func (pts Points) ContainedIn(c PointContainer) Points {
|
||||||
ret := make([]Point, 0, len(pts))
|
ret := make([]Point, 0, len(pts))
|
||||||
|
|
||||||
for _, pt := range pts {
|
for _, pt := range pts {
|
||||||
if c.ContainsPoint(pt) {
|
if !c.ContainedPoints(Points{pt}).Empty() {
|
||||||
ret = append(ret, pt)
|
ret = append(ret, pt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
vertice.go
Normal file
5
vertice.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package gg
|
||||||
|
|
||||||
|
type Vertice = Point
|
||||||
|
type Vertices = []Vertice
|
||||||
|
|
Loading…
Reference in a new issue