123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- import {
- Raycaster,
- Vector2,
- Sprite,
- Math as ThreeMath
- } from 'three';
- import {render} from './Render.js';
- import Constant from './Constant.js';
- import {modelManager} from './ModelManager.js';
- export default class Control{
- constructor(scene,camera){
- this.scene = scene;
- this.camera = camera;
- this.selectModel = null;
- this.arrowControls = null;
- this.onDownPosition = null;
- this.onUpPosition = null;
- this.dragging = false;
- this.raycaster = new Raycaster();
- this.init();
- }
- init(){
- this.bindEvents();
- }
- bindEvents(){
- document.addEventListener('pointermove', this.onPointerMove.bind(this));
- document.addEventListener('pointerdown', this.onPointerDown.bind(this));
- document.addEventListener('pointerup', this.onPointerUp.bind(this));
- }
- onPointerMove( event ) {
- let pointer = new Vector2();
- pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
- pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
- this.setSelectModel(pointer);
- }
- onPointerDown( event ) {
- this.onDownPosition = new Vector2();
- this.onDownPosition.x = ( event.clientX / window.innerWidth ) * 2 - 1;
- this.onDownPosition.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
- this.dragging = true;
- }
- onPointerUp( event ) {
- this.onUpPosition = new Vector2();
- this.onUpPosition.x = ( event.clientX / window.innerWidth ) * 2 - 1;
- this.onUpPosition.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
- this.handleClick();
- this.dragging = false;
- }
- setSelectModel(pointer){
- // 通过摄像机和鼠标位置更新射线
- this.raycaster.setFromCamera( pointer, this.camera );
- // 计算物体和射线的焦点
- var intersects = this.raycaster.intersectObjects( this.scene.children );
- if(intersects && intersects[0])
- {
- for(let i=0;i<intersects.length;++i){
- let model = intersects[i].object;
- //if(model.type == "TransformControlsPlane"){
- if(model.type != "Mesh"&&model.type != "Group"&&model.type != 'Point'){
- continue;
- }
- if(model.parent && model.parent.type === "Group"){
- while(model.parent && model.parent.type === "Group"){
- model = model.parent;
- }
- }
-
- if(modelManager.tilesMeshesUUIDs.indexOf(model.uuid) == -1&&modelManager.meshesUUIDs.indexOf(model.uuid) == -1&&modelManager.pointMeshesUUIDs.indexOf(model.uuid) == -1)
- {
- continue;
- }
- if(this.selectModel == null){
- this.selectModel = model;
- //选中
- render.updateSelectModel(this.selectModel,true);
- }
- else if(this.selectModel.uuid == model.uuid){
- render.updateSelectModel(this.selectModel,true);
- }
- else if(this.selectModel.uuid != model.uuid){
- //恢复
- render.updateSelectModel(this.selectModel,false);
- this.selectModel = model;
- //选中
- render.updateSelectModel(this.selectModel,true);
- }
- return ;
- }
-
- }
- render.updateSelectModel(this.selectModel,false);
- this.selectModel = null;
- }
- /*
- selectObjects(pointer){
- // 通过摄像机和鼠标位置更新射线
- this.raycaster.setFromCamera( pointer, this.camera );
- // 计算物体和射线的焦点
- var intersects = this.raycaster.intersectObjects( this.scene.children );
- if(intersects && intersects[0])
- {
- let model = intersects[0].object;
- if(model.parent && model.parent.type === "Group"){
- while(model.parent && model.parent.type === "Group"){
- model = model.parent;
- }
- }
- Constant.tilesMaterial.color.set( 0xff0000 );
- }
- // for ( var i = 0; i < intersects.length; i++ ) {
- // intersects[ i ].object.material.color.set( 0xff0000 );
- // }
- }
- */
- onDocumentTouchStart( event ) {
- //通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)
- event.preventDefault();
- /*
- html的坐标轴是以左上角为(0,0),右下方向为正方向
- event.clientX=event.pageX返回当事件被触发时鼠标指针向对于浏览器可见区域的X坐标
- event.offsetX返回当前事件相对于事件源元素(srcElement)的X坐标
- event.screenX鼠标相对于用户显示器屏幕左上角的X坐标
- */
- event.clientX = event.touches[0].clientX;
- event.clientY = event.touches[0].clientY;
- this.onDocumentMouseDown( event );
- }
- onDocumentMouseDown( event ) {
- event.preventDefault();
- /*
- mouse.x = (2 * event.clientX - renderer.domElement.clientWidth) / renderer.domElement.clientWidth
- mouse.y = (renderer.domElement.clientHeight - 2 * event.clientY) / renderer.domElement.clientHeight
- 鼠标位置在一个边长为2的正方形内部,正方形中心为(0,0)点
- 因此,mouse.x和mouse.y的取值范围是[-1,1]
- */
- mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
- mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
- //设置该射线从相机位置发出,射向视场的鼠标位置
- raycaster.setFromCamera( mouse, camera );
- //判断射线是否穿过这些物体,参数是数组。返回的是与射线相交的结果数组,按距离从近到远有序排列
- var intersects = raycaster.intersectObjects( objects );
- if ( intersects.length > 0 ) {
- /*
- intersects[ 0 ] {
- distance: double
- face: Face3
- faceIndex: int
- object: Mesh
- point: Vector3
- uv: Vector2
- __proto__: Object
- }
- */
- //intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
- var particle = new Sprite( particleMaterial );
- //vector3不能直接用"等号"赋值。只能用copy进行复制。set方法需要分别传递x,y,z三个标量
- particle.position.copy( intersects[ 0 ].point );
- particle.scale.x = particle.scale.y = 16;
- scene.add( particle );
- }
- // Parse all the faces
- for ( var i in intersects ) {
- //这句已经无效了,因为face下面不存在material,face下存在color,但是即使改变color也改变不了面的颜色
- //intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xffffff | 0x80000000 );
- intersects[ i ].object.material.color.setHex( Math.random() * Constant.defaultColor );
- }
- }
- handleClick(){
- if ( this.selectModel != null && this.onDownPosition.distanceTo( this.onUpPosition ) === 0 ) {
- this.arrowControls.attach( this.selectModel );
- this.arrowControls.setMode('translate');
- //this.arrowControls.setMode('rotate');
- }
- else if(this.selectModel == null && this.onDownPosition.distanceTo( this.onUpPosition ) === 0){
- this.arrowControls.detach( );
- }
- this.onDownPosition = new Vector2();
- this.onUpPosition = new Vector2();
- }
- }
|