<commit_before>package logic

import (
	"github.com/tajtiattila/joyster/block"
	"math"
)

func init() {
	block.RegisterParam("headlook", func(p block.Param) (block.Block, error) {
		return newHeadlook(p), nil
	})
	block.RegisterParam("triggeraxis", func(p block.Param) (block.Block, error) {
		return newTriggerAxis(p), nil
	})
}

type viewaccumulatelogic struct {
	movepertick    float64
	jumppertick    float64
	acapertick     float64
	autocenterdist float64

	enable *bool
	xi, yi *float64
	x, y   float64
	s      float64
}

func newHeadlook(p block.Param) *viewaccumulatelogic {
	dt := p.TickTime()
	l := new(viewaccumulatelogic)
	l.acapertick = p.Arg("AutoCenterAccel") * dt
	l.autocenterdist = p.Arg("AutoCenterDist")
	l.movepertick = p.Arg("MovePerSec") * dt
	l.jumppertick = p.Arg("JumpToCenterAccel") * dt
	if l.acapertick <= 0.0 {
		l.acapertick = 1
	}
	if l.jumppertick <= 0.0 {
		l.jumppertick = 1
	}
	return l
}

func (l *viewaccumulatelogic) Input() block.InputMap {
	return block.MapInput("headlook",
		pt("enable", &l.enable),
		pt("x", &l.xi),
		pt("y", &l.yi),
	)
}

func (l *viewaccumulatelogic) Output() block.OutputMap {
	return block.MapOutput("headlook",
		pt("x", &l.x),
		pt("y", &l.y),
	)
}

func (l *viewaccumulatelogic) Validate() error {
	return block.CheckInputs("headlook", &l.enable, &l.xi, &l.yi)
}

func (l *viewaccumulatelogic) Tick() {
	if *l.enable {
		xv, yv := float64(*l.xi), float64(*l.yi)
		if tiny(xv) && tiny(yv) {
			l.centeraccel(l.acapertick, l.autocenterdist)
		} else {
			l.x += xv * l.movepertick
			l.y += yv * l.movepertick
			if l.x < -1 {
				l.x = -1
			}
			if 1 < l.x {
				l.x = 1
			}
			if l.y < -1 {
				l.y = -1
			}
			if 1 < l.y {
				l.y = 1
			}
			l.s = 0
		}
	} else {
		l.centeraccel(l.jumppertick, 1e6)
	}
}

func (l *viewaccumulatelogic) centeraccel(a, limit float64) {
	// d=a/2*t²
	d := math.Sqrt(l.x*l.x + l.y*l.y)
	switch {
	case d < 1e-6:
		l.x, l.y, l.s = 0, 0, 0
	case d < limit:
		t := math.Sqrt(2 * d / a)
		maxs := a * t
		l.s += a
		if l.s > maxs {
			l.s = maxs
		}
		m := 1 - l.s/d
		if m < 0 {
			m = 0
		}
		l.x *= m
		l.y *= m
	}
}

type triggeraxis struct {
	axisThreshold  float64
	breakThreshold float64
	exp            float64
	m              float64

	left, right *float64

	brk bool
	pos float64
}

func newTriggerAxis(p block.Param) block.Block {
	at := p.Arg("AxisThreshold")
	bt := p.Arg("BreakThreshold")
	exp := p.Arg("Exp")
	m := 1 - at
	return &triggeraxis{
		axisThreshold:  at,
		breakThreshold: bt,
		exp:            exp,
		m:              m,
	}
}

func (t *triggeraxis) Input() block.InputMap {
	return block.MapInput("triggeraxis",
		pt("left", &t.left),
		pt("right", &t.right),
	)
}

func (t *triggeraxis) Output() block.OutputMap {
	return block.MapOutput("triggeraxis",
		pt("", &t.pos),
		pt("break", &t.brk),
	)
}

func (t *triggeraxis) Validate() error { return block.CheckInputs("triggeraxis", &t.left, &t.right) }

func (t *triggeraxis) Tick() {
	lv, rv := *t.left, *t.right
	lx, ly := lv > t.breakThreshold, rv > t.breakThreshold
	if lx == ly {
		t.brk = lx
		t.pos = 0
	} else {
		t.brk = false
		t.pos = t.triggervalue(rv) - t.triggervalue(lv)
	}
}

func (t *triggeraxis) triggervalue(v float64) float64 {
	vv := v - t.axisThreshold
	if v <= 0 {
		return 0
	}
	return math.Pow(vv*t.m, t.exp)
}

func tiny(v float64) bool {
	const rounderr = 1e-4
	return -rounderr < v && v < rounderr
}<commit_msg>triggeraxis: fix result not approaching 1.0<commit_after>package logic

import (
	"github.com/tajtiattila/joyster/block"
	"math"
)

