FX backend in progress

This commit is contained in:
Alexander Nozik 2019-12-15 10:56:44 +03:00
parent cef1a1ee6d
commit fd43ea4843
5 changed files with 46 additions and 34 deletions

View File

@ -1,8 +1,10 @@
package hep.dataforge.vis.spatial.fx
package hep.dataforge.vis.spatial.demo
import hep.dataforge.context.Global
import hep.dataforge.meta.number
import hep.dataforge.vis.spatial.*
import hep.dataforge.vis.spatial.fx.Canvas3D
import hep.dataforge.vis.spatial.fx.FX3DPlugin
import javafx.scene.Parent
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@ -11,22 +13,21 @@ import kotlinx.coroutines.launch
import tornadofx.*
import kotlin.random.Random
class SpatialDemoApp: App(SpatialDemoView::class)
class RendererDemoApp : App(RendererDemoView::class)
class SpatialDemoView: View(){
private val plugin = Global.plugins.fetch(FX3DPlugin)
private val canvas = Canvas3D(plugin)
class RendererDemoView : View() {
val plugin = Global.plugins.fetch(FX3DPlugin)
val renderer = Canvas3D(plugin)
override val root: Parent = borderpane {
center = renderer.root
center = canvas.root
}
lateinit var group: VisualGroup3D
init {
renderer.render {
canvas.render {
box(100,100,100)
group = group {
box(100,100,100)
box(100,100,100) {
@ -45,7 +46,7 @@ class RendererDemoView : View() {
}
}
renderer.apply {
canvas.apply {
angleY = -30.0
angleX = -15.0
}
@ -54,5 +55,5 @@ class RendererDemoView : View() {
fun main() {
launch<RendererDemoApp>()
launch<SpatialDemoApp>()
}

View File

@ -19,13 +19,21 @@ import javafx.scene.input.KeyEvent
import javafx.scene.input.MouseEvent
import javafx.scene.input.ScrollEvent
import javafx.scene.paint.Color
import org.fxyz3d.scene.Axes
import org.fxyz3d.scene.CubeWorld
import org.fxyz3d.utils.CameraTransformer
import tornadofx.*
class Canvas3D(val plugin: FX3DPlugin, val meta: Meta = EmptyMeta) : Fragment(), Renderer<VisualObject3D>, ContextAware {
class Canvas3D(val plugin: FX3DPlugin, meta: Meta = EmptyMeta) :
Fragment(), Renderer<VisualObject3D>, ContextAware {
override val context: Context get() = plugin.context
val world: Group = Group()
val world = CubeWorld(true)
val axes = Axes().also {
it.setHeight(AXIS_LENGTH)
it.setRadius(LINE_WIDTH)
world.add(it)
}
private val camera = PerspectiveCamera().apply {
nearClip = CAMERA_NEAR_CLIP
@ -69,12 +77,12 @@ class Canvas3D(val plugin: FX3DPlugin, val meta: Meta = EmptyMeta) : Fragment(),
768.0,
true,
SceneAntialiasing.BALANCED
).apply {
fill = Color.GREY
this.camera = this@Canvas3D.camera
).also {scene->
scene.fill = Color.GREY
scene.camera = camera
id = "canvas"
handleKeyboard(this)
handleMouse(this)
handleKeyboard(scene)
handleMouse(scene)
}
}
@ -90,7 +98,7 @@ class Canvas3D(val plugin: FX3DPlugin, val meta: Meta = EmptyMeta) : Fragment(),
cameraRotation.ry.angle = CAMERA_INITIAL_Y_ANGLE
cameraRotation.rx.angle = CAMERA_INITIAL_X_ANGLE
}
// KeyCode.X -> axisGroup.isVisible = !axisGroup.isVisible
KeyCode.X -> axes.isVisible = !axes.isVisible
// KeyCode.S -> snapshot()
// KeyCode.DIGIT1 -> pixelMap.filterKeys { it.getLayerNumber() == 1 }.values.forEach {
// toggleTransparency(
@ -145,8 +153,8 @@ class Canvas3D(val plugin: FX3DPlugin, val meta: Meta = EmptyMeta) : Fragment(),
}
if (me.isPrimaryButtonDown) {
cameraRotation.rz.angle =
cameraRotation.rz.angle + mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED
cameraRotation.ry.angle =
cameraRotation.ry.angle + mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED
cameraRotation.rx.angle =
cameraRotation.rx.angle + mouseDeltaY * MOUSE_SPEED * modifier * ROTATION_SPEED
} else if (me.isSecondaryButtonDown) {
@ -162,7 +170,8 @@ class Canvas3D(val plugin: FX3DPlugin, val meta: Meta = EmptyMeta) : Fragment(),
}
override fun render(obj: VisualObject3D, meta: Meta) {
plugin.buildNode(obj)?.let { world.children.add(it) }
val node = plugin.buildNode(obj) ?: kotlin.error("Can't render FX node for object $obj")
world.add(node)
}
companion object {

View File

@ -84,7 +84,7 @@ class FX3DPlugin : AbstractPlugin() {
}
if (this is Shape3D) {
materialProperty().bind(binding["color"].transform { it.material() })
materialProperty().bind(binding[Material3D.MATERIAL_KEY].transform { it.material() })
}
}
}

View File

@ -9,7 +9,7 @@ import javafx.scene.paint.Color
import javafx.scene.paint.Material
import javafx.scene.paint.PhongMaterial
object Materials {
object FXMaterials {
val RED = PhongMaterial().apply {
diffuseColor = Color.DARKRED
specularColor = Color.RED
@ -30,8 +30,9 @@ object Materials {
/**
* Infer color based on meta item
* @param opacity default opacity
*/
fun MetaItem<*>.color(): Color {
fun MetaItem<*>.color(opacity: Double = 1.0): Color {
return when (this) {
is MetaItem.ValueItem -> if (this.value.type == ValueType.STRING) {
Color.web(this.value.string)
@ -47,7 +48,7 @@ fun MetaItem<*>.color(): Color {
node["red"]?.int ?: 0,
node["green"]?.int ?: 0,
node["blue"]?.int ?: 0,
node["opacity"]?.double ?: 1.0
node["opacity"]?.double ?: opacity
)
}
}
@ -58,11 +59,13 @@ fun MetaItem<*>.color(): Color {
*/
fun MetaItem<*>?.material(): Material {
return when (this) {
null -> Materials.GREY
null -> FXMaterials.GREY
is MetaItem.ValueItem -> PhongMaterial(color())
is MetaItem.NodeItem -> PhongMaterial().apply {
(node["color"]?: this@material).let { diffuseColor = it.color() }
node["specularColor"]?.let { specularColor = it.color() }
val opacity = node["opacity"].double ?: 1.0
(node["color"] ?: this@material).let { diffuseColor = it.color(opacity) }
node["specularColor"]?.let { specularColor = it.color(opacity) }
}
}
}

View File

@ -7,6 +7,7 @@ import hep.dataforge.vis.spatial.Shape
import javafx.scene.shape.Mesh
import javafx.scene.shape.MeshView
import javafx.scene.shape.TriangleMesh
import org.fxyz3d.geometry.Face3
import kotlin.reflect.KClass
object FXShapeFactory : FX3DFactory<Shape> {
@ -18,11 +19,9 @@ object FXShapeFactory : FX3DFactory<Shape> {
}
}
private typealias Face = IntArray
private class FXGeometryBuilder : GeometryBuilder<Mesh> {
val vertices = ArrayList<Point3D>()
val faces = ArrayList<Face>()
val faces = ArrayList<Face3>()
private val vertexCache = HashMap<Point3D, Int>()
private fun append(vertex: Point3D): Int {
@ -38,7 +37,7 @@ private class FXGeometryBuilder : GeometryBuilder<Mesh> {
override fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D?, meta: Meta) {
//adding vertices
val face: Face = intArrayOf(append(vertex1), append(vertex2), append(vertex3))
val face = Face3(append(vertex1), append(vertex2), append(vertex3))
faces.add(face)
}
@ -49,7 +48,7 @@ private class FXGeometryBuilder : GeometryBuilder<Mesh> {
mesh.points.addAll(it.x.toFloat(), it.y.toFloat(), it.z.toFloat())
}
faces.forEach {
mesh.faces.addAll(it[0], it[1], it[2])
mesh.faces.addAll(it.p0, it.p1, it.p2)
}
return mesh
}