1 --converts yaw to degrees
2 local degrees = function(yaw)
4 return(yaw*180.0/math.pi)
7 local degree_round = function(degree)
8 return(degree + 0.5 - (degree + 0.5) % 1)
11 local radians_to_degrees = function(radians)
12 return(radians*180.0/math.pi)
15 local dir_to_degrees = function(dir)
17 x = radians_to_degrees(dir.x),
18 y = radians_to_degrees(dir.y),
19 z = radians_to_degrees(dir.z)
24 local test_function(dir) { --q
27 -- roll (x-axis rotation)
28 local sinr_cosp = 2 * (dir.w * dir.x + dir.y * dir.z)
29 local cosr_cosp = 1 - 2 * (dir.x * dir.x + dir.y * dir.y)
30 angles.roll = atan2(sinr_cosp, cosr_cosp)
32 -- pitch (y-axis rotation)
33 local sinp = 2 * (dir.w * dir.y - dir.z * dir.x)
35 angles.pitch = std::copysign(M_PI / 2, sinp); -- use 90 degrees if out of range
37 angles.pitch = std::asin(sinp);
39 -- yaw (z-axis rotation)
40 double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
41 double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
42 angles.yaw = std::atan2(siny_cosp, cosy_cosp);
48 --a movement test to move the head
49 mob.move_head = function(self)
51 --we're multiplying this to set the x and z where the head is
52 local pos = self.object:get_pos()
53 local body_yaw = self.object:get_yaw() - (math.pi/2)
54 local dir = vector.multiply(minetest.yaw_to_dir(body_yaw),0.72)
55 local real_dir = minetest.yaw_to_dir(body_yaw)
56 local body_yaw = degree_round(degrees(minetest.dir_to_yaw(dir)))
61 pos = vector.add(pos,dir)
64 --pos is where the head actually is
66 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 6)) do
67 if object:is_player() then
68 local pos2 = object:get_pos()
69 pos2.y = pos2.y + 1.625
71 local head_yaw = degree_round(degrees(minetest.dir_to_yaw(vector.direction(pos,pos2))))
73 --print("body yaw: ",math.abs(body_yaw),"head yaw:",math.abs(head_yaw))
77 local new_yaw = (head_yaw-body_yaw)
85 if math.abs(new_yaw) <= 90 or math.abs(new_yaw) >= 270 then
86 --do other calculations on pitch and roll
88 local triangle = vector.new(vector.distance(pos,pos2),0,pos2.y-pos.y)
90 local tri_yaw = minetest.dir_to_yaw(triangle)+(math.pi/2)
92 pitch = radians_to_degrees(tri_yaw)
94 local pitch_adjustment = 0
96 if new_yaw >= 270 then
97 pitch_adjustment = new_yaw - 180
98 elseif new_yaw <= -270 then
99 pitch_adjustment = new_yaw + 180
101 pitch_adjustment = new_yaw
104 local roll_adjustment = pitch_adjustment
106 pitch_adjustment = 1-(math.abs(pitch_adjustment)/90)
107 pitch = pitch-- * pitch_adjustment
109 --print(pitch_adjustment)
113 roll = radians_to_degrees(tri_yaw)
115 local roll_adjustment = 0
117 if new_yaw >= 270 then
118 roll_adjustment = new_yaw - 180
119 elseif new_yaw <= -270 then
120 roll_adjustment = new_yaw + 180
122 roll_adjustment = new_yaw
125 local secondary_roll_adjustment = 0
128 secondary_roll_adjustment = 1
130 secondary_roll_adjustment = -1
133 --print(roll_adjustment)
135 roll_adjustment = math.abs(roll_adjustment)/90
136 roll = roll * roll_adjustment * secondary_roll_adjustment
147 self.child:set_attach(self.object, "", vector.new(2.4,1.2,0), vector.new(180+roll, new_yaw, 180+pitch))
151 --self.head_rotation = vector.new(180,new_yaw,180)