We need to forget about the SkinMesh stuff for a while and get our application framework together.
Let's put on a brave face and examine the WinMain which appears next in the SDK sample.
We can see that it relies HEAVILY on stuff we haven't looked at yet, the DXUT application framework. Although it might be useful to totally translate the DXUT stuff too, I'm not inclined to do so - rather, we will translate the DXUT stuff as we encounter it, so as to translate the minimum junk for this project.


//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

// Set the callback functions. These functions allow DXUT to notify
// the application about device changes, user input, and windows messages. The
// callbacks are optional so you need only set callbacks for events you're interested
// in. However, if you don't handle the device reset/lost callbacks then the sample
// framework won't be able to reset your device since the application must first
// release all device resources before resetting. Likewise, if you don't handle the
// device created/destroyed callbacks then DXUT won't be able to
// recreate your device resources.
DXUTSetCallbackDeviceCreated( OnCreateDevice );
DXUTSetCallbackDeviceReset( OnResetDevice );
DXUTSetCallbackDeviceLost( OnLostDevice );
DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackKeyboard( KeyboardProc );
DXUTSetCallbackFrameRender( OnFrameRender );
DXUTSetCallbackFrameMove( OnFrameMove );

// Show the cursor and clip it when in full screen
DXUTSetCursorSettings( true, true );

InitApp();

// Initialize DXUT and create the desired Win32 window and Direct3D
// device for the application. Calling each of these functions is optional, but they
// allow you to set several options which control the behavior of the framework.
DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
DXUTCreateWindow( L"Skinned Mesh" );

// Supports all types of vertex processing, including mixed.
DXUTGetEnumeration()->SetPossibleVertexProcessingList( true, true, true, true );

DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );

// Pass control to DXUT for handling the message pump and
// dispatching render calls. DXUT will call your FrameMove
// and FrameRender callback when there is idle time between handling window messages.
DXUTMainLoop();

// Perform any application-level cleanup here. Direct3D device resources are released within the
// appropriate callback functions and therefore don't require any cleanup code here.
ReleaseAttributeTable( g_pFrameRoot );
delete[] g_pBoneMatrices;

return DXUTGetExitCode();
}


Our version must look a lot like this:


WinMain proc hInst, hInst, pString, dwVal

; Set the callback functions. These functions allow DXUT to notify
; the application about device changes, user input, and windows messages. The
; callbacks are optional so you need only set callbacks for events you're interested
; in. However, if you don't handle the device reset/lost callbacks then the sample
; framework won't be able to reset your device since the application must first
; release all device resources before resetting. Likewise, if you don't handle the
; device created/destroyed callbacks then DXUT won't be able to
; recreate your device resources.
invoke DXUTSetCallbackDeviceCreated, addr OnCreateDevice
invoke DXUTSetCallbackDeviceReset, addr OnResetDevice
invoke DXUTSetCallbackDeviceLost, addr OnLostDevice
invoke DXUTSetCallbackDeviceDestroyed, addr OnDestroyDevice
invoke DXUTSetCallbackMsgProc, addr MsgProc
invoke DXUTSetCallbackKeyboard, addr KeyboardProc
invoke DXUTSetCallbackFrameRender, addr OnFrameRender
invoke DXUTSetCallbackFrameMove, addr OnFrameMove

; Show the cursor and clip it when in full screen
invoke DXUTSetCursorSettings,TRUE,TRUE

invoke InitApp

; Initialize DXUT and create the desired Win32 window and Direct3D
; device for the application. Calling each of these functions is optional, but they
; allow you to set several options which control the behavior of the framework.
invoke DXUTInit,TRUE,TRUE,TRUE ; Parse the command line, handle the default hotkeys, and show msgboxes
.data
sztitle db "Skinned Mesh",0
.code
invoke DXUTCreateWindow,addr sztitle

; Supports all types of vertex processing, including mixed.
invoke DXUTGetEnumeration
OCall eax::CD3DEnumeration.SetPossibleVertexProcessingList, TRUE,TRUE,TRUE,TRUE

invoke DXUTCreateDevice, D3DADAPTER_DEFAULT, TRUE,640, 480, IsDeviceAcceptable, ModifyDeviceSettings

; Pass control to DXUT for handling the message pump and
; dispatching render calls. DXUT will call your FrameMove
; and FrameRender callback when there is idle time between handling window messages.
invoke DXUTMainLoop

; Perform any application-level cleanup here. Direct3D device resources are released within the
; appropriate callback functions and therefore don't require any cleanup code here.
ReleaseAttributeTable g_pFrameRoot
MemFree g_pBoneMatrices;
invoke DXUTGetExitCode
ret
WinMain endp


Yeah, what a mess of unimplemented stuff, huh?
What the above really does is create our main window, enter the messagepump loop, wait for a quit, then clean up.
We've got a bit of work to do in order to implement this awful stuff.
Is it just me, or do microsoft like ugly names??
I am going to stop right now.
I would like to know who is following this stuff, so I can make a decision regarding how light our framework should be.

