THREE.js 函数 - 转换以接受不同的初始旋转

Posted

技术标签:

【中文标题】THREE.js 函数 - 转换以接受不同的初始旋转【英文标题】:THREE.js function - convert to accept a different initial rotation 【发布时间】:2022-01-13 20:38:10 【问题描述】:

我正在尝试将此处找到的代码 http://benchung.com/smooth-mouse-rotation-three-js/ 转换为 AFRAME 组件。

如果初始旋转为“0 0 0”,这一切都很好,但现在我正在尝试设置不同的初始旋转。

@Piotr 请帮我把fiddle 放在一起

但基本上我希望能够设置初始旋转,然后使用其余功能在单击和拖动时旋转对象。

AFRAME.registerComponent('drag-rotate',
    schema :  
      mouseSpeed : default:1,
      touchSpeed : default:2,
      rotation   : type: 'vec3',
      disabled: default: false
    ,
    windowHalfX: window.innerWidth / 2,
    windowHalfY: window.innerHeight / 2,
    targetRotationX:0,
    targetRotationOnMouseDownX:0,
    targetRotationY:0,
    targetRotationOnMouseDownY: 0,
    mouseX:0,
    mouseXOnMouseDown:0,
    mouseY: 0,
    mouseYOnMouseDown: 0,
    init : function()
      this.ifMouseDown = false
      document.addEventListener('touchstart',this.onTouchStart.bind(this))
      document.addEventListener('touchend',this.onTouchEnd.bind(this))
      document.addEventListener('touchmove',this.onTouchMove.bind(this))
      document.addEventListener('mousedown',this.OnDocumentMouseDown.bind(this))
      window.addEventListener( 'resize', this.onWindowResize.bind(this) )
    ,
    update: function (oldData) 
      if(!AFRAME.utils.deepEqual(oldData.rotation, this.data.rotation))
        this.el.setAttribute('rotation',  this.data.rotation)
        this._targetRotation = this.el.object3D.rotation.clone()
        this.targetRotationX = this._targetRotation.x
        this.targetRotationY = this._targetRotation.y
      
    ,
    remove: function() 
      
      document.removeEventListener('touchstart',this.onTouchStart.bind(this))
      document.removeEventListener('mousedown',this.OnDocumentMouseDown.bind(this))
      window.removeEventListener( 'resize', this.onWindowResize.bind(this))
    ,
    onWindowResize: function () 
      this.windowHalfX = window.innerWidth / 2
      this.windowHalfY = window.innerHeight / 2
    ,
    OnDocumentMouseDown : function(event)

      this.ifMouseDown = ['A-SCENE', 'CANVAS'].includes(event.target?.tagName)

      if(this.ifMouseDown)
        document.addEventListener('mouseup',this.OnDocumentMouseUp.bind(this))
        document.addEventListener('mousemove',this.OnDocumentMouseMove.bind(this))
        this.mouseXOnMouseDown = event.clientX - this.windowHalfX
        this.targetRotationOnMouseDownX = this.targetRotationX

        this.mouseYOnMouseDown = event.clientY - this.windowHalfY
        this.targetRotationOnMouseDownY = this.targetRotationY
      

    ,
    OnDocumentMouseUp : function()
      this.ifMouseDown = false
      document.removeEventListener('mouseup',this.OnDocumentMouseUp.bind(this))
      document.removeEventListener('mousemove',this.OnDocumentMouseMove.bind(this))
    ,
    OnDocumentMouseMove : function(event)
    
      if(this.ifMouseDown)
        this.mouseX = event.clientX - this.windowHalfX;
        this.mouseY = event.clientY - this.windowHalfY;

        this.targetRotationY = this.targetRotationOnMouseDownY + (this.mouseY - this.mouseYOnMouseDown) * this.data.mouseSpeed/1000
        this.targetRotationX = this.targetRotationOnMouseDownX + (this.mouseX - this.mouseXOnMouseDown) * this.data.mouseSpeed/1000
      
    ,
    onTouchStart: function(event)  

      if (event.touches.length == 1) 
        this.ifMouseDown = ['A-SCENE', 'CANVAS'].includes(event.target?.tagName)
        this.x_cord = event.touches[ 0 ].pageX
        this.y_cord = event.touches[ 0 ].pageY

        document.addEventListener('touchend',this.onTouchEnd.bind(this))
        document.addEventListener('touchmove',this.onTouchMove.bind(this))
        this.mouseXOnMouseDown = event.touches[ 0 ].pageX - this.windowHalfX
        this.targetRotationOnMouseDownX = this.targetRotationX
        this.mouseYOnMouseDown = event.touches[ 0 ].pageX - this.windowHalfY
        this.targetRotationOnMouseDownY = this.targetRotationY

      
    ,
    onTouchMove: function(event)
      if(this.ifMouseDown)
        this.mouseX = event.touches[ 0 ].pageX - this.windowHalfX;
        this.mouseY = event.touches[ 0 ].pageY - this.windowHalfY;

        this.targetRotationY = this.targetRotationOnMouseDownY + (this.mouseY - this.mouseYOnMouseDown) * this.data.touchSpeed/1000
        this.targetRotationX = this.targetRotationOnMouseDownX + (this.mouseX - this.mouseXOnMouseDown) * this.data.touchSpeed/1000
        
    ,
    onTouchEnd: function(event)
      document.removeEventListener('touchend',this.onTouchEnd.bind(this))
      document.removeEventListener('touchmove',this.onTouchMove.bind(this))
      this.ifMouseDown = false
    ,
    tick: function()

      if(this.data.disabled)
        return
 
     this.el.object3D.rotation.y += ( this.targetRotationX - this.el.object3D.rotation.y ) * 0.1

     this.finalRotationY = (this.targetRotationY - this.el.object3D.rotation.x)
    
     if (this.el.object3D.rotation.x  <= 1 && this.el.object3D.rotation.x >= -1 ) 
      this.el.object3D.rotation.x += this.finalRotationY * 0.1
        
     if (this.el.object3D.rotation.x  > 1 ) 
      this.el.object3D.rotation.x = 1
        
     if (this.el.object3D.rotation.x  < -1 ) 
      this.el.object3D.rotation.x = -1
      
    ,
  );

