automated snapshot
This commit is contained in:
@@ -97,6 +97,7 @@
|
|||||||
# Helps CGO find headers/libs
|
# Helps CGO find headers/libs
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export CGO_ENABLED=1
|
export CGO_ENABLED=1
|
||||||
|
export XDG_SESSION_TYPE=x11
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
138
main.go
138
main.go
@@ -27,13 +27,14 @@ func GrayCurve(v, k float64) rl.Color {
|
|||||||
return rl.Color{R: c, G: c, B: c, A: 255}
|
return rl.Color{R: c, G: c, B: c, A: 255}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
const (
|
||||||
|
screenWidth = 1400
|
||||||
|
screenHeight = 700
|
||||||
|
displayScale = 2
|
||||||
|
snapshotsDir = "snapshots"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
func main() {
|
||||||
screenWidth = 1200
|
|
||||||
screenHeight = 700
|
|
||||||
snapshotsDir = "snapshots"
|
|
||||||
)
|
|
||||||
|
|
||||||
os.MkdirAll(snapshotsDir, 0755)
|
os.MkdirAll(snapshotsDir, 0755)
|
||||||
|
|
||||||
@@ -45,15 +46,42 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rl.SetConfigFlags(rl.FlagWindowHighdpi)
|
||||||
rl.InitWindow(screenWidth, screenHeight, "sumi sierpinski arrow")
|
rl.InitWindow(screenWidth, screenHeight, "sumi sierpinski arrow")
|
||||||
|
|
||||||
sketches := []Sketch {
|
log.Printf("screen=%dx%d render=%dx%d",
|
||||||
SierpinskiArrow{},
|
rl.GetScreenWidth(), rl.GetScreenHeight(),
|
||||||
|
rl.GetRenderWidth(), rl.GetRenderHeight(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
w := rl.GetRenderWidth()
|
||||||
|
h := rl.GetRenderHeight()
|
||||||
|
|
||||||
|
angles := make([]float32, 1000)
|
||||||
|
noise := opensimplex.NewNormalized(0)
|
||||||
|
r := 0.75
|
||||||
|
dtheta := 360.0/float64(len(angles))
|
||||||
|
for i := range len(angles) {
|
||||||
|
rad := float64(i) * dtheta * math.Pi / 180.0
|
||||||
|
x := r * math.Cos(rad)
|
||||||
|
y := r * math.Sin(rad)
|
||||||
|
angles[i] = float32(noise.Eval2(x, y) * 360.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
sketches := []Sketch{
|
||||||
|
&SierpinskiArrow{},
|
||||||
|
&Worm{
|
||||||
|
position: rl.Vector2 { X: 50, Y: 50 },
|
||||||
|
angles: angles,
|
||||||
|
angleIndex: 0,
|
||||||
|
stepSize: 2,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var camera = rl.Camera2D{
|
var camera = rl.Camera2D{
|
||||||
Target: rl.Vector2{X: 0, Y: 0},
|
Target: rl.Vector2{X: 0, Y: 0},
|
||||||
Offset: rl.Vector2{X: float32(screenWidth) / 2, Y: float32(screenHeight) / 2},
|
Offset: rl.Vector2{X: float32(w) / 2, Y: float32(h) / 2},
|
||||||
Rotation: 0,
|
Rotation: 0,
|
||||||
Zoom: 1.0,
|
Zoom: 1.0,
|
||||||
}
|
}
|
||||||
@@ -63,13 +91,18 @@ func main() {
|
|||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
|
|
||||||
ports := MakePorts()
|
ports := MakePorts()
|
||||||
ports["sierpinskiArrowLength"] = Sine {
|
ports["sierpinskiArrowLength"] = Const{
|
||||||
Amp: 1000.0,
|
V: 1200,
|
||||||
Freq: 0.001,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ports["sierpinskiArrowDepth"] = Saw {
|
ports["sierpinskiArrowDepth"] = Const{
|
||||||
Min: 1, Max: 9, Period: 10,
|
V: 7,
|
||||||
|
}
|
||||||
|
|
||||||
|
ports["sierpinskiArrowAngle"] = Sine{
|
||||||
|
Amp: 120,
|
||||||
|
Bias: 100,
|
||||||
|
Freq: 0.1,
|
||||||
}
|
}
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
@@ -79,23 +112,25 @@ func main() {
|
|||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
rl.BeginMode2D(camera)
|
rl.BeginMode2D(camera)
|
||||||
rl.PushMatrix()
|
|
||||||
|
|
||||||
t := time.Since(t0).Seconds()
|
t := time.Since(t0).Seconds()
|
||||||
|
|
||||||
// set up RenderCtx
|
// set up RenderCtx
|
||||||
renderCtx := &RenderCtx {
|
renderCtx := &RenderCtx{
|
||||||
Width: screenWidth,
|
Width: int32(w),
|
||||||
Height: screenHeight,
|
Height: int32(h),
|
||||||
Time: t,
|
Time: t,
|
||||||
Ports: ports.Eval(t),
|
Ports: ports.Eval(t),
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
MAIN DRAWING
|
MAIN DRAWING
|
||||||
**/
|
**/
|
||||||
|
|
||||||
for _, s := range sketches {
|
for _, s := range sketches {
|
||||||
|
rl.PushMatrix()
|
||||||
s.Draw(renderCtx)
|
s.Draw(renderCtx)
|
||||||
|
rl.PopMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
if rl.IsKeyDown(rl.KeySpace) {
|
if rl.IsKeyDown(rl.KeySpace) {
|
||||||
@@ -104,11 +139,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.PopMatrix()
|
|
||||||
rl.EndMode2D()
|
rl.EndMode2D()
|
||||||
|
|
||||||
|
rl.DrawLine(10, 10, int32(w-10), int32(h-10), rl.Black)
|
||||||
|
|
||||||
// HUD
|
// HUD
|
||||||
rl.DrawText("Mouse right button drag to move, mouse wheel to zoom", 10, 10, 20, rl.White)
|
rl.DrawText("Mouse right button drag to move, mouse wheel to zoom", 10, 10, 20, rl.Black)
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,19 +152,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateCamera(camera *rl.Camera2D) {
|
func updateCamera(camera *rl.Camera2D) {
|
||||||
|
// Get the world point that is under the mouse
|
||||||
|
mouseVec2 := rl.GetMousePosition()
|
||||||
|
|
||||||
if rl.IsMouseButtonDown(rl.MouseRightButton) {
|
if rl.IsMouseButtonDown(rl.MouseRightButton) {
|
||||||
|
// get mouse delta from last frame
|
||||||
delta := rl.GetMouseDelta()
|
delta := rl.GetMouseDelta()
|
||||||
|
// compute the amount to move scaled by the camera zoom
|
||||||
delta = rl.Vector2Scale(delta, -1.0/camera.Zoom)
|
delta = rl.Vector2Scale(delta, -1.0/camera.Zoom)
|
||||||
camera.Target = rl.Vector2Add(camera.Target, delta)
|
camera.Target = rl.Vector2Add(camera.Target, delta)
|
||||||
}
|
}
|
||||||
// Zoom based on mouse wheel
|
// Zoom based on mouse wheel
|
||||||
wheel := rl.GetMouseWheelMove()
|
wheel := rl.GetMouseWheelMove()
|
||||||
if wheel != 0 {
|
if wheel != 0 {
|
||||||
// Get the world point that is under the mouse
|
mouseWorldPos := rl.GetScreenToWorld2D(mouseVec2, *camera)
|
||||||
mouseWorldPos := rl.GetScreenToWorld2D(rl.GetMousePosition(), *camera)
|
|
||||||
|
|
||||||
// Set the offset to where the mouse is
|
// Set the offset to where the mouse is
|
||||||
camera.Offset = rl.GetMousePosition()
|
camera.Offset = mouseVec2
|
||||||
|
|
||||||
// Set the target to match, so that the camera maps the world space point
|
// 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
|
// under the cursor to the screen space point under the cursor at any zoom
|
||||||
@@ -144,22 +184,41 @@ func updateCamera(camera *rl.Camera2D) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Worm struct {
|
||||||
|
position rl.Vector2
|
||||||
|
angles []float32
|
||||||
|
angleIndex int
|
||||||
|
stepSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Worm) Draw(ctx *RenderCtx) {
|
||||||
type SierpinskiArrow struct {}
|
|
||||||
|
|
||||||
func (s SierpinskiArrow) Draw(ctx *RenderCtx) {
|
|
||||||
rl.PushMatrix()
|
rl.PushMatrix()
|
||||||
sierpinskiArrow(ctx, int(ctx.Ports["sierpinskiArrowDepth"]), ctx.Ports["sierpinskiArrowLength"])
|
rl.Translatef(w.position.X, w.position.Y, 0)
|
||||||
|
lastAngle := float32(0.0)
|
||||||
|
for i := range w.angles {
|
||||||
|
ii := (i + w.angleIndex) % len(w.angles)
|
||||||
|
angle := w.angles[ii]
|
||||||
|
rl.Rotatef(angle - lastAngle, 0, 0, 1)
|
||||||
|
rl.DrawLine(0, 0, int32(w.stepSize), 0, rl.Black)
|
||||||
|
rl.Translatef(float32(w.stepSize), 0, 0)
|
||||||
|
lastAngle = angle
|
||||||
|
}
|
||||||
rl.PopMatrix()
|
rl.PopMatrix()
|
||||||
|
w.angleIndex = (w.angleIndex + 1) % len(w.angles)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SierpinskiArrow struct{}
|
||||||
|
|
||||||
|
func (s *SierpinskiArrow) Draw(ctx *RenderCtx) {
|
||||||
|
sierpinskiArrow(ctx, int(ctx.Ports["sierpinskiArrowDepth"]), ctx.Ports["sierpinskiArrowLength"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func sierpinskiArrow(ctx *RenderCtx, order int, length float64) {
|
func sierpinskiArrow(ctx *RenderCtx, order int, length float64) {
|
||||||
if order == 0 {
|
if order == 0 {
|
||||||
curve(ctx, order, length, 60)
|
curve(ctx, order, length, ctx.Ports["sierpinskiArrowAngle"])
|
||||||
} else {
|
} else {
|
||||||
rl.Rotatef(60, 0, 0, 1)
|
rl.Rotatef(float32(ctx.Ports["sierpinskiArrowAngle"]), 0, 0, 1)
|
||||||
curve(ctx, order, length, -60)
|
curve(ctx, order, length, -ctx.Ports["sierpinskiArrowAngle"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +226,7 @@ func curve(ctx *RenderCtx, order int, length float64, angle float64) {
|
|||||||
if order == 0 {
|
if order == 0 {
|
||||||
len := int32(length)
|
len := int32(length)
|
||||||
rl.DrawLine(0, 0, len, 0, rl.Black)
|
rl.DrawLine(0, 0, len, 0, rl.Black)
|
||||||
rl.Translatef(float32(len), 0, 0)
|
rl.Translatef(float32(length), 0, 0)
|
||||||
} else {
|
} else {
|
||||||
curve(ctx, order-1, length/2, -angle)
|
curve(ctx, order-1, length/2, -angle)
|
||||||
rl.Rotatef(float32(angle), 0, 0, 1)
|
rl.Rotatef(float32(angle), 0, 0, 1)
|
||||||
@@ -183,25 +242,16 @@ func main2() {
|
|||||||
for i := range len(angles) {
|
for i := range len(angles) {
|
||||||
angles[i] = float32(noise.Eval2(float64(i)*0.05, 0.00))*0.1 - 0.05
|
angles[i] = float32(noise.Eval2(float64(i)*0.05, 0.00))*0.1 - 0.05
|
||||||
}
|
}
|
||||||
|
|
||||||
frameNum := 0
|
frameNum := 0
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
|
|
||||||
frameNum++
|
frameNum++
|
||||||
|
|
||||||
// initial transform by halfway again through angle array
|
// initial transform by halfway again through angle array
|
||||||
|
angleIndex := (frameNum / 10) % len(angles)
|
||||||
angleIndex := (frameNum/10) % len(angles)
|
|
||||||
angle := angles[angleIndex]
|
angle := angles[angleIndex]
|
||||||
|
|
||||||
initAngle := angles[(angleIndex+len(angles)/2)%len(angles)]
|
initAngle := angles[(angleIndex+len(angles)/2)%len(angles)]
|
||||||
rl.Rotatef(2500*initAngle, 0, 0, 1)
|
rl.Rotatef(2500*initAngle, 0, 0, 1)
|
||||||
rl.Translatef(100*initAngle, 100*initAngle, 0)
|
rl.Translatef(100*initAngle, 100*initAngle, 0)
|
||||||
|
|
||||||
fmt.Printf("%.3f", angle)
|
fmt.Printf("%.3f", angle)
|
||||||
|
|
||||||
rl.EndMode2D()
|
rl.EndMode2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ type Signal interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Const struct{ V float64 }
|
type Const struct{ V float64 }
|
||||||
|
|
||||||
func (s Const) Eval(t float64) float64 { return s.V }
|
func (s Const) Eval(t float64) float64 { return s.V }
|
||||||
|
|
||||||
type Sine struct {
|
type Sine struct {
|
||||||
Amp, Freq, Phase, Bias float64
|
Amp, Freq, Phase, Bias float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Sine) Eval(t float64) float64 {
|
func (s Sine) Eval(t float64) float64 {
|
||||||
return s.Bias + s.Amp*math.Sin(2*math.Pi*s.Freq*t+s.Phase)
|
return s.Bias + s.Amp*math.Sin(2*math.Pi*s.Freq*t+s.Phase)
|
||||||
}
|
}
|
||||||
@@ -21,8 +23,8 @@ func (s Sine) Eval(t float64) float64 {
|
|||||||
type Saw struct {
|
type Saw struct {
|
||||||
Min, Max, Period float64
|
Min, Max, Period float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Saw) Eval(t float64) float64 {
|
func (s Saw) Eval(t float64) float64 {
|
||||||
u := math.Mod(t, s.Period) / s.Period // 0..1
|
u := math.Mod(t, s.Period) / s.Period // 0..1
|
||||||
return s.Min + (s.Max-s.Min)*u
|
return s.Min + (s.Max-s.Min)*u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
sketch.go
11
sketch.go
@@ -21,7 +21,7 @@ func MakePorts() Ports {
|
|||||||
**/
|
**/
|
||||||
func (p Ports) Eval(t float64) map[string]float64 {
|
func (p Ports) Eval(t float64) map[string]float64 {
|
||||||
out := make(map[string]float64, len(p))
|
out := make(map[string]float64, len(p))
|
||||||
for name, sig := range(p) {
|
for name, sig := range p {
|
||||||
out[name] = sig.Eval(t)
|
out[name] = sig.Eval(t)
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
@@ -30,10 +30,9 @@ func (p Ports) Eval(t float64) map[string]float64 {
|
|||||||
/** RenderCtx **/
|
/** RenderCtx **/
|
||||||
|
|
||||||
type RenderCtx struct {
|
type RenderCtx struct {
|
||||||
Width int32
|
Width int32
|
||||||
Height int32
|
Height int32
|
||||||
Time float64
|
Time float64
|
||||||
Ports map[string]float64
|
Ports map[string]float64
|
||||||
Cam rl.Camera2D
|
Cam rl.Camera2D
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
storage.go
26
storage.go
@@ -2,25 +2,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"github.com/d2fn/sumi/internal/ids"
|
"github.com/d2fn/sumi/internal/ids"
|
||||||
"github.com/go-git/go-git/v6"
|
"github.com/go-git/go-git/v6"
|
||||||
|
"log"
|
||||||
//"github.com/go-git/go-git/v5/plumbing"
|
//"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-git/go-git/v6/plumbing/object"
|
"database/sql"
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"github.com/gen2brain/raylib-go/raylib"
|
||||||
|
"github.com/go-git/go-git/v6/plumbing/object"
|
||||||
|
_ "modernc.org/sqlite" // pure Go, Nix-friendly
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
"database/sql"
|
|
||||||
_ "modernc.org/sqlite" // pure Go, Nix-friendly
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
repoRoot string
|
repoRoot string
|
||||||
snapshotsDir string
|
snapshotsDir string
|
||||||
gen *ids.Generator
|
gen *ids.Generator
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
log *log.Logger
|
log *log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStorage(snapshotsDir string) (*Storage, error) {
|
func NewStorage(snapshotsDir string) (*Storage, error) {
|
||||||
@@ -30,12 +30,12 @@ func NewStorage(snapshotsDir string) (*Storage, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s := Storage {
|
s := Storage{
|
||||||
repoRoot: ".",
|
repoRoot: ".",
|
||||||
snapshotsDir: snapshotsDir,
|
snapshotsDir: snapshotsDir,
|
||||||
gen: gen,
|
gen: gen,
|
||||||
db: db,
|
db: db,
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
return &s, nil
|
return &s, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user