VitoPlantamura.com logo - Click here to go to the site home page... Click here to go to the site home page... Click here to go to the Blog page... Click here to go to the archives page... Click here to go to the about page...
"extremely impressive work"
- Mark Russinovich, www.sysinternals.com
(referring to my BugChecker)
my face...
Homepage of Vito Plantamura (@), Windows Researcher, VPC Technologies SRL CEO. [user=Guest] - updated: August 08, 2007
 SKELETAL CHARACTER RENDERER (with source code)
SKELETAL CHARACTER RENDERER

SCR is an MFC application that shows my CNode class at work. CNode is a C++ class that implements OpenGL rendering and animation of biped and mesh characters exported from 3DStudio MAX 3.1 through a dedicated plugin. The MFC application, the CNode implementation and the 3DStudio plugin were written by me (Vito Plantamura) in 2000.



INTRODUCTION

The code that makes up this Skeletal Character Renderer (SCR) example application was stripped out from the implementation of the Modeler application included in the MapGen suite of tools, written by me in between 1999-2001. I have included in the source code that can be downloaded from this page only the classes and features that are required for testing and consuming the CNode implementation. For example, no save or open commands are available.

Usually the method of writing a dedicated plugin for the modeling application used by the artists of your team is the best approach when writing a game professionally. The solution of reading and parsing a file exported from the 3D application, in most cases, can be very tricky and complex and doesn't provide the 3D programmer with the necessary level of control and knowledge about the scene and the objects that need to be exported. In the case of 3DStudio and Character Studio, there is a complete object model that can be queried inside the plugin implementation in order to obtain all the informations and data that are useful in the export process. In the case of the plugin I wrote in 2000, after specifying the name of a remote host and the final name of the animation itself, it is possible to export the current scene to the Skeletal renderer application anywhere on the network simply clicking on a button, using DCOM as the transport.



Skeletal characters are a special type of 3D models that are used tipically in last-generation games and 3D realtime software. The use of skeletal models instead of simple keyframed meshes allows to:

     store the model and animation data in less space: the (sometimes extremely) reduced footprint in memory and on disk of the animation is caused by the fact that the animation data (tipically) consists of only one mesh (a series of vertices and faces) in a well-known "pose" and the skeletal data, that is made up of "weights" and transformation info. Instead of storing for each "keyframe" a "snapshot" of the positions of all the model vertices in order to obtain at runtime the final xyz coordinates through linear interpolation between keys, in the skeletal case the position of each vertex in 3D space is calculated taking into account the influences of one or more "bone" from the character "skeleton" on each vertex of that single "pose" mesh. For a complete description of this animation method I advise to search the web for related articles and examples (before looking at my code).
     have more accurate and smooth animations than in the case of simple linear interpolation between keyframed meshes.

You can download from this page the source code of the SCR application. It is a document-view MFC program that can be useful for the following purposes:

     checking out the C++ strong object oriented implementation of the CNode class that is used for:
     calculating for each "GEOMOBJ" the final transformation matrix given a time value, before the rendering phase (EvalWorldState method).
     rendering the node graph to the current OpenGL rendering context (Render method).
     dumping the node graph details to a tree control identified by an HWND handle (DumpInTreeCtrl method)
     viewing how to write a MFC application that renders 3D content in a view/window using OpenGL.
     checking out the implementation of interesting MFC custom CWnd classes such as CTimeSlider, that implements a sliding button used for setting the current frame position for the active animation in the style of those seen in 3DStudio.
     checking out the implementation and employment of typical math classes and objects used in real-world games for representing and manipulating matrices, vectors, planes and quaternions.

USING THE CNODE CLASS

The first step for using the CNode class is to construct an instance starting from a byte stream representing a 3DStudio MAX animation. The 3DS plugin that can be downloaded from this page allows to export the current scene in a format that is compatible with the CNode implementation. Specifically, the plugin, at the click of the "export" button, attempts to contact a remote DCOM server with CLSID equal to "CLSID_MapGenModeler" requesting for a IStream interface pointer. Then, through the methods of that interface, the plugin transfers the animation byte blob to the remote implementation. The entire scene, the meshes contained into it and the relative skeletal and non-skeletal animation data is packed into a single byte stream, that is aimed to be parsed by the remote peer tipically for rendering purposes. The details of the DCOM server location can be specified directly in the plugin controls exposed in a pane of the 3DStudio interface. The format of the animation data is defined in the "anim_format.h" file and is as follows (Please note that the source code included in the archive that can be downloaded from this page is commented poorly and in Italian (I wrote it 5/6 years ago). The comments in the following code were translated from Italian expressly for inclusion in this text):

