Tags

, , , , , , , , , , , , ,

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:

BlenderObjectRotationInOpenGL_0Degrees_Robot

BlenderObjectRotationInOpenGL_0Degrees_Settings

90 degrees:

BlenderObjectRotationInOpenGL_90Degrees_Robot

BlenderObjectRotationInOpenGL_90Degrees_Settings

180 degrees:

BlenderObjectRotationInOpenGL_180Degrees_Robot

BlenderObjectRotationInOpenGL_180Degrees_Settings

270 degrees:

BlenderObjectRotationInOpenGL_270Degrees_Robot

BlenderObjectRotationInOpenGL_270Degrees_Settings

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!

Ciao!

P.S.

I have updated SaltwashAR on GitHub with the code from this post (and amended the documentation accordingly).

I ran the code on my Windows 7 PC using Python Tools for Visual Studio.

Any questions, drop me a line.