OK, this gets a little bit more complex because of the nature of the beast.

Microsoft's sourcecode always assumes that there is just one MESH in the frametree of a SkinMesh... there is at least one MESHCONTAINER attached to one of the frames in the frametree - M$ assumes there is ONLY one... that is not certain, you can have more strewn throughout the frametree.
In fact, microsoft's code will load and animate N meshcontainers, but only draws one.

A meshcontainer holds, among other junk, a chunk of Mesh and a list of which Bones it affects.
The bones are presumed to belong to that MeshContainer and to be found in the frametree at some point BELOW the node that holds the meshcontainer.

So when we wanna attach something to a Bone, we should be dealing with that Bone's owner - which is a MeshContainer at a higher node... and so the MeshContainer is the logical place to be recording which Bones have attachments.
But we can't go screwing with the content of MeshContainers for the same reason that we can't screw with the Frames - these are REFERENCE RESOURCES, shared by ALL instances.

So it would be nice if Instances had some kind of per-MeshContainer list of attachments that are loosely associated with the Reference resources.

In fact, I see no reason that the MeshContainers need to remain inside the FrameTree at all.
They could be stored as any kind of list, array, linkedlist, whatever... but that list needs to be constructed AFTER loading, perhaps within 'SetupBoneMatrices'.

What we really need to know for each Instance is:
-how many MeshContainers
-how many, and which, Bones are referenced by EACH MeshContainer
I'm thinking about using some kind of bitkey to represent some of this.

And it would be nice to link the MeshContainers into a linear list, to speed up the rendering - we wouldn't need to search for them anymore (ok we have a quick pointer to the first one, but what about the rest?)

Posted on 2008-07-12 21:58:01 by Homer

I've finally figured out how I want to go about attaching armour and weapons etc.

The first thing I did was describe a new class called D3D_SkinMeshInstance, whose immediate ancestor is D3D_SkinMesh. The new class overrides the Init and Done methods... the new Init method requires a pointer to an existing (reference) D3D_SkinMesh object, from which it clones a new instance, stealing a copy of essential data and cloning required interfaces.

The next thing I did was extend the FRAME structure, adding a WORD to describe the index of a Bone (if the frame is not a boneframe, its set to -1)

The next thing I did was make some key changes to the ancestor D3D_SkinMesh class, I added a Dynamic method that gets called just after a boneframe's matrix has been updated, just before we return from recursion, at the end of the UpdateFrameMatrices method.
Then I added a dummy callback method that I expect to override in the D3D_SkinMeshInstance class (and any subsequent derived classes).

Now we have our callback method being called on a per-instance basis (through the magic of dynamic overrides), we can determine what response is appropriate as each Bone is updated, and BEFORE the skinmesh itself has been rendered.

If we want the model's hand to obscure the handle of the Sword he or she is holding, then we need to draw the sword just before we draw the skinmesh.The callback scheme makes that incredibly easy, the alternatives would have cost a lot in terms of memory and/or cpu cycles and would have defeated the purpose of trying to share the reference frametree across all instances... we'd have lost all our savings and possibly more.

Any items that need to be drawn 'on top of' the model can be drawn after our call to Render the skinmesh itself.

What are your thoughts?

Posted on 2008-07-14 00:27:01 by Homer
The D3D_SkinMeshInstance object now has its 'onBoneUpdated' callback method implemented... I've added a BITKEY to the class object, where each Bit represents a Bone.
If a bit is Set, then this Bone has something attached to it.
I've also added an array of 'Pointers to attached objects' which corresponds to the set of Bones, and to the Bits in the BitKey...

When a Bone is updated, the callback grabs the Bone's index from the Frame and checks whether the corresponding Bit in the BitKey is Set or Clear.
If its Set, the callback grabs the Pointer from the attachments array at the same Index, and then assumes the attached object is a D3D_MeshManaged object, and proceeds to overwrite its Transform matrix with that of the Bone (ie, from the updated Frame matrix).

Rendering of the attached object is currently left to the MeshManager.

