我有一些代码,我从旧的three.js脚本转换而来,我创建了一个aframe组件
组件将对象补间到摄像机前面的位置并旋转它以使其面向摄像机 . 我已经无法获得世界位置,因为对象位于层次结构的下方,现在对象补间到摄像机下方和左侧的位置 .
有什么想法,我需要改变,以获得相机前的对象?
我已经尝试并努力让这个组件在codepen中工作,但我会继续尝试举例 .
AFRAME.registerComponent('zoom-front-camera', {
schema: {
zooming: {type: 'boolean'},
},
_cameraEntity: null, //Camera Entity
_threeElement: null, //this.el in ThreeJS (Object3D)
_threeCamera: null, //Camera entity in ThreeJS (Object3D)
_initialQuaternion:null, //Initial Quaternion property
_initialPosition: null, //Initial Position property
_targetQuaternion: null, //Target Quaternion property
_targetPosition: null, //Target Position property
//Initialize var, add the event listeners & call the function to change element position
init: function() {
this._cameraEntity = this.el.sceneEl.camera.el
this.el.addEventListener('animation__position-begin', function() {
animationPlaying = true
})
this.el.addEventListener('animation__position-complete', function() {
animationPlaying = false
animationCompleted = true
})
this.retrieveData()
},
update: function() {
return (this.data.zooming) ? this.tweenHotspotToCamera() : this.tweenHotspotToCamera(true)
},
//Loop Function to update the rotation of the element during the position changement (by using Quaternion)
tick: function() {
if(animationCompleted) {
//Dezoom && Animation Completed => so we hide the image
if(!this.data.zooming) {
this.el.setAttribute('visible', false)
//Remove component to avoid keep ticking
this.el.removeAttribute('zoom-front-camera')
}
//Bind reversed zoom event on click
let clickEvent = {
'zoom-front-camera.zooming': !this.data.zooming,
}
this.el.setAttribute('event-set__click', clickEvent)
//Reinitialize animation
animationCompleted = false
return
}
if(!animationPlaying)
return
return (this.data.zooming)
? this.slerpEffect(this._initialPosition, this._targetPosition, this._initialQuaternion, this._targetQuaternion)
: this.slerpEffect(this._targetPosition, this._initialPosition, this._targetQuaternion, this._initialQuaternion)
},
retrieveData: function() {
this._threeElement = this.el.object3D
this._threeCamera = this._cameraEntity.object3D
//Copy the initial data
this._initialPosition = this._threeElement.position.clone()
this._initialQuaternion = this._threeElement.quaternion.clone()
//Some maths to obtain objects around the same size of the screen
//Retrieving the Field of View (FOV) from the camera attribute
const {fov} = this._cameraEntity.getAttribute('camera')
//Convert fov + reduce it
let fovInRad = degToRad(fov) / 2.5
let ratio=window.innerWidth/window.innerHeight //Assuming the FOV is vertical
let pLocal,cPos
let bbox = getCompoundBoundingBox(this._threeElement)
let sizeY = bbox.max.y-bbox.min.y
let sizeX = bbox.max.x-bbox.min.x
sizeX*= this._threeElement.scale.x
sizeY*= this._threeElement.scale.y
let tanFov = Math.tan(fovInRad)
let distY = sizeY/tanFov
let distX = ((sizeX/(ratio*tanFov)) < distY) ? distY : sizeX/(ratio*tanFov)
pLocal= new THREE.Vector3(0, 0, -distX)
cPos = this._threeCamera.position.clone()
cPos.y -= 1
//Apply the direction the camera is facing
this._targetPosition = pLocal.applyMatrix4(this._threeCamera.matrixWorld)
let targetLook = cPos.applyMatrix4(this._threeCamera.matrixWorld)
this._threeElement.position.copy(this._targetPosition)
this._threeElement.lookAt(targetLook)
this._targetQuaternion=this._threeElement.quaternion.clone()
//Take the original data back
this._threeElement.position.copy(this._initialPosition)
this._threeElement.quaternion.copy(this._initialQuaternion)
},
tweenHotspotToCamera: function(reversed=false) {
//Animation
const positionAnimation = {
property: 'position',
from: {...AFRAME.utils.clone(this._threeElement.position)},
to: (reversed) ? {...AFRAME.utils.clone(this._initialPosition.transformDirection(this._threeElement.matrixWorld))} : {...AFRAME.utils.clone(this._targetPosition.transformDirection(this._threeElement.matrixWorld))},
dur: 2000,
easing: 'easeInOutCubic',
startEvents: ['---non-existent-event---'], //Avoid auto-play of the animation
}
//Set the animation on the element
this.el.setAttribute('animation__position', positionAnimation)
//Retrieve the animation
const {animation} = this.el.components.animation__position
if(animation)
animation.play()
},
slerpEffect: function(initialP, finalP, initialQ, finalQ) {
let dstF= initialP.distanceTo(finalP)
let dstC= initialP.distanceTo(this._threeElement.position)
let k=dstC/dstF
THREE.Quaternion.slerp(initialQ, finalQ, this._threeElement.quaternion, k)
//Because few images are disappearing when you click on them
this.el.setAttribute('visible', true)
},
})