Howdy yall, super new to THREE.JS and could use some help. I have a codepen with a sphere mesh and a jet mesh. Currently the code tells the sphere to rotate in relation to the mouse movement but I would like to apply that rotation to the jet instead. Any help is greatly appreciated.
Hello.
I hope this helps you.
Below is the suggest code.
GLTFLoader
let myModel; // NewCode
loader.load('https://assets.codepen.io/1618468/F-16D_1.gltf', function ( gltf ) {
myModel = gltf.scene; // NewCode
//adds 3d object to scene after loading
scene.add(myModel);
...etc
animate() Function
onst animate = () =>
{
targetX = mouseX * .001
targetY = mouseY * .001
const elapsedTime = clock.getElapsedTime()
//Update objects - increase number to create automated animation
sphere.rotation.x = 0 * elapsedTime
sphere.rotation.y = 0 * elapsedTime
sphere.rotation.x += 2 * (targetY - sphere.rotation.x)
sphere.rotation.y += 1.5 * (targetX - sphere.rotation.y)
// NewCode
if (myModel){
myModel.rotation.copy(sphere.rotation.clone())
}
...etc
Result
Thank you ShoOsaka!
How do I remove the sphere completely but keeping the jet rotating?
Is it possible to add easing or damping to this rotation?
This code works with the sphere:
sphere.rotation.x += 2 * (targetY - sphere.rotation.x)
sphere.rotation.y += 1.5 * (targetX - sphere.rotation.y)
When I try to replace the sphere with myModel I get a console error. ;(
myModel.rotation.x += 2 * (targetY - myModel.rotation.x)
myModel.rotation.y += 1.5 * (targetX - myModel.rotation.y)
Uncaught TypeError: Cannot read properties of undefined (reading ‘rotation’)
What am I doing wrong?
Try it the way I did with the squirrel
BeginnerExample step 3
Mr.DeltaFrog
I didn’t make it clear enough.
“MyModel” is Async Object.
Before Loading “MyModel”, Animate Functions is moving.
for that reason, it needs "if (my Model){}"in animate Functions.
Below this put Sample Code.
if (myModel){
myModel.rotation.x += 2 * (targetY - myModel.rotation.x);
myModel.rotation.y += 1.5 * (targetX - myModel.rotation.y);
}
if you want to remove sphere objects, sphere removed or set “visiable” “false”
“remove objects”
function animate () {
targetX = mouseX * .001
targetY = mouseY * .001
const elapsedTime = clock.getElapsedTime()
if (myModel){
myModel.rotation.set(targetY, targetX, myModel.rotation.z);
// Sphere Remove
if (sphere.parent === scene){{
scene.remove(sphere);
sphere.material.dispose();
sphere.geometry.dispose();
}
}
// Render
renderer.render(scene, camera)
// Call tick again on the next frame
window.requestAnimationFrame(animate)
}
“visible: false”
if (myModel){
myModel.rotation.set(targetY, targetX, myModel.rotation.z);
sphere.visible = false; // Here
}
Also, easing can be expressed as “value += (target value - current value) * deceleration value”.
EasingExample
let mouseX
let mouseY
let targetX
let targetY
const windowHalfX = window.innerWidth / 2
const windowHalfY = window.innerHeight / 2
let targetRotation = new THREE.Vector2();
let currentRotation = new THREE.Vector2();
let rotationSpeed = 0.01;
function onDocumentMouseMove (event) {
mouseX = (event.clientX - windowHalfX)
mouseY = (event.clientY - windowHalfY)
targetRotation.x = mouseX;
targetRotation.y = mouseY;
}
const clock = new THREE.Clock()
let isEasing = true;
function animate () {
let d = .001;
targetX = mouseX * d;
targetY = mouseY * d;
currentRotation.x += (targetRotation.x - currentRotation.x) * rotationSpeed;
currentRotation.y += (targetRotation.y - currentRotation.y) * rotationSpeed;
const elapsedTime = clock.getElapsedTime()
if (myModel){
if (isEasing){
myModel.rotation.set(currentRotation.y * Math.PI / 180, currentRotation.x * Math.PI / 180, myModel.rotation.z);
}
else {
myModel.rotation.set(targetY, targetX, myModel.rotation.z);
}
if (sphere.parent === scene){
scene.remove(sphere);
sphere.material.dispose();
sphere.geometry.dispose();
}
}
// Render
renderer.render(scene, camera)
// Call tick again on the next frame
window.requestAnimationFrame(animate)
}
animate()
i hope i can help you
Thank you ShoOsaka! Very very helpful. Thank you for explaining!
I added the easing code, thank you! My problem now is the GLTF keeps rotating past where I wish it to stop. https://codepen.io/deltafrogcraft/pen/XWPyOoj
This previous setup shows where I wish the GLTF rotation to stop.
How would I restrict the rotation amount on the loaded GLTF so it does not rotate past a desired amount?
My goal is to create a similar functionality as the arrow grid here: https://www.refokus.com/
Mr.DeltaFrog
I’m glad it went well.
To control the rate of rotation, we need to add an IF statement before the rotation.
Three.js has a convenient function “MathUtils.radToDeg” that makes it easy to understand angles, and you can write it using this.
How to write sample code
This will result that changes “targetX” by -10 to +10 degrees and “targetY” by -5 to 5 degrees.
if (myModel){
if (
THREE.MathUtils.radToDeg(targetY) > -5 && THREE.MathUtils.radToDeg(targetY) < 5 &&
THREE.MathUtils.radToDeg(targetX) > -10 && THREE.MathUtils.radToDeg(targetX) < 10
){
myModel.rotation.set(targetY, targetX, myModel.rotation.z);
}
}
resultCapture
I hope it goes well.