D3D_SkinMeshInstanceID equ 234234
Object D3D_SkinMeshInstance,D3D_SkinMeshInstanceID,D3D_SkinMesh
RedefineMethod Init, Pointer
RedefineMethod Done
RedefineMethod onBoneUpdated, Pointer ;ptr to FRAME which represents a Named Bone
StaticMethod Attach_To_Bone, Pointer,dword ;ptr to D3D_MESHMANAGED , index of Bone we wanna attach mesh to
StaticMethod Detach_From_Bone, dword ;index of Bone we wanna detach mesh from
DefineVariable pBitKey_Attachments, Pointer,NULL ;binary key denoting which Bones have attachments
DefineVariable pAttachedObjects, Pointer,NULL ;array of ptrs to attached objects

Method D3D_SkinMeshInstance.Done,uses esi
SetObject esi
MemFree  .pBitKey_Attachments
MemFree  .pAttachedObjects

; 覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧
; Method:    D3D_SkinMeshInstance.Init
; Purpose:   Create a CLONE of the given (REFERENCE) SkinMesh with the bInstanced flag set to TRUE (see D3D_SkinMesh.Done)
; Arguments: None.
; Return:    None.
; Notes: Be sure the input param is a REFERENCE SKINMESH, ie, do NOT clone from D3D_SkinMeshInstance
Method D3D_SkinMeshInstance.Init,uses esi edi,pRefSkinMesh
LOCAL dEvents:dword, dOutputs:dword
SetObject esi
mov edi,pRefSkinMesh
mov dEvents, $ICall(.D3D_SkinMesh.pAnimController::ID3DXAnimationController.GetMaxNumEvents)
mov dOutputs, $ICall(.D3D_SkinMesh.pAnimController::ID3DXAnimationController.GetMaxNumAnimationOutputs)

;Clone all the local data from the RefSkinMesh into this new SkinMeshInstance
;making sure we don't overwrite the (first) 20 bytes of data that are internally used by OA32
;Here you can see I am referencing 'the first data variable' in each Class
invoke RtlMoveMemory,addr .pDirect3D,addr .D3D_SkinMesh.pDirect3D,sizeof D3D_SkinMesh-20

mov eax,.dMaxBones
shr eax,3 ;divide by 8 ... we need one BIT per Bone
mov .pBitKey_Attachments,$MemAlloc(eax,MEM_INIT_ZERO)

mov eax,.dMaxBones
shl eax,2 ;multiply by 4 ... we need one DWORD per Bone
mov .pAttachedObjects,$MemAlloc(eax,MEM_INIT_ZERO)

;We CANNOT prevent a call to the ancestor's DONE method - even if we override Done in this class :|
;So we'll use a BOOLEAN to alert the ancestor's Done method NOT to release Shared resources
mov .bIsReferencedResource, FALSE ;<-- I am an INSTANCE, not a REF OBJECT

;Now we need to clone the refmesh's AnimationController...
;Overwrite the COPY of the refskinmesh's animcontroller with a freshly-cloned interface
ICall .pAnimController::ID3DXAnimationController.CloneAnimationController,dOutputs,\
.dAnimationSetCount, .dAnimationSetCount, dEvents, addr .pAnimController

Method D3D_SkinMeshInstance.Attach_To_Bone,uses esi,pMeshInstance,dBoneIndex
SetObject esi
mov edx,.pBitKey_Attachments
mov eax,dBoneIndex
bt word ptr, ax
jc @F
bts word ptr, ax
shl eax,2
mov edx,.pAttachedObjects
push pMeshInstance
pop dword ptr
mov eax,TRUE
@@: mov eax,FALSE

Method D3D_SkinMeshInstance.Detach_From_Bone,uses esi,dBoneIndex
SetObject esi
mov edx,.pBitKey_Attachments
mov eax,dBoneIndex
bt word ptr, ax
jnc @F
btc word ptr, ax
shl eax,2
mov edx,.pAttachedObjects
mov dword ptr,0
mov eax,TRUE
@@: mov eax,FALSE

