Skip to content

Commit 6b72b7e

Browse files
committed
combination
1 parent bdf849f commit 6b72b7e

File tree

4 files changed

+139
-92
lines changed

4 files changed

+139
-92
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# NoiseVisualizer
22

3+
![showcase](showcase.gif)
4+
35
Only supports **Java 11+**!

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ plugins {
33
id 'org.jetbrains.kotlin.jvm' version '1.3.50'
44
id 'application'
55
id 'org.openjfx.javafxplugin' version '0.0.8'
6+
id 'com.github.johnrengelman.shadow' version '5.2.0'
67
}
78

89
group 'com.projecturanus.noisevisualizer'

showcase.gif

10.8 MB
Loading

src/main/kotlin/com/projecturanus/noisevisualizer/NoiseVisualizer.kt

Lines changed: 136 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ package com.projecturanus.noisevisualizer
33
import javafx.animation.TranslateTransition
44
import javafx.application.Application
55
import javafx.beans.property.BooleanProperty
6+
import javafx.beans.property.IntegerProperty
67
import javafx.scene.*
78
import javafx.scene.control.Label
89
import javafx.scene.input.KeyCode
910
import javafx.scene.paint.Color
1011
import javafx.scene.paint.PhongMaterial
1112
import javafx.scene.shape.Box
1213
import javafx.scene.transform.Rotate
13-
import javafx.stage.Stage
1414
import javafx.util.Duration
1515
import org.controlsfx.control.RangeSlider
1616
import tornadofx.*
@@ -34,89 +34,20 @@ var highValueColoring = 0.0
3434
var lowValueFiltering = 0.0
3535
var highValueFiltering = 0.0
3636

37+
var instantMode: BooleanProperty = false.toProperty()
3738
var enableColoring: BooleanProperty = false.toProperty()
3839
var enableFiltering: BooleanProperty = false.toProperty()
40+
var coloredNum: IntegerProperty = 0.toProperty()
41+
var filteredNum: IntegerProperty = 0.toProperty()
3942

40-
class NoiseVisualizer : Application() {
41-
42-
override fun start(primaryStage: Stage) {
43-
println(blockMap)
44-
val root = Group()
45-
for (x in 0 until 16) {
46-
for (y in 0 until 128) {
47-
for (z in 0 until 16) {
48-
// Creating an object of the class Box
49-
val box = Box()
50-
box.setOnMouseMoved { }
51-
box.width = 50.0
52-
box.height = 50.0
53-
box.depth = 50.0
54-
box.userData = Triple(x, y, z)
55-
box.material = PhongMaterial()
56-
box.translateX = x * 70.0
57-
box.translateY = y * 70.0
58-
box.translateZ = z * 70.0
59-
blockMap[x][y].add(z, box)
60-
root.children.add(box)
61-
}
62-
}
63-
}
64-
syncColor()
65-
66-
val scene = Scene(root, 800.0, 600.0, true, SceneAntialiasing.BALANCED)
67-
68-
val rotateX = Rotate(30.0, 500.0, 500.0, 500.0, Rotate.X_AXIS)
69-
val rotateY = Rotate(20.0, 500.0, 500.0, 500.0, Rotate.Y_AXIS)
70-
root.transforms.addAll(rotateX, rotateY)
71-
root.children.add(AmbientLight(Color.WHITE))
72-
73-
scene.setOnMousePressed { me ->
74-
mouseOldX = me.sceneX
75-
mouseOldY = me.sceneY
76-
}
77-
scene.setOnMouseDragged { me ->
78-
mousePosX = me.sceneX
79-
mousePosY = me.sceneY
80-
rotateX.angle = rotateX.angle - (mousePosY - mouseOldY)
81-
rotateY.angle = rotateY.angle + (mousePosX - mouseOldX)
82-
mouseOldX = mousePosX
83-
mouseOldY = mousePosY
84-
}
85-
val camera = PerspectiveCamera(true)
86-
camera.nearClip = 0.1
87-
camera.farClip = 10000.0
88-
camera.translateX = 0.0
89-
camera.translateY = 0.0
90-
camera.translateZ = -100.0
91-
scene.setOnKeyPressed {
92-
val animation = TranslateTransition(Duration.millis(100.0))
93-
animation.node = camera
94-
when (it.code) {
95-
KeyCode.W -> animation.byZ = 300.0
96-
KeyCode.A -> animation.byX = -300.0
97-
KeyCode.S -> animation.byZ = -300.0
98-
KeyCode.D -> animation.byX = 300.0
99-
}
100-
animation.play()
101-
}
102-
scene.fill = Color.WHITE
103-
scene.camera = camera
43+
var mouseOnPos = Triple(0, 0, 0).toProperty()
44+
var selectedPos = Triple(0, 0, 0).toProperty()
10445

105-
primaryStage.scene = scene
106-
primaryStage.show()
107-
showConfigStage()
108-
}
109-
110-
fun showConfigStage() {
111-
val stage = Stage()
112-
val pane = ConfigView().root
113-
val scene = Scene(pane, 600.0, 400.0)
114-
stage.scene = scene
115-
stage.show()
116-
}
117-
}
46+
class NoiseVisualizer : App(MainView::class)
11847

