FX backend in progress
This commit is contained in:
parent
cef1a1ee6d
commit
fd43ea4843
@ -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>()
|
||||
}
|
@ -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 {
|
||||
|
@ -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() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user