.b3d files bones structure

(Posted 5 months ago) Horax

How to get access to .b3d files bones structure?
(For purposes of character customisation, adding clothing, weapon etc.)
I have made some models (4 races, man, woman, boy and girl for each).
Each character has 6 hair styles (and 6 colour variants).

(Posted 5 months ago) RonTek commented:

Hey Horax, you can check out this archived topic here

(Posted 5 months ago) Horax commented:

Yes - thanks a lot, but the link in that topic unfortunately is dead(.
If it is possible - what was in that zip - in two words?

(Posted 5 months ago) markcwm commented:

I don't have that zip but this is pretty much what you're looking for, although it's BMX Openb3d so you've to port it to B3D.
I think you need to call the manual bone code after UpdateWorld in B3D.
It turns the head and/or hip joints.

(Posted 5 months ago) Horax commented:

Sorry! Please forgive me my absolutely (may be) stupidness,
but is exactly what I have:

What is in the "Help":

GetChild (entity,index)
entity - entity handle
index - index of child entity. Should be in the range 1...CountChildren( entity ) inclusive.
Returns a child of an entity.

FindChild ( entity,child_name$ )
entity - entity handle
child_name$ - child name to find within entity
Returns the first child of the specified entity with name matching child_name$.

What must be, something like that:

FindChild (player_model,head)
EntityParent player_hair,head


(Posted 5 months ago) markcwm commented:

Sure, you need a string name ie. "head" in quotes.

(Posted 5 months ago) Horax commented:

Thanks - it works.
Is what I did:

Global player_head=FindChild(player_model,"head")
EntityParent player_hair,player_head

  • before UpdateWorld.

But now I need to get position/rotation of the head:

because hair basic position is 0,0,0:

PositionEntity player_hair,EntityX(player_head),EntityY(player_head),EntityZ(player_head)

And here I have some strange effect:
hair position is not equal to the head position:

The difference between hair position and head position is equal to difference between head position and neck position (=9.375cm).
Why it may be so?

(Posted 5 months ago) markcwm commented:

OK, sorry I've confused you a bit, in B3D the before/after UpdateWorld is not an issue, only in BMX. In B3D you use UpdateWorld for automatic animation, for manual animation use SetAnimTime. I've ported the rotate_bones example now. About the hair issue, maybe you should rotate the neck not the head, it depends on what the hair is connected to.

; rotate_bones.bb
; using manual animation mode

Graphics3D 800,600
SetBuffer BackBuffer()

Local camera=CreateCamera()
Local light=CreateLight()
Local anim_ent=LoadAnimMesh("media/zombie.b3d")

PositionEntity camera,0,10,-30
;Animate anim_ent,1,0.1 ; set mode: 1=loop, 2=ping-pong, 3=one-time

Local joint1 = FindChild(anim_ent,"Joint8")
Local joint2 = FindChild(anim_ent,"Joint10")
Local anim_time#=0, joint1_y#, joint2_y#

While Not KeyHit(1) ;ESC

    If KeyDown(30) Then joint1_y=joint1_y-1 ;A
    If KeyDown(32) Then joint1_y=joint1_y+1 ;D
    If KeyDown(16) Then joint2_y=joint2_y-1 ;Q
    If KeyDown(18) Then joint2_y=joint2_y+1 ;E

    ; in Blitz3d, UpdateWorld is for automatic animations, SetAnimTime is for manual
    If anim_time>20 Then anim_time=2
    SetAnimTime anim_ent,anim_time ; set animation frame, also disables mode

    ; move bones
    If joint1<>0 Then RotateEntity joint1,0,joint1_y,0
    If joint2<>0 Then RotateEntity joint2,0,joint2_y,0


    Text 0,20,"+/- to animate, anim_time: "+anim_time
    Text 0,40,"Q/E: rotate joint1, A/D: rotate joint2"

(Posted 5 months ago) Horax commented:

Thanks - it may be useful.
As I wrote before, the parent for the hair is the head (bone).
Different models have a different number of joints. And more: the same (comporatively) joints - in the different models - have different indexes. If I'd find the joints I'd can not use one code for all of my models. But the bones in my models have fixed names. So, for example: the head - allways is the head. It's why I'm using the bones.

What I did:

Global player_head=FindChild(player_model,"head")
EntityParent player_hair,player_head
PositionEntity player_hair,EntityX(player_head),EntityY(player_head)-9.375,EntityZ(player_head)

Yes, hair on the head.
But this is absolutely not the final positive result (because the coefficient 9.375 is valid only for this model).

(Posted 5 months ago) markcwm commented:

Sorry, I don't have much skeletal rigging experience so I can't really help you with this.

(Posted 5 months ago) RonTek commented:

@Horax, afaik and from what I have seen from game mods and open source engines, usually attachments are rigged into the character itself, hidden and just be toggled in game for easy access.

still very much possible with what you are trying to do with bone attachments and this has been successfully done many times before particularly on b3d demos/games.

perhaps trying to create a pivot on the attachment and parent it to the character head joint would also work nicely if you would consider this option.

(Posted 5 months ago) Horax commented:

The separate points of attachment, tags are in the oldest 3d engines/games/file formats such as Quake 1-3, where was not used the skeletal structures/animations.
Weapon (MD2) - for example - must have animation/origin point equivalent to animation/origin point of the tris (MD2).
Such 3d file formats as B3D, FBX, etc. - do not need any tags because of it's skeletal structure (that itself is - the ful complex of tags).
Good example for using B3D is the RealmCrafter that is written on the Blitz3d & BlitzPlus. Now it is an open source project.

As I know, the B3D file format does not support any empty objects.
I tried to add the dummy object - as a helper. But it was not exported: was lost in the process.
One extra bone adds 117 bytes - it helps - but how big will be the final model if the initial by default has about 50-60 working bones?

After adding one extra bone ("hair"), my code is:
Global hair_place=FindChild(player_model,"hair")
EntityParent player_hair,hair_place
PositionEntity player_hair,EntityX(hair_place),EntityY(hair_place),EntityZ(hair_place)

To be equipped as it shown on the picture:

this character must have 9 extra bones.

(Posted 5 months ago) RonTek commented:

I see and that looks great. I still see the already rigged and toggle attachments option if you would like to have less bones to deal with.

As I know, the B3D file format does not support any empty objects. I tried to add the dummy object - as a helper. But it was not exported: was lost in the process.

not sure about this, but afaik you can do it using a bone without a parent to produce this result. I also remember there were previous loaders that supports pivots like 3dsmax, if you're familiar with it. I will try to check out if I have this in my archives.

either way, if you are strictly enforcing loading all your components using a file, you can just create a custom loader with a config file to load empty, pivot, and other unsupported entities by code.

(Posted 5 months ago) RemiD commented:

yes it is possible, search for a post by me (RemiD), about the blitz3d installer + updates + upgrades B003 (by bobysait).

then you will be able to create skinned vertices and set weights (influences) by some bones.

Reply To Topic (minimum 10 characters)

Please log in to reply