HALCA (Hardware Accelerated Library for Character Animation)


HALCA is an interface to the Cal3D library and extends this with GLSL shader support, morph animations, hardware accelerated morph targets(blend shapes), Dual Quaternion skin shaders, JPEG texture files, direct joint manipulation and other additions to the animation system. The Cal3D library is available in source code from http://home.gna.org/cal3d/ An overview of the HALCA architecture is given in the following figure Figure 1. Figure 2 shows a video where HALCA was used to visualise an avatar in first person perspective that moves like the participant. The video is from our 2010 SIGGRAPH paper on an experiment about place illusion and plausibility.

HALCA Architecture
Fig 1: HALCA Architecture

Fig 2: HALCA used with Optitrack real time motion capture.

Binary Files

The latest version of HALCA for windows Win32 and x64 machines can be downloaded here:

If you are having difficulties running the dll make sure that you have Microsoft Net Framework 2 or higher installed. Also load the dll into the dependency walker to find possible missing dependencies in your system. Sometimes dependency walker reports missing msvcr, msvcp and other dlls although they are installed in your system. This happens because dependecy walker may not be aware of microsoft manifest information. In this case the dll may work even if dependency walker has unresolved dependencies.

Exporter plugin

The binary for the 3D Studio Max 9 and 2008, 2009 and 2010 both for Win32 and x64 platforms is available here:

Max 9/ Max 2008 Max 2009 Max 2010
Win32 cal3d_max9_exporterWin32.dle cal3d_max2009_exporterWin32.dle cal3d_max2010_exporterWin32.dle
x64 cal3d_max9_exporterx64.dle cal3d_max2009_exporterx64.dle cal3d_max2010_exporterx64.dle

Copy the appropriate file to the
directory of your Max application and restart Max.

XVR Interface

An interface file in the XVR scripting language can be found here:

An Example XVR Application

You can find an example XVR application with the Open Source Hero avatar from the Catmother porject here: XVR Example with the Hero avatar. The demo uses blend shapes for facial expressions (morph targets), and animated bump maps for wrinkles. The demo uses a GLSL vertex shader to do skin deformation for animation and blend shapes. You will need a working version of XVR installed on your system. Note that XVR will only run as ActiveX control in Internet Explorer or as a standalone XVRGlut program. The application was tested with Windows XP and Windows Vista. Once the application is running you can navigate through the environment by using the mouse. Right mouse button for moving left, right, forwards and backwards, both mouse keys and drag for moving up and down and the left mouse button to change the view direction up, down, left or right. The avatars facial expressions can be modified with the keys "m", "b", "v", "c", "x". The bump map can be animated with the "k" key. Pressing the keys with and without the left shift key increases and decreases the influence of the morph targets and the bump map.

Example GLUT Application

C++ source code of an example GLUT application that loads HALCA by using the windows LoadLibrary function and adds HALCA function addresses by using the windows GetProcAddress function can be found here:


A short tutorial for loading BVH animations from the Optitrack Arena system onto Character Studio Biped Avatars can be found here.
A short tutorial on exporting characters from 3D Studio Max. It can be found here.
Joan Llobera has written an easy to follow tutorial to get you used to the interface here.
Daniel Perez Marcos has written a tutorial about the things he learnt with Character Studio and HALCA while preparing Avatars for his experiments. here
Anna Bellido has done a tutorial that explains the steps required to export a rigged character with blend shapes and bones from Maya via FBX to 3DStudio Max and to HALCA. You can find it here .


It happens sometimes when exporting a new character that some file is missing or something goes wrong. In this case it is useful to check the HALCAmessages.txt file which is logging events that happen while the characters are loaded. The HALCAmessages.txt is created in the directory in which the library is executed.


A list of publications of research that describes HALCA or for which HALCA was used can be found here .

Changes and News

12.7.2010 added function useShaderOne which allows the user to apply individual shaders for each avatar loaded in the system. added function setShaderUniformOne which allows the user to set all uniform variables of each loaded shader for each avatar. added function geomShaderType which allows the user to change the geometry shader input and output primitives of the specified shader program.

6.7.2010 fixed bug in loading texture maps. The problem was that if there was more than 3 maps defined then the alpha map was not loaded if the diffuse texture was defined as JPEG.

26.4.2010 Added function getAnimationNumFrames to allow the user to read the number of animation frames that are stored in the given animation.

2.3.2010 Added function getGPUBoneIdMap that enables the user to retrieve the mapping of the bone ids in the GPU shader to the skeleton bone ids. This is useful for example if only meshes that are attached to particular bones should be visualised.

4.2.2010 Added function MessageWrite that enables the user to write messages to the HALCAMessages files from the hosting application. This can be useful to debug OpenGL errors caused by other OpenGL calls in the hosting application.

25.1.2010 Added blend masks. See blendCycleNMask Blend masks allow the user to apply blend weights not just to all tracks of an animation, but to every track individually. Therefore every joint in the skeleton can be animated with a different weight. This is useful for example to programmatically separate an animation for parts of the body.

24.1.2010 Fixed memory handling bug that caused problems if more than 8 blend shapes were used in TBO mode.

6.1.2010 Added support to store blend shape information in texture buffer objects. See function setUseTBO. Thanks to Richard Southern at Bournemouth University for pointing me to texture buffer objects.

5.1.2010 Created an example that uses a geometry shader to tesselate the mesh of an animated virtual character.

