I have used the curved image target and by detecting it I have placed a gltf model and it keeps animating. My model has got a idle animation as well. I want the model to keep looping the idle animation until I place my cylindrical shape bottle on the ground (in other words if the distance between the image target and ground is bigger than a threshold value). When I will place the bottle on the ground (in other words, if the distance between the image target and ground is lesser than a threshold value) I want the model to run a different animation. How can I achieve this?
You can write some custom logic which remove the animation-mixer component from your .glb model then adds a new animation whent the threshold is met.
model.removeAttribute('animation-mixer', ' ')
model.setAttribute('animation-mixer', {
clip: 'animation1',
})
You can also take a look at our animation mixer sample project here:
and how to check if the threshold is met?
The basics is to detect the positon of the object3D of your image target to the detected ground at y=0
I would reference some of the logic in this project which can be expanded upon to check for this distance as an example.
you may do something along these lines:
AFRAME.registerComponent('distance-to-ground', {
init: function() {
this.el.addEventListener('object3dset', () => {
this.calculateDistance(); // Initial calculation
});
},
tick: function() {
this.calculateDistance(); // Continuous update each frame
},
calculateDistance: function() {
var position = this.el.object3D.position;
var distance = Math.abs(position.y); // Assuming the ground plane is y = 0
console.log('Distance to ground: ' + distance.toFixed(2) + ' meters');
// You can also set this distance to a property if you need to use it elsewhere
this.el.setAttribute('distance-to-ground', distance.toFixed(2));
}
});
Okay, thanks for this suggestion. This can be done but only when I assume that the ground is at y=0 or y = a fixed y-axis value. But what if I actually want a plane to be detected(preferably a horizontal plane as ground) and only when I place the image tracker on that plane, I want to trigger an event or perform a task?
Hello @Md_Akif_Zaman 8th Wall will always set the ground plane at y=0 so this will not change. 8th Wall detects the largest horizontal surface in your scene and sets this as y=0.
How can I detect if my image target or a any 3d object has collided with the ground (set by 8th wall as you said)?
You could try to calculate the distance of the image target to the detected surface at y=0. You could use some logic along these lines
AFRAME.registerComponent('check-proximity', {
schema: {
threshold: {type: 'number', default: 0.5} // Proximity threshold
},
init: function() {
// Initialize component.
this.wasClose = false; // Track if it was close previously
},
tick: function() {
// Check proximity on every frame.
const yPos = this.el.object3D.position.y;
const isClose = Math.abs(yPos - 0) <= this.data.threshold;
if (isClose && !this.wasClose) {
console.log('Image target is close to y=0');
this.wasClose = true;
} else if (!isClose && this.wasClose) {
console.log('Image target is not close to y=0');
this.wasClose = false;
}
}
});
but that would always be a static calculation, right? Or 8th wall keeps considering the newer biggest horizontal plane (currently visible on the screen) as the ground? or is it only considered once after the project initiates?
Yes, this is considered once after the project initiates. We place the scene y=0 at this position.