11948
fun syncColor() {
49+
coloredNum.value = 0
50+
filteredNum.value = 0
12051
for (x in 0 until 16) {
12152
for (y in 0 until 128) {
12253
for (z in 0 until 16) {
@@ -127,39 +58,145 @@ fun syncColor() {
12758
if (enableFiltering.value) {
12859
if (noise !in lowValueFiltering..highValueFiltering) {
12960
box.visibleProperty().value = false
61+
filteredNum.value++
62+
if (enableColoring.value) {
63+
if (noise in lowValueColoring..highValueColoring) {
64+
coloredNum.value--
65+
}
66+
}
13067
}
13168
}
13269
if (enableColoring.value) {
13370
if (noise in lowValueColoring..highValueColoring) {
13471
(box.material as PhongMaterial).diffuseColor = Color.rgb(abs(noise * 255).toInt() + 1, 0, 0)
72+
coloredNum.value++
13573
}
13674
}
13775
}
13876
}
13977
}
14078
}
14179

142-
class ConfigView : View() {
143-
override val root = gridpane {
80+
fun initSubScene(): SubScene {
81+
println(blockMap)
82+
var root = Group()
83+
for (x in 0 until 16) {
84+
for (y in 0 until 128) {
85+
for (z in 0 until 16) {
86+
// Creating an object of the class Box
87+
val box = Box()
88+
box.setOnMouseMoved { mouseOnPos.value = Triple(x, y, z) }
89+
box.setOnMouseClicked { selectedPos.value = Triple(x, y, z) }
90+
box.width = 50.0
91+
box.height = 50.0
92+
box.depth = 50.0
93+
box.userData = Triple(x, y, z)
94+
box.material = PhongMaterial()
95+
box.translateX = x * 70.0
96+
box.translateY = y * 70.0
97+
box.translateZ = z * 70.0
98+
blockMap[x][y].add(z, box)
99+
root.children.add(box)
100+
}
101+
}
102+
}
103+
syncColor()
104+
105+
val scene = SubScene(root, 600.0, 600.0, true, SceneAntialiasing.BALANCED)
106+
107+
val rotateX = Rotate(30.0, 500.0, 500.0, 500.0, Rotate.X_AXIS)
108+
val rotateY = Rotate(20.0, 500.0, 500.0, 500.0, Rotate.Y_AXIS)
109+
root.transforms.addAll(rotateX, rotateY)
110+
root.children.add(AmbientLight(Color.WHITE))
111+
112+
scene.setOnMousePressed { me ->
113+
mouseOldX = me.sceneX
114+
mouseOldY = me.sceneY
115+
}
116+
scene.setOnMouseDragged { me ->
117+
mousePosX = me.sceneX
118+
mousePosY = me.sceneY
119+
rotateX.angle = rotateX.angle - (mousePosY - mouseOldY)
120+
rotateY.angle = rotateY.angle + (mousePosX - mouseOldX)
121+
mouseOldX = mousePosX
122+
mouseOldY = mousePosY
123+
}
124+
val camera = PerspectiveCamera(true)
125+
camera.nearClip = 0.1
126+
camera.farClip = 10000.0
127+
camera.translateX = 0.0
128+
camera.translateY = 0.0
129+
camera.translateZ = -100.0
130+
camera.fieldOfView = 80.0
131+
scene.fill = Color.WHITE
132+
scene.camera = camera
133+
return scene
134+
}
135+
136+
class MainView : View() {
137+
override val root = splitpane {
138+
title = "Noise Visualizer"
139+
primaryStage.width = 900.0
140+
primaryStage.isResizable = false
141+
val subScene = initSubScene()
142+
opcr(this, subScene) { }
143+
configPane
144+
setOnKeyPressed {
145+
val animation = TranslateTransition(Duration.millis(100.0))
146+
animation.node = subScene.camera
147+
when (it.code) {
148+
KeyCode.W -> animation.byZ = 300.0
149+
KeyCode.A -> animation.byX = -300.0
150+
KeyCode.S -> animation.byZ = -300.0
151+
KeyCode.D -> animation.byX = 300.0
152+
}
153+
animation.play()
154+
}
155+
}
156+
157+
val configPane = gridpane {
144158
paddingAll = 10.0
159+
prefWidth = 200.0
160+
row {
161+
label {
162+
textProperty().bind(mouseOnPos.stringBinding { "Current pos: ${mouseOnPos.value}" })
163+
}
164+
}
165+
row {
166+
label {
167+
textProperty().bind(mouseOnPos.stringBinding { "Noise value: ${noise.GetNoise(mouseOnPos.value.first.toFloat(), mouseOnPos.value.second.toFloat(), mouseOnPos.value.third.toFloat())}" })
168+
}
169+
}
170+
row {
171+
checkbox {
172+
text = "Instant mode"
173+
selectedProperty().value = false
174+
instantMode.bind(selectedProperty())
175+
}
176+
}
177+
row {
178+
label("Frequency")
179+
}
145180
row {
146-
label { text = "Frequency" }
147181
val slider = slider(0, 1)
148-
slider.valueProperty().addListener { observable, oldValue, newValue -> noise.m_frequency = newValue.toFloat() }
182+
slider.valueProperty().addListener { observable, oldValue, newValue -> noise.m_frequency = newValue.toFloat(); if (instantMode.value) { syncColor() } }
149183
label(slider.valueProperty())
150184
}
151185
row {
152186
label { text = "Noise type" }
153187
combobox(null, FastNoise.NoiseType.values().toList()) {
154188
value = FastNoise.NoiseType.Perlin
155-
selectionModel.selectedItemProperty().onChange { noise.m_noiseType = it ?: FastNoise.NoiseType.Perlin }
189+
selectionModel.selectedItemProperty().onChange {
190+
noise.m_noiseType = it ?: FastNoise.NoiseType.Perlin
191+
if (instantMode.value) { syncColor() }
192+
}
156193
}
157194
}
158195
row {
159196
label { text = "Interpolation (Only in Fractal noise)" }
160197
combobox(null, FastNoise.Interp.values().toList()) {
161198
value = FastNoise.Interp.Quintic
162-
selectionModel.selectedItemProperty().onChange { noise.m_interp = it ?: FastNoise.Interp.Quintic }
199+
selectionModel.selectedItemProperty().onChange { noise.m_interp = it ?: FastNoise.Interp.Quintic; if (instantMode.value) { syncColor() } }
163200
}
164201
}
165202
row {
@@ -169,35 +206,42 @@ class ConfigView : View() {
169206
enableColoring.bind(selectedProperty())
170207
}
171208
}
209+
lateinit var lightLabel: Label
172210
row {
173211
label { text = "Light up threshold" }
174-
lateinit var range: Label
175212
RangeSlider(-1.0, 1.0, -0.4, 0.6).attachTo(this) {
176213
disableProperty().value = true
177214
enableColoring.onChange { disableProperty().set(!it) }
178-
lowValueProperty().onChange { lowValueColoring = it; range.text = "$lowValue~$highValue" }
179-
highValueProperty().onChange { highValueColoring = it; range.text = "$lowValue~$highValue" }
215+
lowValueProperty().onChange { lowValueColoring = it; lightLabel.text = String.format("%.5f~%.5f", lowValue, highValue); if (instantMode.value) { syncColor() } }
216+
highValueProperty().onChange { highValueColoring = it; lightLabel.text = String.format("%.5f~%.5f", lowValue, highValue); if (instantMode.value) { syncColor() } }
180217
}
181-
range = label()
182218
}
219+
row {
220+
lightLabel = label()
221+
}
222+
row { label { textProperty().bind(coloredNum.stringBinding { "Colorized amount: \n $it / ${65536 - filteredNum.intValue()} (${String.format("%.2f", ((it?.toDouble() ?: 0.0) / (65536 - filteredNum.intValue())) * 100)}%)" }) } }
183223
row {
184224
checkbox {
185225
text = "Enable filtering"
186226
selectedProperty().value = false
187227
enableFiltering.bind(selectedProperty())
188228
}
189229
}
230+
lateinit var filterLabel: Label
190231
row {
191232
label { text = "Filtering threshold" }
192-
lateinit var range: Label
193233
RangeSlider(-1.0, 1.0, -0.4, 0.6).attachTo(this) {
194234
disableProperty().value = true
195235
enableFiltering.onChange { disableProperty().set(!it) }
196-
lowValueProperty().onChange { lowValueFiltering = it; range.text = "$lowValue~$highValue" }
197-
highValueProperty().onChange { highValueFiltering = it; range.text = "$lowValue~$highValue" }
236+
lowValueProperty().onChange { lowValueFiltering = it; filterLabel.text = String.format("%.5f~%.5f", lowValue, highValue); if (instantMode.value) { syncColor() } }
237+
highValueProperty().onChange { highValueFiltering = it; filterLabel.text = String.format("%.5f~%.5f", lowValue, highValue); if (instantMode.value) { syncColor() } }
198238
}
199-
range = label()
200239
}
240+
row {
241+
filterLabel = label()
242+
}
243+
row { label { textProperty().bind(filteredNum.stringBinding { "Filtered amount: \n $it / 65536 (${String.format("%.2f", ((it?.toDouble() ?: 0.0) / 65536.0) * 100)}%)" }) } }
244+
row { label { textProperty().bind(filteredNum.stringBinding { "Shown amount: \n ${65536 - (it?.toInt() ?: 0)} / 65536 (${String.format("%.2f", ((65536 - (it?.toDouble() ?: 0.0)) / 65536.0) * 100)}%)" }) } }
201245
row {
202246
button("Rebuild").setOnMouseClicked { syncColor() }
203247
}

0 commit comments

Comments
 (0)