anim_format.h

Given that pbAnim is a byte pointer to the animation data received from the plugin, an instance of CSceneRoot (that is derived from CNode and that represents the top most node in the scene) can be created as follows:

CSceneRoot*       pSR = new CSceneRoot( (anim_stream_desc_t* ) pbAnim );
if ( pSR-> m_bCorrupt != FALSE )
{
      delete pSR; // the pbAnim data is corrupt.
}
else
{
      // pSR can be consumed...
}

At this point, the rendering methods can be invoked on pSR in order to render the animation in an OpenGL rendering context. The first step for doing this is to call the EvalWorldState method specifying the time value at which the scene has to be "evaluated". This means that the required transformation matrices and animation data will be calculated for allowing the actual rendering phase to take place. Then the Render method itself has to be called: this method will use the precalculated EvalWorldState data for drawing in the OpenGL rendering context. The only parameter that is required when calling the Render method is the rendering mode that has to be used. The following values can be specified:

enum ERenderMode {
      eWireframe,
      eSolid,
      eTexture,
      eSolidPlusWireframe,
      eWireframeSpecialGreen,
      eWireframeSpecialRed
};

For a real example of the steps described above, check out the OnPaint implementation of the CAnimOpenGLRenderer class. This method contains also the various calls to the OpenGL library required for setting up the projection and transformation matrices and the z-buffer and lighting configuration.

USING THE EXAMPLE APPLICATION

For using the plugin, install 3DStudio MAX 3.1 and optionally Character Studio 2.2. Then copy in the plugin directory of 3DStudio MAX (named "Plugins") the MSC.dlu file. After that, you can export 3DStudio MAX animations directly from the program interface activating the "MapGen Server Control" plugin from the "Utilities" pane of the program and then pressing the "export" button. Make sure to launch on the local machine or on a DCOM reachable machine on the network the MFC Example Application (name "Renderer.exe") before doing anything. The Example Application will setup a DCOM server with CLSID equal to "CLSID_MapGenModeler" listening for incoming connections from the plugin module.

The workspace files in the archive included with this article were created with Visual Studio 6.0. I guess that converting them for a newer version of Visual Studio will not be a problem. For compiling or recompiling the example application, make sure to do the following:

     Specify in Visual Studio, in the "Include Files" window, the path to the "Renderer\Include\BCG464" folder.
     Specify in Visual Studio, in the "Library Files" window, the path to the "Renderer\Lib" folder.

DOWNLOAD

Download the SCR Application (binaries only) from here (871KB).
Download the SCR Application (plus source code) from here (1611KB).

 Quotes
"Among the Windows experts I know personally, no one can beat Vito Plantamura."
- Francesco Balena, Code Architects SRL

"Your NDIS Monitor application, is amongst the most impressive networking code I have seen on the .Net framework."
- Ben Hakim.
 Photos
Various images from italian conferences and events (keep the mouse on a thumbnail for a short description):
Me at the Microsoft/HP/Intel organized Route64 event in Milan in May 2005, explaining how COM+ behaves on 64-bit Microsoft operating systems. I was there with the friends of Code Architects.
Me at the Microsoft Security Roadshow event in Bari in April 2006, explaining how the logon process works in Windows NT. There were 250 attendees.
Microsoft Security Roadshow 2006 in Treviso. This is an image of the huge 700-seats conference room.
Me at the Microsoft Security Roadshow 2006 in Treviso. This is a moment of the 3-hours session.
 Site login
NOTE: Actually the login feature is used only for administrative and content management purposes.
Username

Password

Everything here (code, binaries, text, graphics, design, html) is © 2010 Vito Plantamura and VPC Technologies SRL (VATID: IT06203700965).
If you download something (compilable or not) from the site, you should read the license policy file.
If you want to contact me via email, write at this address.