Away3D学习笔记-空间点捕捉

项目的基本技术要求,就是能捕捉用户在舞台上点击的3D坐标。

首先这涉及侦听MouseDown事件,如果Scene来侦听,当舞台上没东西时,是不会触发鼠标事件的,因此只能用Stage来侦听,而stage侦听的鼠标坐标是舞台的相对坐标,这里就需要一系列换算。

基本思路就是:将舞台坐标先换算为View3D的坐标,再通过Camera与该点的连线与坐标平面相交来计算点。

舞台坐标换View坐标可以以View的MouseX,MouseY属性为参数,调用Camera的unproject来计算。计算相交这部分代码不用自己写,Away3D的Plane3D对象封装了相关函数。因此代码很简洁:

 

	        private function onmd(e:MouseEvent):void
{
var pl:Plane3D = new Plane3D();
pl.fromNormalAndPoint(new Vector3D(0, 0, -1), new Vector3D());
var v:Vector3D = camera.unproject(view.mouseX, view.mouseY)
v=v.add(camera.position);
var p:Vector3D = pl.getIntersectionLineNumbers(v, camera.position);
}

pl.fromNormalAndPoint是创建一个虚拟平面,第一个参数是平面法向,(0,0,-1)就是面向屏幕的面,第二个参数是平面上一点,直接默认在零点即可。

camera.unproject是调用Camera对象的投影方法得到一个坐标值,但这个值是相对于Camera的坐标,所以再加上Camera的坐标就成了绝对坐标。

pl.getIntersectionLineNumbers,函数名字有点长:(,参数是两个点,两点确定一条直线,返回的就是虚拟平面上的点了。

还有一种简单粗暴但有效的办法确定点,那就是创建一个真实的平面做坐标平面,然后监听平面的MouseDown事件,通过事件参数里的SceneX,SceneY,SceneZ来得到空间坐标,这种办法绝对不会错,唯一的问题就是如果平面被别的物体挡住了,MouseDown事件就失效了。

通过实验比较发现,这两种办法确定下来的点的坐标很相似,但后者正好比前者的坐标大了整1.2倍。造成这个诡异误差的原因不明,所以只好手工把前者产生的坐标扩大1.2倍使用了。

p.scaleBy(1.2);

然后我试图从坐标原点画一条线到鼠标点击位置:

var l:LineSegment = new LineSegment();
l.end = new Vertex(0,0,p.z);
l.start = new Vertex(p.x, p.y,p.z);
l.material = new WireframeMaterial(0xff0000);
scene.addChild(l);

问题更诡异了,终点居然比我鼠标点的位置还要长,重新检查两种方法得到的坐标值,发现那个倍数已经变成了1.15。

为了确认那个倍数到底是不是常数,于是我调整Camera位置,focuszoom值继续实验。发现引起误差的原因来自于focus值,解决办法是让focus无限接近0,为了弥补focus过小导致物体太远,再把zoom放大相应倍数。Away3D里focus默认是100,zoom默认是10。这里我设focus为0.1,zoom就是10000。

在实际应用中,要获得某个物体的某个面上的点除了用传统的监听MouseDown外,也可以利用直线和面交点的办法,在创建Plane3D对象时,将物体上某个面的法向量和一个点作为参数。法向量和点用如下方法获取:

 

view.hitManager.elementVO  as FaceVO).face.normal;
view.hitManager.elementVO  as FaceVO).face.v0.position;

View.hitManage用于获取当前点击的一系列属性,类似于MouseEvent3D对象,用于非MouseEvent3D事件。上面两行代码第一行获取法向量,第二行获取被点击面上的一个点,v0是vertexs类,position是vector3D类。

转载于:https://www.cnblogs.com/wocdev/archive/2010/12/05/1897265.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值