Skip to content

Commit 36f04d6

Browse files
committed
add test realizations
1 parent 85aeee0 commit 36f04d6

File tree

16 files changed

+432
-327
lines changed

16 files changed

+432
-327
lines changed

src/main/kotlin/solve/main/MainView.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.github.palexdev.materialfx.css.themes.MFXThemeManager
55
import io.github.palexdev.materialfx.css.themes.Themes
66
import io.github.palexdev.materialfx.dialogs.MFXGenericDialog
77
import io.github.palexdev.materialfx.dialogs.MFXStageDialog
8+
import javafx.application.Platform
89
import javafx.geometry.Insets
910
import javafx.scene.control.ContentDisplay
1011
import javafx.scene.image.Image
@@ -158,7 +159,7 @@ class MainView : View() {
158159
)
159160
mainViewSplitPane.addStylesheet(MainSplitPaneStyle::class)
160161
center = mainViewSplitPane
161-
}
162+
}.also { Platform.runLater { sceneView.initialize() } }
162163

163164
override val root = mainViewBorderPane
164165

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package solve.rendering.canvas
2+
3+
import javafx.animation.AnimationTimer
4+
import javafx.scene.layout.Pane
5+
import java.awt.Color
6+
import java.awt.Image
7+
import java.util.Arrays
8+
import java.util.concurrent.ArrayBlockingQueue
9+
import java.util.concurrent.BlockingQueue
10+
import javax.imageio.ImageIO
11+
import kotlin.io.path.Path
12+
import kotlin.math.pow
13+
import kotlin.math.sin
14+
import kotlin.math.sqrt
15+
import kotlin.system.measureTimeMillis
16+
17+
class BufferedImageCanvas : AnimationTimer(), TestCanvas {
18+
private val width = 1036.0
19+
private val height = 1015.0
20+
21+
private val backgroundColorArray = IntArray(width.toInt() * height.toInt())
22+
23+
private val bufferedImageView = BufferedImageView(width.toInt(), height.toInt())
24+
25+
override val root = Pane(bufferedImageView)
26+
27+
private var frameImages = mutableListOf<Image>()
28+
private var scale = 0f
29+
30+
private var scaledFrameWidth = 0
31+
private var scaledFrameHeight = 0
32+
private var gridWidth = 0
33+
private var gridHeight = 0
34+
35+
override fun drawFrames(testFramePath: String, scale: Float, gridWidth: Int, gridHeight: Int) {
36+
repeat(gridWidth * gridHeight) {
37+
frameImages.add(ImageIO.read(Path(testFramePath).toUri().toURL()))
38+
}
39+
this.scale = scale
40+
this.gridWidth = gridWidth
41+
this.gridHeight = gridHeight
42+
43+
val frameImage = frameImages.first()
44+
45+
this.scaledFrameWidth = (frameImage.getWidth(null) * scale.toDouble()).toInt()
46+
this.scaledFrameHeight = (frameImage.getHeight(null) * scale.toDouble()).toInt()
47+
48+
Arrays.fill(backgroundColorArray, 0)
49+
50+
start()
51+
}
52+
53+
override fun handle(now: Long) {
54+
val graphics = bufferedImageView.graphics
55+
graphics.color = Color.WHITE
56+
graphics.fillRect(0, 0, width.toInt(), height.toInt())
57+
58+
for (y in 0 until gridHeight) {
59+
for (x in 0 until gridWidth) {
60+
graphics.drawImage(
61+
frameImages[y * gridWidth + x],
62+
x * scaledFrameWidth + (300 * sin(5 * now / 1000000000f)).toInt(),
63+
y * scaledFrameHeight + (300 * sin(5 * now / 1000000000f)).toInt(),
64+
scaledFrameWidth,
65+
scaledFrameHeight,
66+
null
67+
)
68+
}
69+
}
70+
71+
bufferedImageView.updateBuffer()
72+
}
73+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package solve.rendering.canvas
2+
3+
import javafx.scene.image.Image
4+
import javafx.scene.image.ImageView
5+
import javafx.scene.image.PixelBuffer
6+
import javafx.scene.image.PixelFormat
7+
import javafx.scene.image.WritableImage
8+
import java.awt.image.BufferedImage
9+
import java.awt.image.DataBufferInt
10+
import java.nio.IntBuffer
11+
12+
class BufferedImageView(private val width: Int, private val height: Int): ImageView() {
13+
private val buffer: IntBuffer = IntBuffer.allocate(width * height)
14+
private val pixelBuffer: PixelBuffer<IntBuffer>
15+
16+
private val _javaFXImage: WritableImage
17+
val javaFXImage: Image
18+
get() = _javaFXImage
19+
20+
val awtImage = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE)
21+
val graphics = awtImage.graphics
22+
23+
init {
24+
val dataBuffer = awtImage.raster.dataBuffer
25+
val dataBufferInt = dataBuffer as DataBufferInt
26+
val rawInts = dataBufferInt.data
27+
val rawIntsBuffer = IntBuffer.wrap(rawInts)
28+
29+
30+
pixelBuffer = PixelBuffer(width, height, rawIntsBuffer, PixelFormat.getIntArgbPreInstance())
31+
_javaFXImage = WritableImage(pixelBuffer)
32+
image = _javaFXImage
33+
}
34+
35+
fun updateBuffer() {
36+
pixelBuffer.updateBuffer { null }
37+
}
38+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package solve.rendering.canvas
2+
3+
import javafx.animation.AnimationTimer
4+
import javafx.scene.canvas.Canvas
5+
import javafx.scene.image.Image
6+
import javafx.scene.layout.Pane
7+
import kotlinx.coroutines.CoroutineScope
8+
import kotlinx.coroutines.Dispatchers
9+
import kotlinx.coroutines.launch
10+
import tornadofx.*
11+
import kotlin.math.pow
12+
import kotlin.math.sqrt
13+
import kotlin.system.measureTimeMillis
14+
15+
class BuiltInCanvas : AnimationTimer(), TestCanvas {
16+
private val width = 1036.0
17+
private val height = 1015.0
18+
19+
private val canvas = Canvas(width, height)
20+
21+
override val root = Pane(canvas)
22+
23+
private val graphicsContext = canvas.graphicsContext2D
24+
private var frameImages = mutableListOf<Image>()
25+
private var scale = 0f
26+
27+
private var scaledFrameWidth = 0.0
28+
private var scaledFrameHeight = 0.0
29+
private var gridWidth = 0
30+
private var gridHeight = 0
31+
32+
private var previousTime = 0L
33+
34+
private val measuredTimes = mutableListOf<Float>()
35+
private var measurementNumber = 0
36+
37+
override fun drawFrames(testFramePath: String, scale: Float, gridWidth: Int, gridHeight: Int) {
38+
repeat(gridWidth * gridHeight) {
39+
frameImages.add(Image(testFramePath))
40+
}
41+
this.scale = scale
42+
this.gridWidth = gridWidth
43+
this.gridHeight = gridHeight
44+
45+
val frameImage = frameImages.first()
46+
47+
this.scaledFrameWidth = frameImage.width * scale.toDouble()
48+
this.scaledFrameHeight = frameImage.height * scale.toDouble()
49+
50+
start()
51+
}
52+
53+
override fun handle(now: Long) {
54+
graphicsContext.clearRect(0.0, 0.0, width, height)
55+
56+
for (y in 0 until gridHeight) {
57+
for (x in 0 until gridWidth) {
58+
graphicsContext.drawImage(
59+
frameImages[y * gridWidth + x],
60+
x * scaledFrameWidth,
61+
y * scaledFrameHeight,
62+
scaledFrameWidth,
63+
scaledFrameHeight
64+
)
65+
}
66+
}
67+
68+
val deltaTime = (now - previousTime) / 1000000000f
69+
measurementNumber += 1
70+
71+
if (measurementNumber > TestCanvas.FirstSkippedMeasurementsNumber)
72+
measuredTimes.add(deltaTime)
73+
74+
if (measurementNumber == TestCanvas.FirstSkippedMeasurementsNumber + TestCanvas.MeasurementsNumber) {
75+
val avgTime = measuredTimes.average()
76+
val variance = measuredTimes.sumOf { (it - avgTime).pow(2) } / measuredTimes.count()
77+
val deviation = sqrt(variance)
78+
79+
println("Average time: $avgTime")
80+
println("Deviation: $deviation")
81+
}
82+
83+
previousTime = now
84+
}
85+
}

src/main/kotlin/solve/rendering/canvas/SceneCanvas.kt renamed to src/main/kotlin/solve/rendering/canvas/OpenGLSceneCanvas.kt

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package solve.rendering.canvas
22

3+
import javafx.application.Platform
34
import org.joml.Vector2f
45
import org.joml.Vector2i
56
import solve.rendering.engine.rendering.renderers.FramesRenderer
@@ -11,16 +12,17 @@ import solve.scene.controller.SceneController
1112
import solve.scene.model.VisualizationFrame
1213
import solve.utils.ServiceLocator
1314
import solve.utils.ceilToInt
15+
import kotlin.io.path.Path
16+
import kotlin.math.pow
17+
import kotlin.math.sqrt
18+
19+
class OpenGLSceneCanvas : OpenGLCanvas(), TestCanvas {
20+
override val root = canvas
1421

15-
class SceneCanvas : OpenGLCanvas() {
1622
private var sceneController: SceneController? = null
1723
private var framesRenderer: FramesRenderer? = null
1824
private var canvasScene: Scene? = null
1925

20-
private var isDraggingScene = false
21-
private var dragStartCameraPoint = Vector2f()
22-
private var dragStartPoint = Vector2i()
23-
2426
private var leftUpperCornerCameraPosition = Vector2f()
2527
private var rightLowerCornerCameraPosition = Vector2f()
2628

@@ -30,54 +32,25 @@ class SceneCanvas : OpenGLCanvas() {
3032
private val rowsNumber: Int
3133
get() = (framesSelectionSize.toFloat() / columnsNumber.toFloat()).ceilToInt()
3234

35+
private val measuredTimes = mutableListOf<Float>()
36+
private var measurementNumber = 0
37+
3338
init {
3439
initializeCanvasEvents()
3540
}
3641

37-
fun setNewSceneFrames(frames: List<VisualizationFrame>, framesSize: Vector2i) {
38-
framesRenderer?.setNewSceneFrames(frames)
39-
this.framesSize = framesSize
40-
}
41-
42-
fun setFramesSelection(framesSelection: List<VisualizationFrame>) {
43-
recalculateCameraCornersPositions()
44-
window.camera.position = leftUpperCornerCameraPosition
45-
46-
framesRenderer?.setFramesSelection(framesSelection)
47-
framesSelectionSize = framesSelection.count()
48-
}
49-
50-
fun setColumnsNumber(columnsNumber: Int) {
51-
framesRenderer?.setGridWidth(columnsNumber)
52-
this.columnsNumber = columnsNumber
53-
}
54-
55-
fun dragTo(toScreenPoint: Vector2i) {
56-
val mousePoint = fromScreenToCameraPoint(toScreenPoint)
57-
if (isDraggingScene) {
58-
val dragVector = mousePoint - dragStartPoint
59-
window.camera.position = dragStartCameraPoint - dragVector.toFloatVector() / window.camera.scaledZoom
42+
override fun drawFrames(testFramePath: String, scale: Float, gridWidth: Int, gridHeight: Int) {
43+
Platform.runLater {
44+
recalculateCameraCornersPositions()
6045
constraintCameraPosition()
6146
}
62-
}
6347

64-
fun startDragging(fromScreenPoint: Vector2i) {
65-
dragStartCameraPoint = window.camera.position
66-
dragStartPoint = fromScreenToCameraPoint(fromScreenPoint)
67-
isDraggingScene = true
48+
val frame = VisualizationFrame(0L, Path(testFramePath), emptyList())
49+
framesRenderer?.setGridSize(gridWidth, gridHeight)
50+
framesRenderer?.setTestFrame(frame)
51+
window.camera.zoom = 2.6f * scale
6852
}
6953

70-
fun stopDragging() {
71-
isDraggingScene = false
72-
}
73-
74-
fun zoomToPoint(screenPoint: Vector2i, newZoom: Float) {
75-
val cameraPoint = fromScreenToCameraPoint(screenPoint)
76-
window.camera.zoomToPoint(cameraPoint, newZoom)
77-
78-
recalculateCameraCornersPositions()
79-
constraintCameraPosition()
80-
}
8154

8255
override fun onInit() {
8356
val controller = ServiceLocator.getService<SceneController>() ?: return
@@ -89,11 +62,23 @@ class SceneCanvas : OpenGLCanvas() {
8962
}
9063

9164
override fun onDraw(deltaTime: Float) {
65+
measurementNumber += 1
66+
67+
if (measurementNumber > TestCanvas.FirstSkippedMeasurementsNumber)
68+
measuredTimes.add(deltaTime)
69+
70+
if (measurementNumber == TestCanvas.FirstSkippedMeasurementsNumber + TestCanvas.MeasurementsNumber) {
71+
val avgTime = measuredTimes.average()
72+
val variance = measuredTimes.sumOf { (it - avgTime).pow(2) } / measuredTimes.count()
73+
val deviation = sqrt(variance)
74+
75+
println("Average time: $avgTime")
76+
println("Deviation: $deviation")
77+
}
78+
9279
canvasScene?.renderers?.forEach { it.render() }
9380
}
9481

95-
private fun fromScreenToCameraPoint(screenPoint: Vector2i) = screenPoint - (window.size / 2)
96-
9782
private fun constraintCameraPosition() {
9883
window.camera.position.x =
9984
window.camera.position.x.coerceIn(leftUpperCornerCameraPosition.x, rightLowerCornerCameraPosition.x)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package solve.rendering.canvas
2+
3+
import javafx.scene.Parent
4+
5+
interface TestCanvas {
6+
val root: Parent
7+
8+
fun drawFrames(testFramePath: String, scale: Float, gridWidth: Int, gridHeight: Int)
9+
10+
companion object {
11+
const val FirstSkippedMeasurementsNumber = 10
12+
const val MeasurementsNumber = 100
13+
}
14+
}

0 commit comments

Comments
 (0)