射线及其衍生功能
一.何为射线
光线投射(RayCaster)可以向特定方向投射光线,并测试哪些对象与其相交。光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)
其中两个重要方法:
1.raycaster.setFromCamera(mouse, camera)
意为设定射线从相机出发,射入方向延鼠标所指。
mouse为在标准化设备坐标中鼠标的二维坐标 —— X分量与Y分量应当在-1到1之间。
其中e为事件,container为div元素name。
一般来说,我们使用raycaster射线,通常会搭配着事件。例如点击事件和鼠标滑动事件。
注意!!!
对于canvas所在div元素宽高的设定必须规范且有效,否则会导致射线与鼠标所指之处出现偏差,使功能出错。
2.raycaster.intersectObjects(scene.children)
此方法可以返回场景中射线所穿过的所有模型,并合成一个数组。
var intersects = raycaster.intersectObjects(scene.children);
一般来说,我们使用的都是这个模型数组中的第一个模型 -- intersects[0]
通过获取intersects,我们可以去控制其object和position等属性。
二.射线的衍生功能
1.模型移动分离export function Separate(object, afterPosition)
所需参数-object,afterPosition。
object为所需移动分离的模型参数,由射线在场景选定并传入。
afterPosition为模型移动完成时所处于的位置。
具体情况(示例):
通过Tween插件实现动画功能。
var tween = new TWEEN.Tween(object.position);
将所需移动分离之模型的坐标放入,表示需要改变的属性为position
tween.to( { x: afterPosition[0], y: afterPosition[1], z: afterPosition[2] },2000 );
再通过tween.to()方法,将afterPosition的值放入模型的三维坐标属性中,2秒的逐渐递加,形成动画
tween.start()
最后tween.start()开始执行动画。
2.相机移动
export function CameraMovement(controls, camera, object, afterPosition)
所需参数-controls,camera,object,afterPosition
controls:自由视角组件,需要其target属性,令相机所看之处一直处于指定位置。
camera:所改变的物体位置的模型,这里为相机,也可以直接传入camera 的position
object:controls.target所对的模型物体坐标。
afterPosition:相机最后所处的位置。
具体情况(示例):
本次我封装相机移动功能,对于动画最后controls.target所指的位置不会因为所选模型的不同而发生变化。
controls.target.set( object.position.x, object.position.y, object.position.z );
第一步将controls.target的值给设定好,但请注意,虽然你已经将所指方向设定好了,但是并不能在执行动画的时候令相机方向保持不变!!!
var tween01 = new TWEEN.Tween(camera.position); tween01.to( { x: afterPosition[0], y: afterPosition[1], z: afterPosition[2], }, 1500 );
之后便于上个功能一样,利用tween.to()去设定动画。
tween01.onUpdate(function () { controls.target.x = 0; controls.target.y = 0; controls.target.z = 0; //console.log(controls.target); controls.update(); });
!!!利用tween.onUpdate(),controls.update(),不断刷新controls.target,可解决动画执行过程中相机方向问题。
tween01.start();
动画开始。
3.模型**隐藏**
export function Disappear(object)
所需参数-object
object:所需隐藏的模型目标。
具体情况(示例):
此功能暂时并未完善
object.material.visible = false;
仅此一行代码,未用到tween插件。
可令模型瞬间消失,但是没有动画效果和令已消失模型重新出现的功能。
待改进。
4.鼠标滑动改变颜色
export class ChangeColor02
所需参数- raycaster,mouse,camera,scene,Color_transformation
raycaster:THREE.JS 的 Raycaster对象
mouse:屏幕中鼠标的位置信息
camera:相机,为raycaster的参数
scene:场景,为class中所需参数
Color_transformation:模型改变的颜色数据
具体情况(示例):
此功能以class(类)为基础
constructor(){ this.pickObject = null this.pickObjectSaveColor = 0 }
在外部实例化ChangeColor类
let pickHelper = new ChangeColor02();
构造方法将属性pickObject与pickObjectSaveColor初始化
类中方法:
pick(raycaster,mouse,camera,scene,Color_transformation){ if (this.pickedObject) { this.pickedObject.material.emissive.setHex(this.pickedObjectSavedColor); this.pickedObject = undefined; } raycaster.setFromCamera(mouse, camera); let intersects = raycaster.intersectObjects(scene.children); if (intersects.length) { this.pickedObject = intersects[0].object this.pickedObjectSavedColor = this.pickedObject.material.emissive.getHex(); this.pickedObject.material.emissive.setHex( 0xFFFF00) console.log(Color_transformation) } }
判定pickObject是否为null
若为0,则执行以下语句
raycaster.setFromCamera(mouse, camera); let intersects = raycaster.intersectObjects(scene.children); if (intersects.length) { this.pickedObject = intersects[0].object this.pickedObjectSavedColor = this.pickedObject.material.emissive.getHex(); this.pickedObject.material.emissive.setHex( 0xFFFF00) console.log(Color_transformation) }
获取被射线穿过的模型数组,选取第一个,利用pickObject和pickObjectSaveColor保存其模型的颜色数据,作为备份
再将之颜色改变。
若为1,则执行以下语句
if (this.pickedObject) { this.pickedObject.material.emissive.setHex(this.pickedObjectSavedColor); this.pickedObject = undefined; }