如何控制Javafx scalafx FXyz三维形状

如何控制Javafx scalafx FXyz三维形状,javafx,scalafx,javafx-3d,Javafx,Scalafx,Javafx 3d,我有下面的测试代码,其中有一个ClothMesh(来自FXyz lib),我 可以拖动、旋转和拖动我的圆控制柄。一切都很好,FXyz很棒。现在我想使用SegmentedSphereMesh,它主要起作用,只是我的圆控制柄是二维的,没有环绕球体。我知道混合2D和3D可能出现的问题。然而,它是如此接近工作;如何使控制柄与球体一起工作,或者用另一种方法实现相同的功能。 注意,我不想通过移动相机来控制形状/网格 import org.fxyz.shapes.complex.cloth.ClothMesh

我有下面的测试代码,其中有一个ClothMesh(来自FXyz lib),我 可以拖动、旋转和拖动我的圆控制柄。一切都很好,FXyz很棒。现在我想使用SegmentedSphereMesh,它主要起作用,只是我的圆控制柄是二维的,没有环绕球体。我知道混合2D和3D可能出现的问题。然而,它是如此接近工作;如何使控制柄与球体一起工作,或者用另一种方法实现相同的功能。 注意,我不想通过移动相机来控制形状/网格

import org.fxyz.shapes.complex.cloth.ClothMesh
import org.fxyz.shapes.primitives.SegmentedSphereMesh

import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.DoubleProperty
import scalafx.collections.ObservableFloatArray
import scalafx.scene.image.Image
import scalafx.scene.input.{MouseButton, MouseEvent}
import scalafx.scene.paint.PhongMaterial
import scalafx.scene.shape._
import scalafx.scene.transform.Rotate
import scalafx.scene._
import scalafx.scene.paint.Color

/**
 * left mouse to drag the meshView and also to drag the handles
 * right mouse drag + ctrl to rotate about X axis
 * right mouse drag + alt to rotate about Y axis
 * right mouse drag + shift to rotate about Z axis
 */

object ClothTest2 extends JFXApp {
  private var dx = 0.0
  private var dy = 0.0

  stage = new PrimaryStage {
    scene = new Scene(600, 600, true, SceneAntialiasing.Balanced) {
      fill = Color.LightGray
      val testImg = "https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png"
      val img = new Image(testImg, 400, 400, false, true)

      val meshView = new SegmentedSphereMesh(20, 4, 2, 200d)
    //  val meshView = new ClothMesh(4, 4, 200, 200, 0.5, 0.5, 1.0)

      meshView.setDrawMode(DrawMode.Fill)
      meshView.setCullFace(CullFace.None)
      meshView.style = "-fx-background-color: #00000000"
      meshView.setMaterial(new PhongMaterial(Color.White, img, null, null, null))
      val controller = new MeshController(meshView.getMesh().asInstanceOf[javafx.scene.shape.TriangleMesh].points)
      val viewGroup = new Group(meshView, controller)
      root = new Group(new AmbientLight(Color.White), viewGroup) { translateX = 70; translateY = 70 }
      camera = new PerspectiveCamera(true) {
        nearClip = 0.0
        farClip = 100000.0
        fieldOfView = 42
        verticalFieldOfView = true
        translateZ = -900
      }
      val rotHandler = new RotHandler(viewGroup)
      onMouseDragged = (event: MouseEvent) => {
        rotHandler.onMouseDragged(event)
        if (event.button == MouseButton.PRIMARY) {
          viewGroup.layoutX = event.sceneX + dx
          viewGroup.layoutY = event.sceneY + dy
          event.consume()
        }
      }
      onMousePressed = (event: MouseEvent) => {
        rotHandler.onMousePressed(event)
        dx = viewGroup.layoutX.value - event.sceneX
        dy = viewGroup.layoutY.value - event.sceneY
        event.consume()
      }
    }
  }
}

class CircleHandle(color: Color) extends Circle {
  radius = 8
  var dx = 0.0
  var dy = 0.0
  fill <== when(hover) choose Color.Red.deriveColor(1, 1, 1, 0.4) otherwise color.deriveColor(1, 1, 1, 0.4)
  strokeWidth <== when(hover) choose 3 otherwise 2
  stroke = color
  onMousePressed = (event: MouseEvent) => {
    dx = centerX.value - event.x
    dy = centerY.value - event.y
    event.consume()
  }
  onMouseDragged = (event: MouseEvent) => {
    centerX = event.x + dx
    centerY = event.y + dy
    event.consume()
  }
}

class MeshController(thePoints: ObservableFloatArray) extends Group {
  children = for (i <- 0 until thePoints.size by 3) yield new CircleHandle(Color.Yellow) {
      centerX() = thePoints.get(i)
      centerX.onChange { (obs, oldVal, newVal) => thePoints.set(i, newVal.floatValue()) }
      centerY() = thePoints.get(i + 1)
      centerY.onChange { (obs, oldVal, newVal) => thePoints.set(i + 1, newVal.floatValue()) }
    }
}

