Hi we are using 8th wall to place gaussian splat models in AR and we are having trouble with the cursor becoming too small in the far-away distance. A simple solution would be to not have the cursor travel too far away from the user but we have been told by our dev that this is not an option in the code as of yet.
Our first hack was to make the model render quite large so that even in the far distance, the model would still be a nice size to be viewed on a phone. But then, obviously, when the model is placed close by, the render will be far too big to be enjoyed properly.
Does anyone have another solution to this problem? We render plants, so they are not very big and get way too small very fast.
Hereβs an edited version of the cursor component that has a max distance parameter.
const tapPlaceCursorComponent = {
schema: {
maxDistance: { type: 'number', default: 10 } // Maximum distance in meters
},
init() {
this.raycaster = new THREE.Raycaster()
this.camera = document.getElementById('camera')
this.threeCamera = this.camera.getObject3D('camera')
this.ground = document.getElementById('ground')
// 2D coordinates of the raycast origin, in normalized device coordinates (NDC)---X and Y
// components should be between -1 and 1. Here we want the cursor in the center of the screen.
this.rayOrigin = new THREE.Vector2(0, 0)
this.cursorLocation = new THREE.Vector3(0, 0, 0)
this.el.sceneEl.addEventListener('click', (event) => {
// Check if cursor is within maxDistance
const distance = this.cursorLocation.distanceTo(this.threeCamera.position)
if (distance > this.data.maxDistance) {
console.warn('Cannot place object: Too far from camera')
return
}
// Create new entity for the new object
const newElement = document.createElement('a-entity')
// Spawn model at location of the cursor
newElement.setAttribute('position', this.el.object3D.position)
const randomYRotation = Math.random() * 360
newElement.setAttribute('rotation', `0 ${randomYRotation} 0`)
newElement.setAttribute('visible', 'false')
newElement.setAttribute('scale', '0.0001 0.0001 0.0001')
newElement.setAttribute('gltf-model', '#treeModel')
newElement.setAttribute('shadow', {receive: false})
this.el.sceneEl.appendChild(newElement)
newElement.addEventListener('model-loaded', () => {
// Once the model is loaded, we are ready to show it popping in using an animation
newElement.setAttribute('visible', 'true')
newElement.setAttribute('animation', {
property: 'scale',
to: '10 10 10',
easing: 'easeOutElastic',
dur: 800,
})
})
})
},
tick() {
// Raycast from camera to 'ground'
this.raycaster.setFromCamera(this.rayOrigin, this.threeCamera)
const intersects = this.raycaster.intersectObject(this.ground.object3D, true)
if (intersects.length > 0) {
const [intersect] = intersects
this.cursorLocation = intersect.point
}
// Only update cursor position if within maxDistance
const distance = this.cursorLocation.distanceTo(this.threeCamera.position)
if (distance <= this.data.maxDistance) {
this.el.object3D.position.y = 0.1
this.el.object3D.position.lerp(this.cursorLocation, 0.4)
this.el.object3D.rotation.y = this.threeCamera.rotation.y
}
},
}
export { tapPlaceCursorComponent }
You just need to replace your current tap-place-cursor.js and then in body.html replace your tap-place-cursor component attribute with something like this: