JavaFX3D-如何使用3D对象和UI控件为组和子场景设置不同的摄影机?
由于JavaFX8中的新特性,可以将3D对象与2D UI控件相结合 我将此文档用作手册: 因此,我制定了以下代码:JavaFX3D-如何使用3D对象和UI控件为组和子场景设置不同的摄影机?,java,3d,javafx-2,javafx-8,Java,3d,Javafx 2,Javafx 8,由于JavaFX8中的新特性,可以将3D对象与2D UI控件相结合 我将此文档用作手册: 因此,我制定了以下代码: public class CastAnalytics extends Application { final Group root = new Group(); final Group axisGroup = new Group(); final XForm world = new XForm(); final PerspectiveCamera
public class CastAnalytics extends Application {
final Group root = new Group();
final Group axisGroup = new Group();
final XForm world = new XForm();
final PerspectiveCamera camera = new PerspectiveCamera(true);
final PerspectiveCamera subSceneCamera = new PerspectiveCamera(false);
final XForm cameraXForm = new XForm();
final XForm cameraXForm2 = new XForm();
final XForm cameraXForm3 = new XForm();
final double cameraDistance = 450;
final XForm moleculeGroup = new XForm();
private Timeline timeline;
boolean timelinePlaying = false;
double CONTROL_MULTIPLIER = 0.1;
double SHIFT_MULTIPLIER = 0.1;
double ALT_MULTIPLIER = 0.5;
double mousePosX;
double mousePosY;
double mouseOldX;
double mouseOldY;
double mouseDeltaX;
double mouseDeltaY;
@Override
public void start(Stage primaryStage) throws Exception{
buildScene();
buildCamera();
buildAxes();
Scene scene = new Scene(root, 1024, 768, true);
scene.setFill(Color.GREY);
handleKeyboard(scene, world);
handleMouse(scene, world);
primaryStage.setTitle("Sample Application");
primaryStage.setScene(scene);
primaryStage.show();
scene.setCamera(subSceneCamera);
scene.setCamera(camera);
}
private void buildScene() {
root.getChildren().add(world);
Label label = new Label("123");
HBox hBox = new HBox();
hBox.getChildren().add(label);
SubScene subScene = new SubScene(hBox, 200, 200);
subScene.setLayoutX(100);
subScene.setLayoutY(100);
root.getChildren().addAll(subScene);
}
private void buildCamera() {
root.getChildren().addAll(cameraXForm);
cameraXForm.getChildren().add(cameraXForm2);
cameraXForm2.getChildren().add(cameraXForm3);
cameraXForm3.getChildren().add(camera);
cameraXForm3.setRotateZ(180.0);
camera.setNearClip(0.1);
camera.setFarClip(10000.0);
camera.setTranslateZ(-cameraDistance);
cameraXForm.ry.setAngle(320.0);
cameraXForm.rx.setAngle(40);
}
private void buildAxes() {
Box box = new Box(200,200,200);
axisGroup.getChildren().addAll(box);
world.getChildren().addAll(axisGroup);
}
private void handleMouse(Scene scene, final Node root) {
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent me) {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseOldX = me.getSceneX();
mouseOldY = me.getSceneY();
}
});
scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseDeltaX = (mousePosX - mouseOldX);
mouseDeltaY = (mousePosY - mouseOldY);
double modifier = 1.0;
double modifierFactor = 0.1;
if (me.isControlDown()) {
modifier = 0.1;
}
if (me.isShiftDown()) {
modifier = 10.0;
}
if (me.isPrimaryButtonDown()) {
cameraXForm.ry.setAngle(cameraXForm.ry.getAngle() - mouseDeltaX * modifierFactor * modifier * 2.0); // +
cameraXForm.rx.setAngle(cameraXForm.rx.getAngle() + mouseDeltaY * modifierFactor * modifier * 2.0); // -
} else if (me.isSecondaryButtonDown()) {
double z = camera.getTranslateZ();
double newZ = z + mouseDeltaX * modifierFactor * modifier;
camera.setTranslateZ(newZ);
} else if (me.isMiddleButtonDown()) {
cameraXForm2.t.setX(cameraXForm2.t.getX() + mouseDeltaX * modifierFactor * modifier * 0.3); // -
cameraXForm2.t.setY(cameraXForm2.t.getY() + mouseDeltaY * modifierFactor * modifier * 0.3); // -
}
}
});
}
private void handleKeyboard(Scene scene, final Node root) {
final boolean moveCamera = true;
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
Duration currentTime;
switch (event.getCode()) {
case Z:
if (event.isShiftDown()) {
cameraXForm.ry.setAngle(0.0);
cameraXForm.rx.setAngle(0.0);
camera.setTranslateZ(-300.0);
}
cameraXForm2.t.setX(0.0);
cameraXForm2.t.setY(0.0);
break;
case X:
if (event.isControlDown()) {
if (axisGroup.isVisible()) {
axisGroup.setVisible(false);
} else {
axisGroup.setVisible(true);
}
}
break;
case S:
if (event.isControlDown()) {
if (moleculeGroup.isVisible()) {
moleculeGroup.setVisible(false);
} else {
moleculeGroup.setVisible(true);
}
}
break;
case SPACE:
if (timelinePlaying) {
timeline.pause();
timelinePlaying = false;
} else {
timeline.play();
timelinePlaying = true;
}
break;
case UP:
if (event.isControlDown() && event.isShiftDown()) {
cameraXForm2.t.setY(cameraXForm2.t.getY() - 10.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown() && event.isShiftDown()) {
cameraXForm.rx.setAngle(cameraXForm.rx.getAngle() - 10.0 * ALT_MULTIPLIER);
} else if (event.isControlDown()) {
cameraXForm2.t.setY(cameraXForm2.t.getY() - 1.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown()) {
cameraXForm.rx.setAngle(cameraXForm.rx.getAngle() - 2.0 * ALT_MULTIPLIER);
} else if (event.isShiftDown()) {
double z = camera.getTranslateZ();
double newZ = z + 5.0 * SHIFT_MULTIPLIER;
camera.setTranslateZ(newZ);
}
break;
case DOWN:
if (event.isControlDown() && event.isShiftDown()) {
cameraXForm2.t.setY(cameraXForm2.t.getY() + 10.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown() && event.isShiftDown()) {
cameraXForm.rx.setAngle(cameraXForm.rx.getAngle() + 10.0 * ALT_MULTIPLIER);
} else if (event.isControlDown()) {
cameraXForm2.t.setY(cameraXForm2.t.getY() + 1.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown()) {
cameraXForm.rx.setAngle(cameraXForm.rx.getAngle() + 2.0 * ALT_MULTIPLIER);
} else if (event.isShiftDown()) {
double z = camera.getTranslateZ();
double newZ = z - 5.0 * SHIFT_MULTIPLIER;
camera.setTranslateZ(newZ);
}
break;
case RIGHT:
if (event.isControlDown() && event.isShiftDown()) {
cameraXForm2.t.setX(cameraXForm2.t.getX() + 10.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown() && event.isShiftDown()) {
cameraXForm.ry.setAngle(cameraXForm.ry.getAngle() - 10.0 * ALT_MULTIPLIER);
} else if (event.isControlDown()) {
cameraXForm2.t.setX(cameraXForm2.t.getX() + 1.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown()) {
cameraXForm.ry.setAngle(cameraXForm.ry.getAngle() - 2.0 * ALT_MULTIPLIER);
}
break;
case LEFT:
if (event.isControlDown() && event.isShiftDown()) {
cameraXForm2.t.setX(cameraXForm2.t.getX() - 10.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown() && event.isShiftDown()) {
cameraXForm.ry.setAngle(cameraXForm.ry.getAngle() + 10.0 * ALT_MULTIPLIER); // -
} else if (event.isControlDown()) {
cameraXForm2.t.setX(cameraXForm2.t.getX() - 1.0 * CONTROL_MULTIPLIER);
} else if (event.isAltDown()) {
cameraXForm.ry.setAngle(cameraXForm.ry.getAngle() + 2.0 * ALT_MULTIPLIER); // -
}
break;
}
}
});
}
public static void main(String[] args) {
launch(args);
}
}
公共类扩展应用程序{
最终组根=新组();
最终组axisGroup=新组();
最终XForm world=新XForm();
最终透视摄影机=新透视摄影机(真);
最终透视摄影机子场景A=新透视摄影机(假);
最终XForm cameraXForm=新XForm();
最终XForm cameraXForm2=新XForm();
最终XForm cameraXForm3=新XForm();
最终双摄像度=450;
最终XForm分子组=新XForm();
私人时间表;
布尔时间线播放=假;
双控_乘数=0.1;
双移位乘法器=0.1;
双ALT_乘数=0.5;
双鼠标;
双鼠标定位;
双鼠标;
双小老鼠;
双滑鼠斧;
双滑鼠日;
@凌驾
public void start(Stage primaryStage)引发异常{
buildScene();
buildCamera();
buildAxes();
场景=新场景(root,1024768,true);
场景。设置填充(颜色。灰色);
手持键盘(场景、世界);
手推车(场景、世界);
primaryStage.setTitle(“示例应用程序”);
初级阶段。场景(场景);
primaryStage.show();
场景.设置摄像机(亚场景摄像机);
场景。设置摄像机(摄像机);
}
私有void buildScene(){
root.getChildren().add(世界);
标签=新标签(“123”);
HBox HBox=新的HBox();
hBox.getChildren().add(标签);
亚新统亚新统=新亚新统(hBox,200200);
亚新世setLayoutX(100);
亚新世setLayoutY(100);
root.getChildren().addAll(子场景);
}
私人摄像机(){
root.getChildren().addAll(cameraXForm);
cameraXForm.getChildren().add(cameraXForm2);
cameraXForm2.getChildren().add(cameraXForm3);
cameraXForm3.getChildren().add(摄影机);
cameraXForm3.setRotateZ(180.0);
摄像头。setNearClip(0.1);
摄像机。setFarClip(10000.0);
摄影机.setTranslateZ(-camerRadiance);
cameraXForm.ry.setAngle(320.0);
摄像机变换接收设置角度(40);
}
私有void buildAxes(){
盒子=新盒子(200200);
axisGroup.getChildren().addAll(框);
world.getChildren().addAll(axisGroup);
}
私有void handleMouse(场景,最终节点根){
scene.setOnMousePressed(新的EventHandler(){
@重写公共无效句柄(MouseEvent me){
mousePosX=me.getSceneX();
mousePosY=me.getSceneY();
mouseOldX=me.getSceneX();
mouseOldY=me.getSceneY();
}
});
scene.setonMouseDrawed(新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent me){
mouseOldX=mousePosX;
mouseOldY=鼠标点;
mousePosX=me.getSceneX();
mousePosY=me.getSceneY();
mouseDeltaX=(mousePosX-mouseOldX);
mouseDeltaY=(mousePosY-mouseOldY);
双修饰符=1.0;
双修饰符系数=0.1;
如果(me.isControlDown()){
修饰符=0.1;
}
如果(me.isshift down()){
修饰符=10.0;
}
if(me.isPrimaryButtonDown()){
cameraXForm.ry.setAngle(cameraXForm.ry.getAngle()-mouseDeltaX*modifierFactor*modifier*2.0);//+
cameraXForm.rx.setAngle(cameraXForm.rx.getAngle()+mouseDeltaY*modifierFactor*modifier*2.0);//-
}else if(me.isSecondaryButtonDown()){
double z=camera.getTranslateZ();
double newZ=z+mouseDeltaX*modifierFactor*modifier;
摄影机。setTranslateZ(newZ);
}否则如果(me.isMiddleButtonDown()){
cameraXForm2.t.setX(cameraXForm2.t.getX()+mouseDeltaX*modifierFactor*modifier*0.3);//-
cameraXForm2.t.setY(cameraXForm2.t.getY()+mouseDeltaY*modifierFactor*modifier*0.3);//-
}
}
});
}
私有void handleKeyboard(场景,最终节点根){
最终布尔值moveCamera=true;
scene.setOnKeyPressed(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
持续时间;
开关(event.getCode()){
案例Z:
if(event.isShiftDown()){
cameraXForm.ry.setAngle(0.0);
cameraXForm.rx.setAngle(0.0);
摄像头.setTranslateZ(-300.0);
}
cameraXForm2.t.setX(0.0);
cameraXForm2.t.setY(0.0);
打破
案例十:
if(event.isControlDown()){
if(axisGroup.isVisible()){
axisGroup.setVisible(false);
}否则{
setVisible(true);
}
}
打破
案例S:
if(event.isControlDown()){
if(moleculeGroup.isVisible()){
分子组。设置可见(假);
}否则{
分子组。设置可见(真);
}
scene.setCamera(subSceneCamera);
scene.setCamera(camera);
@Override
public void start(Stage primaryStage) throws Exception{
...
primaryStage.show();
scene.setCamera(camera);
}
private void buildScene() {
...
subScene.setLayoutX(100);
subScene.setLayoutY(100);
subScene.setCamera(subSceneCamera);
root.getChildren().addAll(subScene);
}
public class rotate3Dwithpanel extends Application
{
private double mouseOldX, mouseOldY = 0;
private Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
private Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS);
@Override
public void start(Stage stage) throws Exception
{
final PhongMaterial redMaterial = new PhongMaterial();
redMaterial.setSpecularColor(Color.ORANGE);
redMaterial.setDiffuseColor(Color.RED);
Box myBox = new Box(100, 100, 100);
myBox.setTranslateX(400);
myBox.setTranslateY(300);
myBox.setTranslateZ(400);
myBox.setMaterial(redMaterial);
Rectangle rectangle = new Rectangle();
rectangle.setX(200);
rectangle.setY(600);
rectangle.setWidth(200);
rectangle.setHeight(100);
rectangle.setFill(Color.GREY);
// to Set pivot points
rotateX.setPivotX(400);
rotateX.setPivotY(300);
rotateX.setPivotZ(400);
rotateY.setPivotX(400);
rotateY.setPivotY(300);
rotateY.setPivotZ(400);
rotateZ.setPivotX(400);
rotateZ.setPivotY(300);
rotateZ.setPivotZ(400);
// initialize the camera
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.getTransforms().addAll (rotateX, rotateY, new Translate(0, 0, 0));
Group root = new Group();
Group subRoot = new Group();
root.getChildren().add(rectangle);
Scene scene = new Scene(root, 1000, 1000, true);
SubScene subScene = new SubScene(subRoot, 800, 800, true, SceneAntialiasing.BALANCED);
subScene.setCamera(camera);
subRoot.getChildren().add(myBox);
root.getChildren().add(subScene);
// events for rotation
rectangle.setOnMousePressed(event -> {
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
rectangle.setOnMouseDragged(event -> {
if(event.isPrimaryButtonDown())
{
rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
}
});
stage.setTitle("JavaFX 3D Object");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}