class RotHandler(val viewer: Group) {
  private val angleX = DoubleProperty(0)
  private val angleY = DoubleProperty(0)
  private val angleZ = DoubleProperty(0)
  private var anchorX = 0d
  private var anchorY = 0d
  private val rotX = new Rotate { angle <== angleX; axis = Rotate.XAxis }
  private val rotY = new Rotate { angle <== angleY; axis = Rotate.YAxis }
  private val rotZ = new Rotate { angle <== angleZ; axis = Rotate.ZAxis }
  viewer.transforms = Seq(rotX, rotY, rotZ)
  def onMousePressed(event: MouseEvent) = {
    anchorX = event.sceneX
    anchorY = event.sceneY
    event.consume()
  }
  def onMouseDragged(event: MouseEvent) = {
    // right mouse only
    if (event.button == MouseButton.SECONDARY) {
      event match {
        // rotation about the Y axis, dragging the mouse in the x direction
        case ev if ev.altDown => angleY() = anchorX - event.sceneX
        // rotation about the X axis, dragging the mouse in the y direction
        case ev if ev.controlDown => angleX() = anchorY - event.sceneY
        // rotation about the Z axis, dragging the mouse in the x direction
        case ev if ev.shiftDown => angleZ() = anchorX - event.sceneX
        case _ => // ignore everything else
      }
    }
    event.consume()
  }
}
import org.fxyz.shapes.complex.cloth.ClothMesh
导入org.fxyz.shapes.primitives.SegmentedSphereMesh
导入scalafx.Includes_
导入scalafx.application.JFXApp
导入scalafx.application.JFXApp.PrimaryStage
导入scalafx.beans.property.DoubleProperty
导入scalafx.collections.Observalefloatarray
导入scalafx.scene.image.image
导入scalafx.scene.input.{MouseButton,MouseEvent}
导入scalafx.scene.paint.PhongMaterial
导入scalafx.scene.shape_
导入scalafx.scene.transform.Rotate
导入scalafx.scene_
导入scalafx.scene.paint.Color
/**
*使用鼠标左键拖动meshView并拖动控制柄
*用鼠标右键拖动并按住ctrl键可绕X轴旋转
*用鼠标右键拖动并按住alt键以绕Y轴旋转
*用鼠标右键拖动并按住shift键可绕Z轴旋转
*/
对象ClothTest2扩展了JFXApp{
私有变量dx=0.0
私有变量dy=0.0
阶段=新的初级阶段{
场景=新场景(600600,true,SceneAntialiasing.Balanced){
填充=颜色。浅灰色
val testImg=”https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png"
val img=新图像(testImg,400,400,false,true)
val meshView=新的分段SphereMesh(20,4,2200D)
//val meshView=新的ClothMesh(4,4,200,200,0.5,0.5,1.0)
meshView.setDrawMode(DrawMode.Fill)
meshView.setCullFace(CullFace.None)
meshView.style=“-fx背景色:#00000000”
setMaterial(新的PhongMaterial(Color.White、img、null、null、null))
val controller=new MeshController(meshView.getMesh().asInstanceOf[javafx.scene.shape.TriangleMesh].points)
val viewGroup=新组(网状视图、控制器)
根=新组(新环境光(Color.White),视图组){translateX=70;translateY=70}
摄像头=新透视摄像头(真){
nearClip=0.0
farClip=100000.0
视野=42
垂直视野=真
translateZ=-900
}
val rotHandler=新rotHandler(视图组)
onMouseDrawed=(事件:MouseEvent)=>{
rotHandler.onMouseDrawed(事件)
if(event.button==MouseButton.PRIMARY){
viewGroup.layoutX=event.sceneX+dx
viewGroup.layoutY=event.sceneY+dy
event.consume()
}
}
onMousePressed=(事件:MouseEvent)=>{
rotHandler.onMousePressed(事件)
dx=viewGroup.layoutX.value-event.sceneX
dy=viewGroup.layoutY.value-event.sceneY
event.consume()
}
}
}
}
类CircleHandle(颜色:color)扩展圆{
半径=8
var dx=0.0
var dy=0.0
填满{
centerX=事件.x+dx
centerY=event.y+dy
event.consume()
}
}
类MeshController(点:ObservaleFloataRay)扩展组{
children=for(i thePoints.set(i,newVal.floatValue())}
centerY()=点.get(i+1)
centerY.onChange{(obs,oldVal,newVal)=>thePoints.set(i+1,newVal.floatValue())}
}
}
RotHandler类(val查看器:组){
private val angleX=DoubleProperty(0)
private val angleY=DoubleProperty(0)
private val angleZ=DoubleProperty(0)
专用var anchorX=0d
私有变量anchorY=0d
private val rotX=new Rotate{angle angleZ()=anchorX-event.sceneX
case=>//忽略其他所有内容
}
}
event.consume()
}
}

我是FXyz团队的一员,希望提供帮助,但您是否可以发布一张图像或提供一个图像链接,以显示您当前的效果。我目前没有编译和运行Scala的设置。另外,您能否更详细地描述一下您在说“让我的句柄与球体一起工作”时希望使用的方式谢谢Birdasaur花时间看我的问题。我已经更新了代码(和一些图片)at:基本上,我最初的问题是如何将我的控制柄附加到分段SphereMesh的顶点。我想我现在已经这样做了,尽管我仍然不能像用ClothMesh那样拖动它们。我将离开一周。当我回来时,我会将代码转换为java。我是FXyz团队的一员,我想提供帮助,但你能帮我吗t图片或提供图片链接到您当前的效果。我目前没有编译和运行Scala的设置。另外,您能否更详细地描述一下,当您说“让我的手柄与球体一起工作”时,您希望如何操作?Thx。感谢Birdasaur花时间看我的问题。我已经更新了代码(和一些图片)at:基本上,我最初的问题是如何将我的控制柄附加到分段SphereMesh的顶点。我想我现在已经这样做了,尽管我仍然不能像拖动ClothMesh那样拖动它们。我将离开一周。回来后,我将把代码转换成java。