6.12.2009 fixed problem in the max exporter plugin that caused the plugin to crash when using the max exporter script. The problem was caused by a Microsoft Foundation Class problem. In addition the max exporter plugins were linked statically so that there is no more dependency with cal3d.dll

20.11.2009 added functions setPrimitive and setPrimitiveOne which enable the user to change the opengl primitive used to render the avatar meshes.

16.11.2009 added support to load 2 more texture maps per material file. These texture maps are bound to a Sampler2D. The uniform name of the sampler is "gloss" and "subsurf" respectively. These textures can be used to provide 2D map information for specular reflection and subsurface scattering shaders but can also be used to provide any other texture information to the shaders. In summary the material file can now contain up to 5 textures. 1st a diffuse map, 2nd a bump map, 3rd an opacity map, 4th a gloss map and 5th a subsurface scattering map. At the moment diffuse and opacity map must have the same resolution. The opacity map is internally merged with the diffuse to represent an opengl RGBA texture. The function useTextureUnit specifies the texture unit at which to start using the texture. eg if useTextureUnit is set to 2 then diffuse and opacity map will use texture unit 2, bump map will use texture unit 3, gloss map will use texture unit 4 and the subsurface scattering map would use texture unit 5. By default the starting texture unit is 0.

20.10.2009 Added functions setVertexWeightThreshold, getNumGPUMeshes, setMaxBonesPerMesh. These functions are useful for more efficient collision detection algorithms.

19.10.2009 Added function selectMesh that enables the user to select individual meshes of the avatar to be rendered.

16.10.2009 Added support to load geometry shaders in the loadShaders function.

13.10.2009 Added function getAnimationTime to retrieve the local time at which the specified animation is currently played.

24.09.2009 Added Max2010 exporter for both Win32 and x64 platforms.

13.9.2009 Added setLocalDir function so that the virtual character data can be stored in a different subdirectory or shared in a global directory between different applications

8.9.2009 Added x64 version of Max 2009 exporter

28.8.2009 Changed behaviour of getBoneBB when called with bone id 0 it returns the bounding box of the whole body. Added function updateBoneBB to update the bounding box information for individual bones for performance reasons.


Added XVR example application with blend shapes for facial expressions and bump maps.
Added list of publications related to HALCA.
Added Tutorial by Anna Bellido on exporting Characters from Maya to HALCA.


The libraries were compiled for x64 machines.


Added exporter for 3D Studio Max 2009.
Added source code for GLUT example application.


Added support for morph targets in shader programs.
Added support for bump map rendering to create for example more realistc wrinkles on the skin of characters.
A tutorial that shows how to use this functionality is in development.
Aitor Rovira has decided to use HALCA for the bystander project to design their first experiment.


Daniel Perez Marcos created a Brain Computer Interface (BCI) scenario with HALCA and XVR which we used in the Barcelona Brain Fair to allow participants to control avatars by thought in a virtual running competition.


Added function distanceToBoundingCylinder that enables the user to measure the distance between a given 3D point and a bone of the skeleton of a character.
Improved performance of handling multiple characters. If the same mesh, texture, animation, material or skeleton file is used more than once then such data is now loaded only once in memory and reused whenever possible. Vertex buffer objects that are created from an avatar description file are also reused on the GPU if they are created from the same .cfg file.


Fixed bugs in isPointInsideCyl and getBoneBoundingCylinderRadius. These functions didn't correctly calculate the cylinder intersection. In addition a radius parameter was added to isPointInsideCyl in order to enable the user to test between cylinder and a sphere intersection. If the radius is 0 then a point test is carried out.

Thanks to Elias Giannopoulos alias Johnson for testing the functions in order to integrate them with his haptic devices. Function getBoneBB did not take the scale that was set either in the .cfg file or by the setModelScale function of the avatar into account. Thanks to Alejandro Beacco Porres for discovering the problem.


Added functions getModelScale setModelScale to interactively change the scale of each avatar non uniformly in x, y and z.


Added functions for checking collisions with bounding boxes or bounding cylinders of limbs. isPointInside isPointInsideCyl
The function getBoneBB was changed to return the corner points of the bounding box specified by a boneid. The previous implementation of that function did not work. Function getBoneBoundingCylinderRadius was added to allow the user to retrieve the radius of the bounding cylinder of a bone. These bounding volume functions are also useful for the integration of Avatars with the PhysX engine. Functions setAllBoneState and getAllBoneState to set and get the state of the whole skeleton of an avatar by using a single array of translation and rotations were added in order to allow the user to interface efficiently with external sources of motion.


Fixed a bug that caused problems with negative dt in blendCycle if the animation was blended in with a delay. Thanks to Alejandro Beacco Porres for discovering the problem. Modifications in the core cal3D library were required.

Added a short tutorial on exporting characters from 3D Studio Max. It can be found here.


Added checkbox to Max animation exporter that enables the user to save in OpenGl coordinate system. Previously this was only possible with the export_cal3D.ms exporter script. A short description can be found here.
A short tutorial for loading BVH animations from the Optitrack Arena system onto Character Studio Biped Avatars can be found here.


Added function exeActPart which allows the user to define a start time and a duration for an animation to be executed. Fading in and out still work as before. Modifications to the core Cal3D library, in particular the CalAnimation class were required.

Bernhard Spanlang