func init() {
	block.RegisterParam("headlook", func(p block.Param) (block.Block, error) {
		return newHeadlook(p), nil
	})
	block.RegisterParam("triggeraxis", func(p block.Param) (block.Block, error) {
		return newTriggerAxis(p), nil
	})
}

type viewaccumulatelogic struct {
	movepertick    float64
	jumppertick    float64
	acapertick     float64
	autocenterdist float64

	enable *bool
	xi, yi *float64
	x, y   float64
	s      float64
}

func newHeadlook(p block.Param) *viewaccumulatelogic {
	dt := p.TickTime()
	l := new(viewaccumulatelogic)
	l.acapertick = p.Arg("AutoCenterAccel") * dt
	l.autocenterdist = p.Arg("AutoCenterDist")
	l.movepertick = p.Arg("MovePerSec") * dt
	l.jumppertick = p.Arg("JumpToCenterAccel") * dt
	if l.acapertick <= 0.0 {
		l.acapertick = 1
	}
	if l.jumppertick <= 0.0 {
		l.jumppertick = 1
	}
	return l
}

func (l *viewaccumulatelogic) Input() block.InputMap {
	return block.MapInput("headlook",
		pt("enable", &l.enable),
		pt("x", &l.xi),
		pt("y", &l.yi),
	)
}

func (l *viewaccumulatelogic) Output() block.OutputMap {
	return block.MapOutput("headlook",
		pt("x", &l.x),
		pt("y", &l.y),
	)
}

func (l *viewaccumulatelogic) Validate() error {
	return block.CheckInputs("headlook", &l.enable, &l.xi, &l.yi)
}

func (l *viewaccumulatelogic) Tick() {
	if *l.enable {
		xv, yv := float64(*l.xi), float64(*l.yi)
		if tiny(xv) && tiny(yv) {
			l.centeraccel(l.acapertick, l.autocenterdist)
		} else {
			l.x += xv * l.movepertick
			l.y += yv * l.movepertick
			if l.x < -1 {
				l.x = -1
			}
			if 1 < l.x {
				l.x = 1
			}
			if l.y < -1 {
				l.y = -1
			}
			if 1 < l.y {
				l.y = 1
			}
			l.s = 0
		}
	} else {
		l.centeraccel(l.jumppertick, 1e6)
	}
}

func (l *viewaccumulatelogic) centeraccel(a, limit float64) {
	// d=a/2*t²
	d := math.Sqrt(l.x*l.x + l.y*l.y)
	switch {
	case d < 1e-6:
		l.x, l.y, l.s = 0, 0, 0
	case d < limit:
		t := math.Sqrt(2 * d / a)
		maxs := a * t
		l.s += a
		if l.s > maxs {
			l.s = maxs
		}
		m := 1 - l.s/d
		if m < 0 {
			m = 0
		}
		l.x *= m
		l.y *= m
	}
}

type triggeraxis struct {
	axisThreshold  float64
	breakThreshold float64
	exp            float64
	m              float64

	left, right *float64

	brk bool
	pos float64
}

func newTriggerAxis(p block.Param) block.Block {
	at := p.Arg("AxisThreshold")
	bt := p.Arg("BreakThreshold")
	exp := p.Arg("Exp")
	m := 1 / (1 - at)
	return &triggeraxis{
		axisThreshold:  at,
		breakThreshold: bt,
		exp:            exp,
		m:              m,
	}
}

func (t *triggeraxis) Input() block.InputMap {
	return block.MapInput("triggeraxis",
		pt("left", &t.left),
		pt("right", &t.right),
	)
}

func (t *triggeraxis) Output() block.OutputMap {
	return block.MapOutput("triggeraxis",
		pt("", &t.pos),
		pt("break", &t.brk),
	)
}

func (t *triggeraxis) Validate() error { return block.CheckInputs("triggeraxis", &t.left, &t.right) }

func (t *triggeraxis) Tick() {
	lv, rv := *t.left, *t.right
	lx, ly := lv > t.breakThreshold, rv > t.breakThreshold
	if lx == ly {
		t.brk = lx
		t.pos = 0
	} else {
		t.brk = false
		t.pos = t.triggervalue(rv) - t.triggervalue(lv)
	}
}

func (t *triggeraxis) triggervalue(v float64) float64 {
	vv := v - t.axisThreshold
	if vv <= 0 {
		return 0
	}
	return math.Pow(vv*t.m, t.exp)
}

func tiny(v float64) bool {
	const rounderr = 1e-4
	return -rounderr < v && v < rounderr
}
{'fraction_non_alphanumeric': 0.16673947866608418, 'fraction_numerical': 0.021115479831076162, 'mean_word_length': 2.8540965207631874, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4515880', 'n_tokens_mistral': 3266, 'n_tokens_neox': 3019, 'n_words': 672}