@@ -3,14 +3,14 @@ package com.projecturanus.noisevisualizer
33import javafx.animation.TranslateTransition
44import javafx.application.Application
55import javafx.beans.property.BooleanProperty
6+ import javafx.beans.property.IntegerProperty
67import javafx.scene.*
78import javafx.scene.control.Label
89import javafx.scene.input.KeyCode
910import javafx.scene.paint.Color
1011import javafx.scene.paint.PhongMaterial
1112import javafx.scene.shape.Box
1213import javafx.scene.transform.Rotate
13- import javafx.stage.Stage
1414import javafx.util.Duration
1515import org.controlsfx.control.RangeSlider
1616import tornadofx.*
@@ -34,89 +34,20 @@ var highValueColoring = 0.0
3434var lowValueFiltering = 0.0
3535var highValueFiltering = 0.0
3636
37+ var instantMode: BooleanProperty = false .toProperty()
3738var enableColoring: BooleanProperty = false .toProperty()
3839var 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
11948fun 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