我在更新函数中用 AFRAME 设置的初始角度和这里设置的不一样。即禁用此组件

启用它

如果我在示例代码中将这些值归零,则旋转为“0 0 0”并且它正常工作。

    this.el.setAttribute('rotation',  this.data.rotation)
    this._targetRotation = this.el.object3D.rotation.clone()
    this.targetRotationX = 0
    this.targetRotationY = 0

【问题讨论】:

Anwsered 太快了,再想一想我不确定这里有什么问题。我把代码扔进了fiddle,我不确定应该有什么不同 谢谢我应该这样做。但是,例如,如果您将旋转设置为“0 45 0”jsfiddle.net/na78pwou/2,那么它应该只在 Y 轴上旋转。不是。 感谢您的帮助@PiotrAdamMilewski 我已经更新了问题 - 基本上我希望能够设置初始轮换并尊重这一点。 【参考方案1】:

这个神奇的代码起作用了

 this.el.object3D.rotation.y += ( (this._targetRotation.y + this.targetRotationX) - this.el.object3D.rotation.y ) * 0.1
 this.finalRotationY = ((this._targetRotation.x + this.targetRotationY) - this.el.object3D.rotation.x)

【讨论】:

以上是关于THREE.js 函数 - 转换以接受不同的初始旋转的主要内容,如果未能解决你的问题,请参考以下文章

在 Three.js 中将经度和纬度转换为 xyz(为了旋转相机)的问题

three.js:结合 tween.js 围绕世界轴旋转对象

three.js如何让场景中模型跟随鼠标旋转呀

在 three.js 中移动相机、lookAt 和旋转

webgl之五彩光源

THREE.Mesh 的法线与原始模型不同