Method D3D_SkinMeshInstance.onBoneUpdated,uses esi,pBoneFrame
SetObject esi
mov eax,pBoneFrame
mov edx,.pBitKey_Attachments
movzx eax,.FRAME.BoneIndex
bt word ptr, ax
jnc @F
;The bit was SET - this bone has something attached to it
shl eax,2
mov edx,.pAttachedObjects
mov edi, dword ptr
;For now we'll assume that the attachment is a D3D_MeshManaged object (we can attach skinmeshes at a later date)
;Let's overwrite the MANAGED MESH's transform matrix with the BONE's transform matrix
mov edx,pBoneFrame
invoke RtlMoveMemory,addr .D3D_MeshManaged.mBodyToWorld, addr .FRAME.matCombined,sizeof D3DXMATRIX
@@: ;The bit was CLEAR - theres nothing attached to this Bone

Your thoughts?
Posted on 2008-07-14 03:20:37 by Homer
While I'm 'boning up', I thought it would be cool to extend the MeshManager class (used to manage instances of static meshes) so that it also manages the reference meshes.

By properly managing both Reference and Instance objects, the user is free to concentrate on the stuff that matters to them, free to forget about managing these resources.

Now the MeshManager keeps two lists - one is a list of ManagedMesh instances - these refer to D3D_Mesh instances... the other is a list of loaded D3D_Mesh instances :)
Although we can load several Reference Meshes, each will be loaded only once.. and ALL instances of these ref meshes are kept in a single group, no matter which mesh they represent.

Note that these changes only affect STATIC meshes - not Skinned ones.
I do not think THESE changes will break any existing applications, however the changes to Skinmesh are another matter. I'll be providing Biterider with any / all files I have messed with, and I'm pretty sure that he'll make them immediately available for download via OA32's Updater application.

Posted on 2008-07-14 10:16:11 by Homer
The code to attach instanced static meshes to instanced animated skinmeshes is working, based on the 'onBoneUpdated' dynamic callback I mentioned previously.
I'm still not completely convinced that it can't be done more efficiently, but its still a lot more efficient than the typical solution of loading multiple copies of the entire resource.
This is gonna be fun, my lead 3D artist has been grinding his teeth, now the shoe is going on the other foot :P
Posted on 2008-07-14 21:08:50 by Homer
D3D_MeshManager was afforded the Scaling support from D3D_Mesh, and now I've got a demo of a walking model (instanced) with a Sword attached to its hand (instanced), wherever the hand goes, whichever way the hand aims, the sword follows it, bound by its transform matrix.

The important part here is that everything is Instanced - if we had seventeen bloodthirsty pirates on our screen, and one dropped his sword, the rest will hang onto theirs, even though they all share the same skinmesh. We can give them different accessories to make them appear more different, and we can switch their Skin texture as well, which makes a huge difference to the APPEARANCE of a model, given the same underlying geometry.
Posted on 2008-07-15 06:53:41 by Homer
Current work:
I've found a much better place to implement the code which 'dynamically welds' attachments to my skinmesh instances.. it means one callback per skinmesh update, instead of one callback per boneframe update.. vastly more efficient.

Next work:
I'm going to leverage the skinmesh-attachments stuff in order to implement BREAKABLE skinmeshes. You'll be able to tear your enemies limb from limb :)

