如何在3d世界中拾取鼠标

时间:2010-07-30 14:38:50

标签: opengl graphics 3d

我对如何在3D世界中拾取鼠标有一些疑问。

现在我在3d世界中有几个点,通过使用这些点我可以绘制曲线

我想用鼠标在这条曲线上选择一个点,可以改变3d世界的视口,所以我想知道在任何一个视口,当我在曲线附近按下鼠标按钮时,哪个点离鼠标最近?或者我选择了哪一点?

我不知道如何实施它,如果你知道,请帮助我。

感谢。祝你好运。

3 个答案:

答案 0 :(得分:3)

如果你试图点击离散点(可能是曲线上的节点),另一种方法是将它们投射回屏幕坐标并检查与鼠标位置的紧密匹配 - 因为这是在整数坐标中完成的,只需要大致准确(假设您的点数相差几个像素。

另一个技巧是在离屏缓冲区中重绘场景,每个点(或曲线上的位置)以不同的RGB颜色绘制 - 然后使用getPixel函数返回鼠标点下的颜色并查看点ID。这在有雾的复杂场景中不起作用。

答案 1 :(得分:2)

OpenGL有selection mode,您可以在其中获取鼠标单击的位置,并创建一个矩阵,该矩阵将绘图限制为鼠标周围的某个任意(小)区域(例如,7x7像素块)。然后,您可以绘制“东西”(曲线,点,等等),它将创建所有落入您定义的块内部的对象的记录。如果多个项目落入该区块内,您将获得所记录的任何记录,每个项目一条记录,按从前到后的z顺序排序。

完成后,您将获得与鼠标点击相近的点的记录。大多数时候,你只会使用最接近前面的,但偶尔你会想要做更多的工作来弄清楚它们中的哪一个(如果有多个,显然)真的最接近到原来的鼠标点击点。如果您决定这样做,gluProject和(可能)gluUnProject会很方便。

答案 2 :(得分:-1)

下面的java代码可以在3d屏幕中拾取原始形状(线,点等)或3d几何(立方体,球体等)并打印所选内容。

首先构建一个主类(ietuval1),然后构建一个公共类(即secim2)。

public class tuval1 {

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

new secim2();

}

}

import java.awt.GraphicsConfiguration;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import javax.media.j3d.Appearance;

import javax.media.j3d.BranchGroup;

import javax.media.j3d.Canvas3D;

import javax.media.j3d.PolygonAttributes;

import javax.media.j3d.Shape3D;

import javax.media.j3d.Transform3D;

import javax.media.j3d.TransformGroup;

导入javax.swing.JFrame;

导入javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.ColorCube;

import com.sun.j3d.utils.geometry.Primitive;

import com.sun.j3d.utils.geometry.Sphere;

import com.sun.j3d.utils.picking.PickCanvas;

import com.sun.j3d.utils.picking.PickResult;

import com.sun.j3d.utils.universe.SimpleUniverse;

public class secim2 extends MouseAdapter {     私人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);

    canvas.setSize(400, 400);

    SimpleUniverse universe = new SimpleUniverse(canvas);

    BranchGroup group = new BranchGroup();


    // create a color cube


       Vector3f vector = new Vector3f(-0.3f, 0.0f, 0.0f);

        Transform3D transform = new Transform3D();

        transform.setTranslation(vector);

        TransformGroup transformGroup = new TransformGroup(transform);

        ColorCube cube = new ColorCube(0.2f);

        transformGroup.addChild(cube);

        group.addChild(transformGroup);

        // create sphere

      Vector3f vector2=new Vector3f(+0.5f,0.0f,0.0f); 

      Appearance app=new Appearance();

      app.setPolygonAttributes(

 new PolygonAttributes(PolygonAttributes.POLYGON_LINE,

               PolygonAttributes.CULL_BACK,0.0f));

      Transform3D transform2= new Transform3D();

      transform2.setTranslation(vector2);

      TransformGroup transformGroup2=new TransformGroup(transform2) ;





      Sphere sphere= new Sphere(0.2f ,app);

      transformGroup2.addChild(sphere );

      group.addChild(transformGroup2);

        universe.getViewingPlatform().setNominalViewingTransform();

        universe.addBranchGraph(group);


      pickCanvas = new PickCanvas(canvas, group);

      pickCanvas.setMode(PickCanvas.BOUNDS);

     pencere.add(canvas);

      canvas.addMouseListener(this);


}

public void mouseClicked(MouseEvent o)

{

    pickCanvas.setShapeLocation(o);

    PickResult result = pickCanvas.pickClosest();

    if (result == null) {

       System.out.println("Nothing picked");

    } else {

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

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

       if (p != null) {

          // System.out.println("Selected");
         System.out.println(p.getClass().getName());

       } else if (s != null) {

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

       } else{

          System.out.println("null");

       }

    }

}

}