- changed status to open
DazHead property is set wrong when I import daz armatures (not figures) with off-zero object coordinates
What a mouthful of a title again. So I have an object that has a daz armature, it is not a figure but a cupboard. I can import that cupboard and then open the doors by moving the bones of the armature.
When I put the cupboard into the scene and leave it at zero and save and import that, everything works fine. But, if I move the cupboard to off zero coordinates and open the door and save and apply the pose, the door detaches from the cupboard and flies of.
The reason for that is that DazHead on the edit bone is set incorrectly. At least I can see that that is the only real difference, and when I go and manually correct the DazHead property of all bones, it works.
To correct it I simply take the object position * 100 and subtract it from DazHead. So I move the cupboard on the X axis to -150 in daz, then it will end up at -1.5 in blender. Then my bone has a DazHead like (-100.707, 43.0, 28.7086) and I just subtract (-150, 0, 0) ending up with (49.293, 43.0, 28.7086) and everything works.
Comments (6)
-
repo owner -
reporter What I said isn’t entirely accurate, to reproduce my problem:
- load cupboard into Daz
- move cupboard to off-zero coordinates
- load into Blender
- open the door by moving the door bone in Blender
- save pose
- apply pose in Daz
- see doors flying off
If you don’t move the cupboard to off-zero coordinates in 2. it works fine.
-
reporter I found out that in DazHead is set in bone.py buildBoneProps from the head that getHeadTail returns:
head,tail,orient,xyz,wsmat = self.getHeadTail(center) head0,tail0,orient0,xyz0,wsmat0 = self.getHeadTail(center, False) bone.DazHead = head
and getHeadTail just gets it from restdata and doesn’t really do much other then that with it, but then restdata is filled in objfile.py loadDbzFile and there you take head from the ws_transform of the bone. Now I am kind of wondering why even use the world space transform for bones? Shouldn’t it be the local transform, as in local to the current armature? But I tried that and it failed completely so I guess I am not going to question using the world space transform there as long as it works.
However for the DazHead I noticed I really just need to keep the original head that you get from bone[“center_point”] in the loadDbzFile function here:
for bone in figure["bones"]: head = Vector(bone["center_point"]) daz_head = head tail = Vector(bone["end_point"]) vec = tail - head if "ws_transform" in bone.keys(): ws = bone["ws_transform"] wsmat = Matrix([ws[0:3], ws[3:6], ws[6:9]]) head = Vector(ws[9:12]) tail = head + vec @ wsmat else: head = Vector(bone["ws_pos"]) x,y,z,w = bone["ws_rot"] quat = Quaternion((w,x,y,z)) rmat = quat.to_matrix().to_3x3() ws = bone["ws_scale"] smat = Matrix([ws[0:3], ws[3:6], ws[6:9]]) tail = head + vec @ smat @ rmat wsmat = smat @ rmat if "orientation" in bone.keys(): orient = bone["orientation"] xyz = bone["rotation_order"] origin = bone["origin"] else: orient = xyz = origin = None bname = bone["name"] rmat = wsmat.to_4x4() rmat.col[3][0:3] = LS.scale*head restdata[bname] = (head, tail, orient, xyz, origin, wsmat, daz_head) transforms[bname] = (rmat, head, rmat.to_euler(), (1,1,1))
and I already added the change I made to fix the problem for me to the code: I just assign
daz_head = Vector(bone["center_point"])
and put that intorestdata[bname]
and then in buildBoneProps I do this:head,tail,orient,xyz,wsmat,daz_head = self.getHeadTail(center) head0,tail0,orient0,xyz0,wsmat0,daz_head0 = self.getHeadTail(center, False) bone.DazHead = daz_head
and now everything works correctly as far as I can tell.
-
repo owner The world space location combines bone proportions and object transformations. It would be desireable to only include the former, but afaiu it is not possible to extract that information from DS. The data that is available are the unmorphed bones at rest, and the morphed bones with object transformation which DS uses to draw the viewport and rendering. If you use dbz fitting use get both, which work best if the character is in rest pose. Morphed fitting may be an alternative.
-
repo owner Forget what I wrote above. The center-point is indeed the location of the bone in armature space and can be used for the DazHead variable. Your suggestion has been implemented.
-
- changed status to resolved
- Log in to comment