के रूप में @ jdub1581 बताते हैं, Camera
दृश्य पर अपने 3 डी objets के साथ माउस आंदोलन को बाध्य करने के लिए महत्वपूर्ण है।
स्टार्टर के लिए, हम सार्वजनिक एपीआई PickResult
के बारे में जानते हैं, जो हमें कैमरे की स्थिति से किए गए कुछ रे ट्रेसिंग तकनीकों के आधार पर माउस के साथ 3 डी ऑब्जेक्ट का चयन करने की अनुमति देता है।
लेकिन एक बार हमारे पास एक वस्तु है, इसे स्थानांतरित करना एक अलग समस्या है।
ओपनजेएफएक्स भंडार पर खिलौने परियोजना में Camera3D कक्षा को इस समस्या के समाधान (3 डी ऑब्जेक्ट्स को 3 डी स्पेस में ले जाने) के लिए एक समाधान की तलाश में है।
/*
* returns 3D direction from the Camera position to the mouse
* in the Scene space
*/
public Vec3d unProjectDirection(double sceneX, double sceneY,
double sWidth, double sHeight) {
}
जब से तुम गणितीय स्पष्टीकरण के लिए कहा, इस विधि त्रिकोणमिति आप देख रहे थे उपयोग करता है:
यह एक promissing विधि unProjectDirection
कहा जाता है। यह आपको एक 3D सदिश (एक्स, वाई) माउस निर्देशांक के आधार पर दे देंगे, एक निजी Vec3d
वर्ग (है कि हम सार्वजनिक Point3D
से बदल सकते हैं) का उपयोग: में एक सामान्यीकृत वेक्टर पाने के लिए
double tanOfHalfFOV = Math.tan(Math.toRadians(camera.getFieldOfView()) * 0.5f);
Vec3d vMouse = new Vec3d(tanOfHalfFOV*(2*sceneX/sWidth-1), tanOfHalfFOV*(2*sceneY/sWidth-sHeight/sWidth), 1);
कुछ आगे परिवर्तनों लागू होते हैं दृश्य निर्देशांक।
अगला चरण इस सामान्यीकृत वेक्टर को असली निर्देशांक में बदल देगा, केवल कैमरे से ऑब्जेक्ट से दूरी का उपयोग करके, नतीजे पर दिए गए ऑब्जेक्ट पर, ऑब्जेक्ट स्थिति को बदल देगा।
मूल रूप से, इस कोड स्निपेट को एक वस्तु खींच की पूरी प्रक्रिया की रूपरेखा:
scene.setOnMousePressed((MouseEvent me) -> {
vecIni = unProjectDirection(me.getSceneX(), me.getSceneY(),
scene.getWidth(),scene.getHeight());
distance=me.getPickResult().getIntersectedDistance();
});
scene.setOnMouseDragged((MouseEvent me) -> {
vecPos = unProjectDirection(mousePosX, mousePosY,
scene.getWidth(),scene.getHeight());
Point3D p=vecPos.subtract(vecIni).multiply(distance);
node.getTransforms().add(new Translate(p.getX(),p.getY(),p.getZ()));
vecIni=vecPos;
distance=me.getPickResult().getIntersectedDistance();
});
और यह एक पूर्ण काम कर बुनियादी उदाहरण है:
public class Drag3DObject extends Application {
private final Group root = new Group();
private PerspectiveCamera camera;
private final double sceneWidth = 800;
private final double sceneHeight = 600;
private double mousePosX;
private double mousePosY;
private double mouseOldX;
private double mouseOldY;
private final Rotate rotateX = new Rotate(-20, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(-20, Rotate.Y_AXIS);
private volatile boolean isPicking=false;
private Point3D vecIni, vecPos;
private double distance;
private Sphere s;
@Override
public void start(Stage stage) {
Box floor = new Box(1500, 10, 1500);
floor.setMaterial(new PhongMaterial(Color.GRAY));
floor.setTranslateY(150);
root.getChildren().add(floor);
Sphere sphere = new Sphere(150);
sphere.setMaterial(new PhongMaterial(Color.RED));
sphere.setTranslateY(-5);
root.getChildren().add(sphere);
Scene scene = new Scene(root, sceneWidth, sceneHeight, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.web("3d3d3d"));
camera = new PerspectiveCamera(true);
camera.setVerticalFieldOfView(false);
camera.setNearClip(0.1);
camera.setFarClip(100000.0);
camera.getTransforms().addAll (rotateX, rotateY, new Translate(0, 0, -3000));
PointLight light = new PointLight(Color.GAINSBORO);
root.getChildren().add(light);
root.getChildren().add(new AmbientLight(Color.WHITE));
scene.setCamera(camera);
scene.setOnMousePressed((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
PickResult pr = me.getPickResult();
if(pr!=null && pr.getIntersectedNode() != null && pr.getIntersectedNode() instanceof Sphere){
distance=pr.getIntersectedDistance();
s = (Sphere) pr.getIntersectedNode();
isPicking=true;
vecIni = unProjectDirection(mousePosX, mousePosY, scene.getWidth(),scene.getHeight());
}
});
scene.setOnMouseDragged((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
if(isPicking){
vecPos = unProjectDirection(mousePosX, mousePosY, scene.getWidth(),scene.getHeight());
Point3D p=vecPos.subtract(vecIni).multiply(distance);
s.getTransforms().add(new Translate(p.getX(),p.getY(),p.getZ()));
vecIni=vecPos;
PickResult pr = me.getPickResult();
if(pr!=null && pr.getIntersectedNode() != null && pr.getIntersectedNode()==s){
distance=pr.getIntersectedDistance();
} else {
isPicking=false;
}
} else {
rotateX.setAngle(rotateX.getAngle()-(mousePosY - mouseOldY));
rotateY.setAngle(rotateY.getAngle()+(mousePosX - mouseOldX));
mouseOldX = mousePosX;
mouseOldY = mousePosY;
}
});
scene.setOnMouseReleased((MouseEvent me)->{
if(isPicking){
isPicking=false;
}
});
stage.setTitle("3D Dragging");
stage.setScene(scene);
stage.show();
}
/*
From fx83dfeatures.Camera3D
http://hg.openjdk.java.net/openjfx/8u-dev/rt/file/5d371a34ddf1/apps/toys/FX8-3DFeatures/src/fx83dfeatures/Camera3D.java
*/
public Point3D unProjectDirection(double sceneX, double sceneY, double sWidth, double sHeight) {
double tanHFov = Math.tan(Math.toRadians(camera.getFieldOfView()) * 0.5f);
Point3D vMouse = new Point3D(tanHFov*(2*sceneX/sWidth-1), tanHFov*(2*sceneY/sWidth-sHeight/sWidth), 1);
Point3D result = localToSceneDirection(vMouse);
return result.normalize();
}
public Point3D localToScene(Point3D pt) {
Point3D res = camera.localToParentTransformProperty().get().transform(pt);
if (camera.getParent() != null) {
res = camera.getParent().localToSceneTransformProperty().get().transform(res);
}
return res;
}
public Point3D localToSceneDirection(Point3D dir) {
Point3D res = localToScene(dir);
return res.subtract(localToScene(new Point3D(0, 0, 0)));
}
public static void main(String[] args) {
launch(args);
}
}
है कि आप उठा और खींचने की अनुमति देगा दृश्य पर क्षेत्र:
यह प्रकाशन का हिस्सा नहीं है आईसी एपीआई, लेकिन आप कैमराहेल्पर का उपयोग करने का प्रयास कर सकते हैं .. में 3 विधियां हैं, जिन्हें आप चाहते हैं ** है।pickProjectionPlane (कैमरा, एक्स, वाई) – jdub1581