automated snapshot

This commit is contained in:
sumi
2025-12-21 18:16:05 -06:00
parent deb020b5c8
commit 63fa362060
2 changed files with 86 additions and 98 deletions

62
main.go
View File

@@ -15,10 +15,17 @@ import (
const ( const (
targetWidth = 800 targetWidth = 800
targetHeight = 600 targetHeight = 600
sourceScale = 1 sourceScale = 10
snapshotsDir = "snapshots" snapshotsDir = "snapshots"
) )
type TextureCam struct {
SourceWidth int
SourceHeight int
LookAt rl.Vector2
Zoom float32
}
func main() { func main() {
sourceWidth := sourceScale * targetWidth sourceWidth := sourceScale * targetWidth
@@ -32,7 +39,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
rl.SetConfigFlags(rl.FlagWindowHighdpi & rl.FlagMsaa4xHint) rl.SetConfigFlags(rl.FlagMsaa4xHint)
rl.InitWindow(targetWidth, targetHeight, "sumi sierpinski arrow") rl.InitWindow(targetWidth, targetHeight, "sumi sierpinski arrow")
log.Printf("screen=%dx%d render=%dx%d", log.Printf("screen=%dx%d render=%dx%d",
@@ -42,11 +49,11 @@ func main() {
// point at source center // point at source center
// put source center at center of screen // put source center at center of screen
var camera = rl.Camera2D { var camera = TextureCam {
Target: rl.Vector2{X: float32(targetWidth) / 2, Y: float32(targetHeight) / 2}, LookAt: rl.Vector2 { X: float32(sourceWidth) / 2.0, Y: float32(sourceHeight) / 2.0 },
Offset: rl.Vector2{}, Zoom: 1.0,
Zoom: 1.0, SourceWidth: sourceWidth,
Rotation: 0, SourceHeight: sourceHeight,
} }
/* /*
@@ -85,7 +92,6 @@ func main() {
} }
for !rl.WindowShouldClose() { for !rl.WindowShouldClose() {
updateCamera(&camera)
// begin drawing // begin drawing
t := time.Since(t0).Seconds() t := time.Since(t0).Seconds()
@@ -98,9 +104,11 @@ func main() {
SourceHeight: int32(sourceHeight), SourceHeight: int32(sourceHeight),
Time: t, Time: t,
Ports: ports.Eval(t), Ports: ports.Eval(t),
Cam: camera, Cam: &camera,
} }
sketch.Update(renderCtx)
/** /**
MAIN DRAWING MAIN DRAWING
**/ **/
@@ -131,6 +139,7 @@ type FieldSketch struct {
Field Field Field Field
} }
/*
func (s *FieldSketch) Draw(ctx *RenderCtx) { func (s *FieldSketch) Draw(ctx *RenderCtx) {
fmt.Printf("drawing field") fmt.Printf("drawing field")
for x := range ctx.TargetWidth { for x := range ctx.TargetWidth {
@@ -143,6 +152,7 @@ func (s *FieldSketch) Draw(ctx *RenderCtx) {
} }
} }
} }
*/
type ContourLayer struct { type ContourLayer struct {
field Field field Field
@@ -196,40 +206,6 @@ func RandRadialVec(rng *rand.Rand, minRadius float32, maxRadius float32, loAngle
return rl.Vector2{X: float32(r * math.Cos(rad)), Y: float32(r * math.Sin(rad))} return rl.Vector2{X: float32(r * math.Cos(rad)), Y: float32(r * math.Sin(rad))}
} }
func updateCamera(camera *rl.Camera2D) {
// Get the world point that is under the mouse
mouseVec2 := rl.GetMousePosition()
if rl.IsMouseButtonDown(rl.MouseRightButton) {
// get mouse delta from last frame
delta := rl.GetMouseDelta()
// compute the amount to move scaled by the camera zoom
delta = rl.Vector2Scale(delta, -1.0/camera.Zoom)
delta.Y = -delta.Y
camera.Target = rl.Vector2Add(camera.Target, delta)
}
// Zoom based on mouse wheel
wheel := rl.GetMouseWheelMove()
if wheel != 0 {
mouseWorldPos := rl.GetScreenToWorld2D(mouseVec2, *camera)
// Set the offset to where the mouse is
camera.Offset = mouseVec2
// Set the target to match, so that the camera maps the world space point
// under the cursor to the screen space point under the cursor at any zoom
camera.Target = mouseWorldPos
// Zoom increment
const zoomIncrement float32 = 0.125
camera.Zoom += (wheel * zoomIncrement)
if camera.Zoom < zoomIncrement {
camera.Zoom = zoomIncrement
}
}
}
type Worm struct { type Worm struct {
position rl.Vector2 position rl.Vector2
angles []float32 angles []float32

120
sketch.go
View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
"fmt" "math"
"github.com/gen2brain/raylib-go/raylib" "github.com/gen2brain/raylib-go/raylib"
) )
@@ -10,36 +10,17 @@ type Sketch struct {
} }
func NewSketch() Sketch { func NewSketch() Sketch {
return Sketch { return Sketch{
layerTools: make(map[string]LayerTools), layerTools: make(map[string]LayerTools),
} }
} }
func (s *Sketch) CreateLayer(name string, layer Layer, sourceWidth int32, sourceHeight int32) { func (s *Sketch) CreateLayer(name string, layer Layer, sourceWidth int32, sourceHeight int32) {
texture := rl.LoadRenderTexture(sourceWidth, sourceHeight) texture := rl.LoadRenderTexture(sourceWidth, sourceHeight)
s.layerTools[name] = LayerTools { s.layerTools[name] = LayerTools{
name: name, name: name,
texture: &texture, texture: &texture,
layer: layer, layer: layer,
}
}
func LayerViewRect(ctx *RenderCtx) rl.Rectangle {
z := ctx.Cam.Zoom
// get the viewport width in texture space
viewportWidth := float32(ctx.TargetWidth) / z
viewportHeight := float32(ctx.TargetHeight) / z
x := rl.Clamp(ctx.Cam.Target.X - viewportWidth/2, 0, float32(ctx.SourceWidth) - viewportWidth/2.0)
y := rl.Clamp(ctx.Cam.Target.Y - viewportHeight/2, 0, float32(ctx.SourceHeight) - viewportHeight/2.0)
return rl.Rectangle{
X: x,
Y: y,
Width: viewportWidth,
Height: viewportHeight,
} }
} }
@@ -52,36 +33,68 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
layer.Draw(ctx) layer.Draw(ctx)
rl.EndTextureMode() rl.EndTextureMode()
} }
// composite all layers to screen // composite all layers to screen
//ClampCameraToLayer(ctx) screen := rl.Rectangle {
X: 0,
//view := LayerViewRect(ctx) Y: 0,
src := rl.Rectangle { Width: float32(ctx.TargetWidth),
X: 0,
Y: 0,
Width: float32(ctx.SourceWidth),
Height: -float32(ctx.SourceHeight),
}
dst := rl.Rectangle {
X: 0,
Y: 0,
Width: float32(ctx.TargetWidth),
Height: float32(ctx.TargetHeight), Height: float32(ctx.TargetHeight),
} }
fmt.Printf("src = %v, dst %v\n", src, dst) viewport := s.CalcViewport(ctx)
for _, instance := range s.layerTools { for _, instance := range s.layerTools {
rl.DrawTexturePro(instance.texture.Texture, src, dst, rl.Vector2{}, 0, rl.White) rl.DrawTexturePro(instance.texture.Texture, viewport, screen, rl.Vector2{}, 0, rl.White)
} }
} }
func (s *Sketch) CalcViewport(ctx *RenderCtx) rl.Rectangle {
viewportWidth := rl.Clamp(float32(ctx.SourceWidth) / ctx.Cam.Zoom, 0, float32(ctx.SourceWidth))
viewportHeight := rl.Clamp(float32(ctx.SourceHeight) / ctx.Cam.Zoom, 0, float32(ctx.SourceHeight))
return rl.Rectangle{
X: rl.Clamp(ctx.Cam.LookAt.X - viewportWidth/2.0, 0, float32(ctx.SourceWidth)-viewportWidth),
Y: rl.Clamp(ctx.Cam.LookAt.Y - viewportHeight/2.0, 0, float32(ctx.SourceHeight)-viewportHeight),
Width: float32(viewportWidth),
Height: -float32(viewportHeight),
}
}
func (s *Sketch) Update(ctx *RenderCtx) {
if rl.IsMouseButtonDown(rl.MouseRightButton) {
// get mouse delta from last frame
delta := rl.GetMouseDelta()
// compute the amount to move scaled by the camera zoom
delta = rl.Vector2Scale(delta, -sourceScale/ctx.Cam.Zoom)
delta.Y = -delta.Y
ctx.Cam.LookAt = rl.Vector2Add(ctx.Cam.LookAt, delta)
}
// clamp LookAt to be somewhere on the texture
ctx.Cam.LookAt.X = rl.Clamp(ctx.Cam.LookAt.X, 0, float32(ctx.SourceWidth-1))
ctx.Cam.LookAt.Y = rl.Clamp(ctx.Cam.LookAt.Y, 0, float32(ctx.SourceHeight-1))
// Zoom based on mouse wheel
wheel := rl.GetMouseWheelMove()
if wheel != 0 {
const zoomIncrement float32 = 0.05
if wheel > 0 {
ctx.Cam.Zoom *= 1+zoomIncrement
} else {
ctx.Cam.Zoom *= 1-zoomIncrement
}
}
// clamp zoom to > 1 so we don't ever zoom out more than necessary
ctx.Cam.Zoom = rl.Clamp(ctx.Cam.Zoom, 1, math.MaxInt64)
}
type LayerTools struct { type LayerTools struct {
name string name string
layer Layer layer Layer
texture *rl.RenderTexture2D texture *rl.RenderTexture2D
} }
@@ -91,7 +104,7 @@ type Layer interface {
Draw(ctx *RenderCtx) Draw(ctx *RenderCtx)
} }
type TestPattern struct { } type TestPattern struct{}
func DrawGrid(spacing int32, halfExtent int32) { func DrawGrid(spacing int32, halfExtent int32) {
col := rl.Color{R: 220, G: 220, B: 220, A: 255} col := rl.Color{R: 220, G: 220, B: 220, A: 255}
@@ -107,13 +120,13 @@ func DrawGrid(spacing int32, halfExtent int32) {
func (tp *TestPattern) Draw(ctx *RenderCtx) { func (tp *TestPattern) Draw(ctx *RenderCtx) {
rl.ClearBackground(rl.Black) rl.ClearBackground(rl.Black)
centerX := float32(ctx.SourceWidth)/2 centerX := float32(ctx.SourceWidth) / 2
centerY := float32(ctx.SourceHeight)/2 centerY := float32(ctx.SourceHeight) / 2
rl.DrawRectangleRec(rl.Rectangle { X: 0, Y: 0, Width: centerX, Height: centerY }, rl.Red) rl.DrawRectangleRec(rl.Rectangle{X: 0, Y: 0, Width: centerX, Height: centerY}, rl.Red)
rl.DrawRectangleRec(rl.Rectangle { X: centerX, Y: 0, Width: centerX, Height: centerY }, rl.Green) rl.DrawRectangleRec(rl.Rectangle{X: centerX, Y: 0, Width: centerX, Height: centerY}, rl.Green)
rl.DrawRectangleRec(rl.Rectangle { X: 0, Y: centerY, Width: centerX, Height: centerY }, rl.Blue) rl.DrawRectangleRec(rl.Rectangle{X: 0, Y: centerY, Width: centerX, Height: centerY}, rl.Blue)
rl.DrawRectangleRec(rl.Rectangle { X: centerX, Y: centerY, Width: centerX, Height: centerY }, rl.White) rl.DrawRectangleRec(rl.Rectangle{X: centerX, Y: centerY, Width: centerX, Height: centerY}, rl.White)
rl.DrawLine(0, 0, ctx.SourceWidth, ctx.SourceHeight, rl.Black) rl.DrawLine(0, 0, ctx.SourceWidth, ctx.SourceHeight, rl.Black)
@@ -126,7 +139,6 @@ func (tp *TestPattern) Draw(ctx *RenderCtx) {
rl.PopMatrix() rl.PopMatrix()
} }
/** Ports **/ /** Ports **/
type Ports map[string]Signal type Ports map[string]Signal
@@ -151,9 +163,9 @@ func (p Ports) Eval(t float64) map[string]float64 {
type RenderCtx struct { type RenderCtx struct {
TargetWidth int32 TargetWidth int32
TargetHeight int32 TargetHeight int32
SourceWidth int32 SourceWidth int32
SourceHeight int32 SourceHeight int32
Time float64 Time float64
Ports map[string]float64 Ports map[string]float64
Cam rl.Camera2D Cam *TextureCam
} }