Am I rotating the 3D object correctly in the direction of movement? [SOLVED]

Hi all :raised_hand:

I’m trying to make the model turn smoothly and along a short path in the direction in which it is moving.

I wrote code that works:

        if vmath.length(direction) > 0  then
		local angle = math.atan2(-direction.x, -direction.z)
		local quat = vmath.quat_rotation_y(angle)
		local my_rotation = go.get_rotation()
		go.set_rotation(vmath.slerp(dt * self.speed, my_rotation, quat))
	end 

But the documentation says:

Slerp is computationally more expensive than lerp.

Did I do everything right or is there a better way?

In the console, after a few seconds of moving forward, some “large” rotation values ​​appear.
I don’t think that’s normal, right?

screen

1 Like

It looks good to me.

Those aren’t large number but in fact very small numbers. They’re so small they using exponent notation. Note the E, and -08, which means there’s 8 0’s before the first digit in the number.

1 Like

Okay, then maybe it will be useful to someone in the future.

function init(self)
	msg.post(".", "acquire_input_focus")
	msg.post("@render:", "use_camera_projection")
	msg.post("camera", "acquire_camera_focus")

	self.speed_rotation = 10
	self.speed = 6
	
	self.bindings = {
		forward = hash 'key_w',
		backward = hash 'key_s',
		left = hash 'key_a',
		right = hash 'key_d'
	}

	self.input = {
		forward = nil,
		backward = nil,
		left = nil,
		right = nil
	}
end

function update(self, dt)
	local direction = vmath.vector3()
	local input = self.input

	if input.forward then
		direction.z = -1
	elseif input.backward then
		direction.z = 1
	end

	if input.right then
		direction.x = 1
	elseif input.left then
		direction.x = -1
	end

	if vmath.length(direction) >= 1 then
		direction = vmath.normalize(direction)
	end

	if vmath.length(direction) > 0  then
		local angle = math.atan2(-direction.x, -direction.z)
		local quat = vmath.quat_rotation_y(angle)
		local my_rotation = go.get_rotation()
		print(go.get_rotation())
		go.set_rotation(vmath.slerp(dt * self.speed_rotation, my_rotation, quat))
	end 
	
	go.set_position(go.get_position()+direction*dt*self.speed)
end

function on_input(self, action_id, action)
	if not action_id then
		return
	end

	if action_id == self.bindings.right then
		self.input.right = not action.released or nil
	elseif action_id == self.bindings.left then
		self.input.left = not action.released or nil
	end

	if action_id == self.bindings.forward then
		self.input.forward = not action.released or nil
	elseif action_id == self.bindings.backward then
		self.input.backward = not action.released or nil
	end
end
2 Likes

this code helped me a lot.