This will be done as follows:
Firstly, we'll make our model, complete with joint hierarchy (at minimum).
Then we cut the model up into bodyparts, splitting the mesh into N meshes, one per Joint.
We'll apply a different Material to each bodypart - this is important.
Now for each Bodypart, we hide all the others, cap the open surfaces (stumps) of the bodypart, and save it out to a separate file.
(We MAY need to move the bodypart to the Origin - it depends on the implementation, I'm yet to decide..)
Now we have our complete model, and a bunch of bodyparts.
We never attach the bodyparts to the skinmesh - when we wish to break the skinmesh, we instance some bodyparts, stop the skinmesh animations, and initialize the bodypart instances  in WorldSpace based on the attachment joint's transform - as IF we were attaching them.

Now when rendering the skinmesh, if its not 'completely broken', we draw the materials of the joints that have NOT been broken.. this is how we can retain our animated skinmesh minus, say, an arm and a leg :P

I could not find any information online about how to do this, I'm winging it.

Posted on 2008-07-16 08:02:20 by Homer
I'm not sure I made myself clear in the previous post.
There's no need really to attach the breakable limbs to the skinmesh - what we really want to do is determine their position/orientation at the moment breakage occurs - so it would make sense to use existing code to attach, and then immediately detach, the bodyparts that just got chopped off by that axe-wielding barbarian... now those severed limbs can be treated as simply static meshes under the influence of the physics simulator... in fact the original bodyparts are still being animated by the skinmesh (cant see any easy way to prevent this), they're just being hidden either through tagging of Material or by storing each in a separate MeshContainer (bonegroup) within the frametree... I think the Material-tagging method will be cheaper than having to process multiple MeshContainers... but then again, multiple MeshContainers indeed opens the possibility of eliminating the animation of 'invisible' limbs :)

Posted on 2008-07-17 01:21:07 by Homer
I've just installed an experimental new version of OA32.
The teething problems are relatively minor, but require that I edit any objects that I wrote (Biterider has modified all the ones you get with OA32, its only 'personal' objects that need the changes).

If I was a new OA32 user, it would not affect me at all, but existing OA32 users are going to need to learn how the changes affect them, should this version of OA32 be released.

And for future reference (in case I forget, which I am liable to), the following three statements sum up the major syntactical changes:

StaticMethod becomes VirtualMethod
BoundMethod becomes StaticMethod
@ClassName becomes TPL_ClassName

Posted on 2008-07-18 02:41:04 by Homer

Just curious - what are you guys working on lately?

Homer, not much programming these days since its summer here.
Mainly "Honey DO" lists... :lol: Grass cutting, gardens, and whatever else she can come up with for me to do...
Posted on 2008-07-18 21:06:34 by rags
Heh, make hay while the sun shines :P

I've just re-implemented support for outbound connections in my iocp-based networking support object, so it can talk to itself:P

Further, each network session can now use its own protocol-handling object... note where I say 'Client' I refer to a network session, regardless of who initiated it.
The framework marshalls protocol-dependent calls to each Client's protocol handler...
basically the framework just makes calls to Client methods in a dumb fashion, and from there execution is passed to the Client's protocol handler.

By default, the server knows a Protocol, supplied as a derivation of a common 'abstract interface'. All the 'Inbound' client sessions will inherit this handler, so conversations between our local server and remote clients will only use the default protocol, or the server will spit the dummy and kick the client off (for breaching the protocol).

But each 'Outbound' client session can have its own Protocol handler, so conversations between local clients and a remote server can use ANY PROTOCOL, they are not tied down to using the default protocol of our server.

It's all very nicely asynchronous, using overlapped socket io.
I guess I'll keep going to weed out some of the unnecessary calls across objects :)

Posted on 2008-07-20 23:31:48 by Homer

I've implemented support for grouping of clients on the Server via a new object called ClientGroup. This object implements a hierarchy or tree of nodes where each node contains a list of clients. The idea was borrowed from DirectPlay - it made a lot of sense to me that te ability to track groups of clients is going to be valuable for a wide range of server implementations - for example, 'Lobby' servers, chatroom servers, games that support clans / tribes / teams etc.
The code has been tested in a demo 'LobbyServer', with a cheesy GUI to let the local administrator visualize and modify the client groups at runtime.

Next I'll be implementing some kind of abstract support for Account Registration and Authentication, and also abstract support for application event notifications - probably by embedding an instance of my relatively new EventManager object, rather than forcing the User to have to think about application-side event sinking interfaces. And when thats in place, I can begin to redirect the Game application event handling through the Server so that when you eg press a key, instead of being handled locally, the event is sent to the server, a reply is returned, and then the Game reacts to the Reply from the Server. I know its blindingly obvious but the temptation to hook up local handlers for everything is acute and its just not what you want for a network-ready gaming framework.