If you are keen to see this project unfold any further, say so now.
Posted on 2005-12-28 04:21:54 by Homer
Tick Tock... (I can feel myself rot)...
Posted on 2005-12-28 07:30:31 by Homer
Amaizing work. I'm putting all peaces together...
As for the string allocation, you can use StrNew or StrAlloc from the ObjMem32 library.

Biterider
Posted on 2005-12-28 07:37:01 by Biterider
Thanks for the heads up Biterider - do these just wrap an invocation of MemAlloc, or do they call the COM SysAllocString thingy?
Posted on 2005-12-28 07:48:48 by Homer
PS Biterider - happy to see you are watching this, I'll be screaming for help when this version fails - I am willing to send you the existing (and much cleaner) SkinMesh oa32 class as it stands, basically I think its failing me because I miss one stage of matrix multiplication at the scene root..
Hey, you wanna scrap both our D3DApp classes and translate the DX9 sample framework?
It's ugly as hell, but implementing it may provide some impetus for your model..

Oh yeah, I downloaded the December SDK today - it sucks.. lol
Theres a bunch of DX10 samples, but you need to have Longhorn (Vista) OS and you also need a graphic card that isn't publically available - pretty useful to most devs I imagine..
Posted on 2005-12-28 07:53:12 by Homer
Hi Homer,

I have spent my time translating the "Modular SkinMesh" source posted at flipcode.org, which is basically a modified version of the sdk skinmesh sample.. the author has moved a bunch of stuff around in order to make the skinmesh class less closely associated with the SDK Sample and more useful as a generic skinmesh class.
Of course, there's no binary included, because the bloody thing doesn't work.


It's a pitty flipcode.org's activities have been stopped, but at least the information it contained is still available.
In the "Featered Articles" section of the site, I saw Phil Taylor's 2 articles:
"Modular D3D SkinnedMesh" and "SkinnedMesh DPlay Maze".
His approach seems good to me. And in fact that's what we want to: A reusable SkinnedMesh class.
I can feel your frustration, when your translation of it didn't work.

But what about your conclusion: "There's no binary included, because the thing doesn't work"?
I can't imagine that his example couldn't be compiled. The article even mentions David Jurado's updated version of it.
My conclusion is: Couldn't there be a small inaccuracy in your translation?

Friendly regards,
mdevries.
Posted on 2005-12-30 01:51:48 by mdevries
Hi Homer,

I suggest that it might be mutually beneficial to translate the original DX9 SDK skinmesh sample here, in public, with the hope that more eyes mean less bugfixes, and so that you guys can see what is involved in translating a cpp source to oa32.


This direct approach is a good idea from education point of view.

I hope it attracts some people. And isn't it now, then maybe in the future.
You never know who will be interested some day.

Friendly regards,
mdevries.
Posted on 2005-12-30 01:59:15 by mdevries
Hi Homer,

That being said, I feel a linear approach to the translation of the sample code is warranted.
Unless someone can tell me why I should not, I will begin posting slabs of the original file, in order of appearance, and follow each with the oa32 translation of it.


This approach has the advantage everyone can follow you directly from the SDK. So it's clear what is ahead of us.
But our goal must remain: a reusable SkinnedMesh class.

Friendly regards,
mdevries.
Posted on 2005-12-30 02:03:40 by mdevries
Hi Homer/Biterider,

Note that when we define objects with OA32, we should declare a unique "class identifier".
The value of CAllocateHierarchyID is totally arbitrary, I tend to invent random numbers and hope that they don't collide with existing OA32 class identifiers


You mention the problem: Colliding with used OA32 class identifiers.
Is there a logic in the way OA32 uses class identifiers?

Friendly regards,
mdevries.
Posted on 2005-12-30 02:12:15 by mdevries
Hi Homer,

In the Modular version I originally translated, a lot of these fields had been moved into the SkinMesh class instead of being global like this.


I can imagine. If you have more than one instance of the same SkinMesh class, each one of them should have it's own set of variables.

Friendly regards,
mdevries.
Posted on 2005-12-30 02:16:41 by mdevries
Hi Homer,

Our version of this procedure uses OA32's MemAlloc macro.
More specifically, I use $MemAlloc, which is a lot like $invoke..
MemAlloc allocates memory on the Process Heap.
This may not be the best place to shove strings, but it'll do the job.
Right now I'm not concerned about efficiency, just wanna make it work.


In the passed years you have tried hard to make the animated SkinnedMesh work.
I can understand you first want to make it work.
Making the code more efficient can always be done at a later moment in time.

Friendly regards,
mdevries.
Posted on 2005-12-30 02:20:56 by mdevries
Hi Homer,

Here's the original version of the CreateMeshContainer method.
It will look scary at first, but there's nothing to be afraid of..


It looks scary at first, indeed. But the translation is rather straight forward, as I can see.

Friendly regards,
mdevries.
Posted on 2005-12-30 02:27:46 by mdevries
Hi Homer,

