2011-01-31 290 views
0

我希望当我点击屏幕上的特定点时,返回点击3D场景中的点的函数调用。例如,当我点击屏幕的左上角时,它应该返回x = 0,y = 1,z = 1;请帮我创建一个方法来做到这一点。如何根据鼠标点击获取3D中点的坐标?

编辑:

Root = new BranchGroup(); 

setLayout(new BorderLayout()); 
add(canvas3D,BorderLayout.CENTER); 
SimpleUniverse universe = new SimpleUniverse(canvas3D); 

Shape(); 
universe.addBranchGraph(Root); 
ViewingPlatform viewingPlatform = universe.getViewingPlatform(); 
OrbitBehavior behavior = new OrbitBehavior(canvas3D); 
behavior.setSchedulingBounds(bounds); 
viewingPlatform.setViewPlatformBehavior(behavior); 
viewingPlatform.setNominalViewingTransform(); 
} 

我使用NetBeans SimpleUniverse

+2

如何场景产生,你使用任何特定的3D引擎? – 2011-01-31 22:26:48

+2

不,我使用NetBeans。 – 2011-01-31 22:37:17

回答

3

恐怕答案并不简单。根据你场景中的内容,当你点击屏幕时,鼠标坐标应该改变。例如,如果您有两个物体,以便前面的物体遮挡后面的物体,那么您需要获取前面的物体坐标。这被称为mouse picking,有几种技术。我找到几个论坛来解释它是如何完成的并且有代码示例。

基本上这个想法是,你可以想象在用户和屏幕之间有激光(或其他可以投射光线的东西)。然后这个东西通过鼠标点击屏幕上的点来投影射线。然后将拾取光线路径上的任何物体,并可选择解析光线路径中物体的遮挡顺序,以为您提供距离“屏幕”最近的物体。

我对J3D并不熟悉,但是从一些教程中一起学习了下面的代码。它应该让你至少开始。您要查找的是底部的这条线Point3D intercept = ...

http://www.java3d.org/selection.html

package j3d_picking; 

import java.awt.*; 
import javax.swing.*; 
import javax.media.j3d.*; 
import com.sun.j3d.utils.universe.*; 
import com.sun.j3d.utils.picking.behaviors.*; 
import com.sun.j3d.utils.geometry.*; 
import com.sun.j3d.utils.picking.PickIntersection; 
import com.sun.j3d.utils.picking.PickResult; 
import com.sun.j3d.utils.picking.PickTool; 
import javax.vecmath.Point3d; 

