Arkwood awoke with a pounding head. ‘Where am I?’ he said, rubbing his eyes.
‘You are on the parlour floor,’ I replied bitterly. You see, my Belgian buddy got drunk on the Christmas sherry and missed my “Animated Robot” presentation.
But I told him that, yes, I shall forgive him. As long as he can stay sober long enough to witness my next demo: “Rotated Robot”.
Arkwood sneered, ‘Oh, it sounds really interesting. I can hardly wait.’
In my last post, Blender animation in OpenGL (Mark III), I created an animated 3D robot in Blender. I imported the robot into SaltwashAR – my Python Augmented Reality application – and rendered the robot on a 2D marker using OpenGL.
But now I want to use the techniques in my post Augmented Reality with 3D object rotation to rotate the robot. Let’s go!
Create rotation in Blender
So, we already have the robot at 0 degrees i.e. facing us. But how do we rotate it 90 degrees, 180 degrees and 270 degrees?
Stack Exchange provided the answer to the question: How do I rotate a group of objects? We use parenting. I parented the robot to its right-facing leg, and then updated the Location and Rotation settings as thus…
Robot at 0 degrees:
Great. The robot will stay at the centre of the 2D marker as we rotate it.
I exported the robot from Blender at each rotation, using the Wavefront OBJ format.
Use rotation in OpenGL
Armed with the OBJ files, I preprocessed them into OpenGL commands as per my last post. My AR application now has frames to load for the robot at each rotation:
class RockyRobot(Robot): # load frames def load_frames(self, is_animated): self.body_frame = rocky_robot_body_frame() self.head_passive_frames = rocky_robot_head_passive_frames(is_animated) self.head_speaking_frames = rocky_robot_head_speaking_frames(is_animated) self.degrees_90_frame = rocky_robot_degrees_90_frame() self.degrees_180_frame = rocky_robot_degrees_180_frame() self.degrees_270_frame = rocky_robot_degrees_270_frame()
Each time we want to render a robot, we simply check the rotation value of the 2D marker. A rotation value of 0 means that we want to render the robot at 0 degrees. A rotation value of 1, and we render the robot at 90 degrees. Rotation value of 2, we render robot at 180 degrees. And a rotation value of 3, the robot is rendered at 270 degrees.
# get next frame def next_frame(self, rotation, is_speaking): # handle any rotation if rotation != 0: self.is_facing = False if rotation == 1: glCallList(self.degrees_90_frame) elif rotation == 2: glCallList(self.degrees_180_frame) elif rotation == 3: glCallList(self.degrees_270_frame) return # otherwise handle facing robot self.is_facing = True glCallList(self.body_frame) self.head_frame_index += 1 if is_speaking: if self.head_frame_index >= len(self.head_speaking_frames): self.head_frame_index = 0 glCallList(self.head_speaking_frames[self.head_frame_index]) else: if self.head_frame_index >= len(self.head_passive_frames): self.head_frame_index = 0 glCallList(self.head_passive_frames[self.head_frame_index])
And that is about that. One thing to note is that if the robot is not facing us (i.e. not at 0 degrees) then it can not speak to us and we can not speak to it. It would be bad manners otherwise 🙂
Here’s a demo of Rocky Robot and Sporty Robot in rotation:
Rather swell, I’m sure you’ll agree.
But there is no point asking Arkwood for his opinion – he’s passed out on the brandy again!
I ran the code on my Windows 7 PC using Python Tools for Visual Studio.
Any questions, drop me a line.