-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathselect.go
More file actions
88 lines (76 loc) · 3.2 KB
/
select.go
File metadata and controls
88 lines (76 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package noiselib
type Select struct {
SourceModule []Module
LowerBound, UpperBound, EdgeFalloff float64
}
const DefaultSelectEdgeFalloff = 0.0
const DefaultSelectLowerBound = -1.0
const DefaultSelectUpperBound = 1.0
func (s Select) GetSourceModule(index int) Module {
return s.SourceModule[index]
}
func (s Select) SetSourceModule(index int, source Module) {
s.SourceModule[index] = source
}
func (s Select) GetValue(x, y, z float64) float64 {
if s.SourceModule[0] == nil || s.SourceModule[1] == nil || s.SourceModule[2] == nil {
panic("Select requires 3 source modules.")
}
controlValue := s.SourceModule[2].GetValue(x, y, z)
if s.EdgeFalloff > 0.0 {
if controlValue < (s.LowerBound - s.EdgeFalloff) {
// The output value from the control module is below the selector
// threshold; return the output value from the first source module.
return s.SourceModule[0].GetValue(x, y, z)
} else if controlValue < (s.LowerBound + s.EdgeFalloff) {
// The output value from the control module is near the lower end of the
// selector threshold and within the smooth curve. Interpolate between
// the output values from the first and second source modules.
lowerCurve := (s.LowerBound - s.EdgeFalloff)
upperCurve := (s.LowerBound + s.EdgeFalloff)
alpha := SCurve3((controlValue - lowerCurve) / (upperCurve - lowerCurve))
return LinearInterp(s.SourceModule[0].GetValue(x, y, z), s.SourceModule[1].GetValue(x, y, z), alpha)
} else if controlValue < s.UpperBound-s.EdgeFalloff {
//The output value from the contorl module is within the selector
// threshold; return the output value from the second source module.
return s.SourceModule[1].GetValue(x, y, z)
} else if controlValue < s.UpperBound+s.EdgeFalloff {
//The output value from the control module is near the upper end of the
// selector threshold and within the smooth curve. Interpolate between
// the output values from the first and second source modules.
lowerCurve := (s.UpperBound - s.EdgeFalloff)
upperCurve := (s.UpperBound + s.EdgeFalloff)
alpha := SCurve3((controlValue - lowerCurve) / (upperCurve - lowerCurve))
return LinearInterp(s.SourceModule[1].GetValue(x, y, z), s.SourceModule[0].GetValue(x, y, z), alpha)
} else {
// Output value from the contorl module is above the selector threshold;
// return the output value from the first soruce module
return s.SourceModule[0].GetValue(x, y, z)
}
} else {
if controlValue < s.LowerBound || controlValue > s.UpperBound {
return s.SourceModule[0].GetValue(x, y, z)
} else {
return s.SourceModule[1].GetValue(x, y, z)
}
}
}
func (s *Select) SetBounds(lowerBound, upperBound float64) {
if lowerBound > upperBound {
panic("LowerBound in Select must be lower than UpperBound")
}
s.LowerBound = lowerBound
s.UpperBound = upperBound
s.SetEdgeFalloff(s.EdgeFalloff)
}
func (s *Select) SetEdgeFalloff(edgeFalloff float64) {
boundSize := s.UpperBound - s.LowerBound
if edgeFalloff > (boundSize / 2) {
s.EdgeFalloff = (boundSize / 2)
} else {
s.EdgeFalloff = edgeFalloff
}
}
func DefaultSelect() Select {
return Select{make([]Module, SelectModuleCount), DefaultSelectLowerBound, DefaultSelectUpperBound, DefaultSelectEdgeFalloff}
}