Easiest way for straight path animation?

Hello community, I hope you are having a nice weekend :confetti_ball:

I have one question which I can’t wrap my head around. In my scene, I have a car, which has speed and rim size controls, all those things work nicely.

But as you can imagine, I want my car to drive only in specific area, so it doesn’t go out of the scene.

The issue is, I don’t know how to do it properly. I have tried it with “if” statements, checking if car has reached a certain position and then animating it again, but that logic doesn’t seem to work well, I wonder maybe it is possible to somehow set boundaries or something?

My ultimate goal would be to see car going:

  1. Straight until water
  2. Then it turns 180 degrees (I will just rotate all wheels and car frame itself)
  3. And then again straight to end of plane
  4. Turn around and then again go till the water… etc

And this cycle should repeat infinitely (I suppose you get this idea).

If you have any thoughts or ideas, they are all welcome. And here is my JS part of the code so you can take a look at it: Car project - Pastebin.com

Just the first thought, popped in my head:
https://jsfiddle.net/prisoner849/pgceahbd/

You also can use Tween.js or GSAP libraries.

1 Like

Thanks for the idea, I have never used vectors before, so this is a bit new for me. But I suppose for this to work, I would have to apply this function to my whole 5 elements (4 wheels and car body) or somehow stitch them all together to one piece? I have tried this one one of my cars wheels, it goes, but not quite in to the direction I want it to, rather than forward.

var lim = 5;
var clock = new THREE.Clock();
var speed = 1;
var dir = new THREE.Vector3(4, 0, 0).normalize();
var pos = new THREE.Vector3();
var lookAt = new THREE.Vector3();

renderer.setAnimationLoop(() => {

	pos.copy(wheel_front_right.position).addScaledVector(dir, speed * clock.getDelta());

if (Math.abs(pos.length()) >= lim) {
	
	var posDif = Math.abs(pos.length()) - lim;
	dir.negate();
	pos.addScaledVector(dir, posDif);

}
wheel_front_right.position.copy(pos);
lookAt.copy(pos).add(dir);
wheel_front_right.lookAt(lookAt);

renderer.render(scene, camera);
})

I set X axis here var dir = new THREE.Vector3(4, 0, 0).normalize(); (I suppose that’s where you set the movement) but like mentioned, it got rotated weirdly.

I managed to integrate slider values to the speed inside this movement function, so now I can adjust it, which is good.

I just need to figure out that thing with rotation of wheels and then I would somehow make it work.

Why do you move a wheel instead of the whole car?

My car is constructed of 5 sperate objects, car frame and 4 separate wheels (all with animations set seperatly) so I’m not quite sure how I should apply that movement to my whole car, since if I will apply it to the car frame, it would work I guess, but the wheels will not go back together with frame and carry on driving off the scene. Maybe I’m just not grasping the whole concept yet, I would be pleased if you could explain.

I’ve updated the fiddle :slight_smile: Take a look at how the things added to each other.

1 Like

Will the car’s path be pre-determined in the animation? Or would you eventually be adding controls for a user to steer it or something like that?

1 Like

There’s pre-built car controls here:

https://threejs.org/examples/#webgl_materials_cars

They should work with any generic car model (4 wheels and a body, optional steering wheel). You can also take a look at how the camera follows the car (click “follow camera”), and how the car and camera jump back to the center of the map when it drives too far.

1 Like

Yes, path is pre-determined, so far no need of user controls for it, just a simple forward and backwards movement.

Alright, so I have used a group and combined my car with my wheels. Now I have added whole car to your given algorithm, which is good already, but I still have a few issues (pardon me if I’m too rookie to fully understand that algorithm, doing my best at learning three.js).

  1. My car moves sideways as opposed to moving forward, any ideas how I can change direction? (it is vectors’ direction as I understand).
  2. Wheels do not spin. I saw you have added wheels to your fiddle with arrays and functions but that’s a bit out league for me just for now, would there be any “amateur” way to make them spin? I tried adding wheel_front_right.rotation.z = some value for testing in the whole car moving function, but that doesn’t seem to work.

My current setup looks like this:

//movement
	var lim = 20;
	var clock = new THREE.Clock();
	var dir = new THREE.Vector3(0, 0, 250).normalize();
	var pos = new THREE.Vector3();
	var lookAt = new THREE.Vector3();

	renderer.setAnimationLoop(() => {

		pos.copy(car_frame.position).addScaledVector(dir, controlBoxParams.carSpeed * clock.getDelta()); 
	
	if (Math.abs(pos.length()) >= lim) {
		
		var posDif = Math.abs(pos.length()) - lim;
		dir.negate();
		pos.addScaledVector(dir, posDif);
	
	}
	car_frame.position.copy(pos);
	lookAt.copy(pos).add(dir);
	car_frame.lookAt(lookAt);
	
	renderer.render(scene, camera);
	})

ezgif-6-d869031d7c0f

1 Like

I’ve forked the fiddle and made some changes.
https://jsfiddle.net/prisoner849/p8mx314L/
Now the wheels are children of the frame too (note their y-coordinates in comparison to the previous fiddle).
So, the rest is to change the vector of direction. It’s THREE.Vector3(1, 0, 0).
No need to put big numbers in the direction vector, as it’s normalized, means its length is always equals to 1.

Perfect, I have managed to deal with the wheels, now they spin nicely, thank you!

Now only one last issue left, even though when I set vector to THREE.Vector3(1, 0, 0) the car moves in the right direction, its object position (as a whole) is not right, it seems to be facing to the left. I tried adding car_frame.rotation.y = Math.PI; in the function to get it rotated, but that doesn’t work, I guess function overrides everything.

My current issue with cars’ position itself, once I fix it, I will call this a WIN :pray:

It’s because you’ve aligned your car along x-axis. Whereas I did it along z-axis, as I (planned to) use .lookAt() method.

Yeah, noticed that just now. Any ideas how could I get around this? I could spin whole scene around so car would go its path, but that’s a bit rough, maybe there is any way to make it follow the X axis as opposed to Y in your provided movement function?

Aligned the car along X-axis. Removed the using of .lookAt(). Used just rotation of the car.
https://jsfiddle.net/prisoner849/qxvsLrhg/

4 Likes

Perfection! Modified code for my thing and it worked, so happy.

Thank you @prisoner849, you were amazing at helping me, props to you!

You’re welcome :beers:

… and not only you @morphix here at this thing :blue_car:, but many other questioners before it. One of them was me. :slightly_smiling_face:

If you look into the Collection of examples from discourse.threejs.org, you can see his many :trophy: helpful examples.

Many, many thanks for that! :+1::+1::+1:

4 Likes

You can also find many great examples of @prisoner849 in his “Youngling’s diaries” codepen :smiley:

4 Likes