We have arrived at WinMain in the SDK sample.

From here on, things will be weird, because we will attempt to avoid implementing mountains of unnecessary generic app support code.

Things are also weird because the application-specific code and the skinmesh code are presented together, whereas we would ultimately like to separate SkinMesh class code from the application junk, so that we have a reusable SkinMesh class object we can instance in future apps..


Not implementing unnecessary generic app support code is good. It makes the code less massive at the moment.
But as you saw in the translation of Phil Taylor's version of the SDK Sample, it may not be working at first.
Why not translating the sample as it is. And when it works, you can move stuff around to make the code more like want it to be: Reusable SkinnedMesh code.

Friendly regards,
mdevries.
Posted on 2005-12-30 02:39:52 by mdevries
Hi Homer,

If you are keen to see this project unfold any further, say so now.


Tick Tock... (I can feel myself rot)...


You know my answer, don't you? But I can't always be online.
So be patient. If noone answers within a few hours, it doesn't mean you are doing it for nothing.
Just keep up the good work. I respect your knowledge and skill on this subject.

Friendly regards,
mdevries.
Posted on 2005-12-30 02:46:49 by mdevries
Hi mdevries,

STOP SPAMMING THE BOARD. All of your previous posts could have been combined into one, please use common sense with utilizing these forums.
Posted on 2005-12-30 02:59:20 by SpooK
Hi Spook,

Thanks for your correction. I'll keep it in mind.

B.t.w. Thanks for unlocking the incidentally Locking stage of this topic.

Friendly regards,
mdevries.
Posted on 2005-12-30 03:05:32 by mdevries
Hi mdevries
The class identifier is a distinctive and unique ID for this class. It is used in several places to identify an unknown object instance. I.e. it is used when you retrieve an object from a Stream. The code implementation reads this ID from the stream and then it knows how to recreate the object. Another use of these IDs is the error reporting strategy used in ObjAsm32.
These IDs should be unique, at least in an application. If the compiler detects an ID collision, it reports an error. For all objects included in the package, the IDs are concentrated in a file called ObjIDs.inc in the \Code\Objects directory. It is a good practice to put user defined IDs in a separate file, since in future releases, this file could be overridden.

Regards

Biterider
Posted on 2005-12-30 09:45:46 by Biterider
I'm convinced that there was no error in my translation of the modular skinmesh code. I have provided biterider with a copy of it in order to verify this according to my belief that many eyes make code work. I believe the problem was in my implementation of the scene root, whose transformation matrix is inherited by the entire hierarchy in one way or another.
Today, in order to confirm this conviction, and out of boredom, I wrote a MeshManager class which can maintain N instances of a static mesh. It works fine, so I must accept that the problem is NOT in the mesh loading or rendering code, it is in the matrix transformations.
Having studied the SDK sample's gui framework for a couple of days, I must reiterate that I am not inclined to translate the whole lot in a braindead fashion. My own gui framework, and biteriders, are equal if not superior to the SDK version. What I will do is translate and implement various elements of the SDK gui framework as they are needed, and as I see fit.. for example, I've already translated the CD3DArcBall camera support class.
I wanted to have the skinmesh stuff working before the end of the year, but that's unlikely now.
Ah well, I am nevertheless determined to make it work, and I believe I will.
I'll post all related code next year (in the coming days) for anyone who is interested.
Posted on 2005-12-30 10:43:43 by Homer

I'm convinced that there was no error in my translation of the modular skinmesh code. I have provided biterider with a copy of it in order to verify this according to my belief that many eyes make code work. I believe the problem was in my implementation of the scene root, whose transformation matrix is inherited by the entire hierarchy in one way or another.
Today, in order to confirm this conviction, and out of boredom, I wrote a MeshManager class which can maintain N instances of a static mesh. It works fine, so I must accept that the problem is NOT in the mesh loading or rendering code, it is in the matrix transformations.
Having studied the SDK sample's gui framework for a couple of days, I must reiterate that I am not inclined to translate the whole lot in a braindead fashion. My own gui framework, and biteriders, are equal if not superior to the SDK version. What I will do is translate and implement various elements of the SDK gui framework as they are needed, and as I see fit.. for example, I've already translated the CD3DArcBall camera support class.
I wanted to have the skinmesh stuff working before the end of the year, but that's unlikely now.
Ah well, I am nevertheless determined to make it work, and I believe I will.
I'll post all related code next year (in the coming days) for anyone who is interested.


I will look forward to see your great work, now see if I can succed and post some animation code, next year, until then happy new year Homer
Posted on 2005-12-30 12:48:03 by daydreamer
I succeeded with animation code - I can load a skinmesh model's frame hierarchy and all its animation data and I can animate it, but I can't render it.
I get a jumble of animated triangles, which some other authors describe seeing when they "forget to call the UpdateMatrices method".
It must be damn close to being right, I bet its some small bug I'm overlooking.

Posted on 2006-01-05 08:58:21 by Homer