public class HelloJava3D 
     extends JFrame 
{ 

    public HelloJava3D() 
    { 
     GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); 
     Canvas3D canvas3D = new Canvas3D(config); 

     BranchGroup scene = createSceneGraph(); 

     // SimpleUniverse is a Convenience Utility class 
     SimpleUniverse simpleU = new SimpleUniverse(canvas3D); 

     // This moves the ViewPlatform back a bit so the 
     // objects in the scene can be viewed. 
     simpleU.getViewingPlatform().setNominalViewingTransform(); 

     BoundingSphere behaveBounds = new BoundingSphere(); 
     ExamplePickBehavior behavior = new ExamplePickBehavior(canvas3D, scene, behaveBounds); 
     scene.addChild(behavior); 

     scene.compile(); 
     simpleU.addBranchGraph(scene); 

     getContentPane().add(canvas3D, BorderLayout.CENTER); 
    } // end of HelloJava3D (constructor) 

    public BranchGroup createSceneGraph() 
    { 
     // Create the root of the branch graph 
     BranchGroup objRoot = new BranchGroup(); 

     // Create a simple shape leaf node, add it to the scene graph. 
     // ColorCube is a Convenience Utility class 
     ColorCube cube = new ColorCube(0.4); 
     cube.setCapability(Node.ENABLE_PICK_REPORTING); 
     PickTool.setCapabilities(cube, PickTool.INTERSECT_FULL); 
     objRoot.addChild(cube); 

     return objRoot; 
    } // end of createSceneGraph method of HelloJava3D 

    public static void main(String[] args) 
    { 
     JFrame frame = new HelloJava3D(); 
     frame.setTitle("Hello Java3D"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setBounds(0, 0, 400, 300); 
     frame.setVisible(true); 
    } 

    private class ExamplePickBehavior extends PickMouseBehavior 
    { 

     public ExamplePickBehavior(Canvas3D canvas, BranchGroup bg, Bounds bounds) 
     { 
      super(canvas, bg, bounds); 
      setSchedulingBounds(bounds); 

      pickCanvas.setMode(PickTool.GEOMETRY_INTERSECT_INFO); 
      // allows PickIntersection objects to be returned 
     } 

     public void updateScene(int xpos, int ypos) 
     { 
      pickCanvas.setShapeLocation(xpos, ypos); 
      // register mouse pointer location on the screen (canvas) 

      Point3d eyePos = pickCanvas.getStartPosition(); 
      // get the viewer's eye location 

      PickResult pickResult = null; 
      pickResult = pickCanvas.pickClosest(); 
      // get the intersected shape closest to the viewer 

      if (pickResult != null) { 
       PickIntersection pi = pickResult.getClosestIntersection(eyePos); 
       // get the closest intersect to the eyePos point 
       Point3d intercept = pi.getPointCoordinatesVW(); 
       System.out.println(intercept); 
       // extract the intersection pt in scene coords space 
       // use the intersection pt in some way... 
      } 
     } // end of updateScene() 
    } // end of ExamplePickBehavior class 
} 
-1

enter code here下面的Java代码,打印在3D画面的3D对象的(形状)的中心坐标。结果为(x = -0.5,Y = 0.0,Z = 0.4)

  public class secim2 extends MouseAdapter{ 


private PickCanvas pickCanvas; 





public secim2(){ 
    JFrame pencere=new JFrame(); 
    pencere.setSize(300, 300); 
    pencere.setVisible(true); 
    JFrame frame = new JFrame(" 3D Box Select"); 

    GraphicsConfiguration config =     SimpleUniverse.getPreferredConfiguration(); 

    Canvas3D canvas = new Canvas3D(config); 

    SimpleUniverse universe = new SimpleUniverse(canvas); 

    BranchGroup group = new BranchGroup(); 


    // create a color cube 


     Transform3D transform= new Transform3D(); 
    Vector3d vector = new Vector3d(-0.5, 0.0, 0.4); 

     Transform3D transform = new Transform3D(); 

     transform.setTranslation(vector); 

     TransformGroup transformGroup = new TransformGroup(transform); 

     ColorCube cube = new ColorCube(0.1f); 

     transformGroup.addChild(cube); 

     group.addChild(transformGroup); 


     universe.getViewingPlatform().setNominalViewingTransform(); 

     universe.addBranchGraph(group); 


     pickCanvas = new PickCanvas(canvas, group); 

     pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO); 

    pencere.add(canvas); 

     canvas.addMouseListener(this); 


} 

public void mouseClicked(MouseEvent e) 

{ 



    pickCanvas.setShapeLocation(e); 

    PickResult result = pickCanvas.pickClosest(); 

    if (result == null) { 


    } else { 

     Primitive p = (Primitive)result.getNode(PickResult.PRIMITIVE); 

     Shape3D s = (Shape3D)result.getNode(PickResult.SHAPE3D); 

     if (p != null) { 

     System.out.println(p.getClass().getName()); 


     } else if (s != null) { 

      System.out.println(s.getClass().getName()); 

      Vector3f position = new Vector3f(); 

     s.getLocalToVworld(transform); 

     transform.get(position); 

     System.out.print(position); 

     // System.out.print(s.getLocalToVworld(transform2); 
     } else{ 

      System.out.println("null"); 

     } 

    } 

} 

}

公共类tuval1 {

public static void main(String[] args) { 
    // TODO Auto-generated method stub 

新secim2();

} 

}