Posted on 2008-07-22 01:14:28 by Homer
Decided to attack those topics in the opposite order.
I noticed that my Server object was still being derived from the Primer ancestor object, which is the root object in OA32 kinda like IUnknown is for COM interfaces.
Now I have Server being derived from my EventManager.
This gives me a way for Server apps to register their interest in various (assumedly asynchronous) events that occur within (are triggered by) the Server framework, perhaps to force the GUI to refresh its content in regards to a state change (if the server has a gui, or a window at all, neither are requirements).
It gives me a way for the Server to call USERCODE in response to internal events, which might be handy, don't you think?

Posted on 2008-07-22 02:23:41 by Homer

Nah, I stripped away all the Event stuff I'd just added.
Then I spent some hours chasing some resource leaks, getting rid of a few blatantly unnecessary methods, renaming some stuff, and generally cleaning it up.
Then I implemented support for multiple Listeners, using my existing Client object.
I needed an object to wrap a socket handle, and hey, I already had one.
Listeners are just Clients whose socket is a listening server.
Like all Clients, they are tagged with a Protocol handler.
Clients issued by a Listener for ACCEPT are tagged with their Listener, and his Protocol.

So now we can serve on multiple ports, use multiple protocols, and do it all through a shared pool of resources.

Having done that, I created a new Listen method to allocate new Listeners, so the Server no longer begins to Listen when Initialized, which means that the framework can be used as a pure Server (inbound connects), or as a pure Client (outbound connects), or it can do both.
I have renamed the Server object to "NetEngine" to recognize this fact.

Posted on 2008-07-22 07:38:46 by Homer
Sounds good, homer! :)
Posted on 2008-07-22 07:41:44 by f0dder
I'm now having a look at implementing automatic NAT traversal via upnp.
I know, not all routers / NAT devices supports it, and it can be disabled by those who are concerned about the malware already on their system abusing upnp (lol, if you have malware then you're already screwed, it can enable upnp too).
However I'd like my applications to at least TRY to use it, before whining at the User to manually configure port-forwarding.
Posted on 2008-07-23 04:19:39 by Homer
(lol, if you have malware then you're already screwed, it can enable upnp too).
Spot on the sugar, baby!

If upnp isn't available you could also try using STUN :)
Posted on 2008-07-23 09:33:03 by f0dder
STUN is no good for me, the NetEngine currently does not have a TCP emulation layer, in fact it has zero UDP support. Perhaps I'll add that at some stage but for now I'm happy to use TCP and wear the overhead - gamers tend not to use dialup connections these days :)
There is always STUNT to consider in the meantime :)
Posted on 2008-07-24 02:36:07 by Homer
I generally prefer TCP connections myself, lots of people using UDP end up writing basically a (less reliable) TCP clone - which is a waste of effort. But for protocols that can survive a few dropped packets here and there, UDP can be fine - and STUN is a cute trick :)
Posted on 2008-07-24 09:23:08 by f0dder
Today was a quiet day so I decided to try a little experiment that I've had on my mind for some time now - I was wondering how to create an animated skinmesh that contains multiple meshcontainers, so that I can 'break' the skinmesh at runtime by terminating the rendering at a given meshcontainer in the hierarchy...
I was under the impression that I'd have to bind each Bone to its associated mesh, but its much easier than that... all you need to do is have multiple meshes, then select Everything, and Bind once... the fact that you have more than one Mesh is all you need to create more than one MeshContainer. I've been merging my meshes because I was led to believe that a skinmesh REQUIRES a single mesh, but that is absolutely untrue... unless you're a cut and paste cowboy who's relying on the code from those DX SDK samples in its given form :P
Now I need to speak to my 3D artist and tell him the good news - then he can explain to the 2D guys how we want 'stump textures' on the (normally) hidden faces on the endcaps of each bodypart :)

Posted on 2008-07-27 00:56:17 by Homer