University of Southern CaliforniaUSC
USC ICT TwitterUSC ICT FacebookUSC ICT YouTube

Working with 3dsMax studio assets in SmartBody | General SmartBody Discussion | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Working with 3dsMax studio assets in SmartBody
July 2, 2014
6:58 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Hi again,

after being able thanks to your help and source code available to integrate smartbody within game engine, we have a production question about getting assets from 3dsMax and putting them in SmartBody.

We have read the Retargeting, Joint mapping, and Creating character parts of the SmartBody manual, as well as related posts in the forum, but we still have a couple of questions about working with 3dsMax assets in SmartBody:

1 - To use a 3D human model created with 3dsMax, which has a biped skeleton (.bip) associated to animate it, are the following steps correct? (please correct me if I'm wrong):
    1.1 Export the 3dsMax skeleton (biped) as a Collada file (.dae).
    1.2 Export the mesh data from 3dsMax as a Collada file too.
    1.3 Follow tutorial code like "4_CreatingCharacter.py":
    1.4 Create a character and do a joint mapping from the custom skeleton (the .dae file containing the biped skeleton exported from 3dsMax) to the SmartBody native skeletal format (like for example zebra2-map.py).
   1.5 Apply the character the .dae deformable mesh exported too from 3dsMax.

 

Other questions are:

2 Which correspondence exists between the biped skeleton from 3dsMax and the native skeleton of SmartBody at a joint level, is there any documentation or script I can read, or is enought reading the format definitions and doing a mapping script myself?

3 What happens when doing a skeleton mapping, if I cannot find a corresponding joint in the custom skeleton for a particular joint of the smartbody native skeleton, can I ignore it without having problems (and which would be the right solution otherwise)?

4 Does SmartBody loads an skeleton file with .dae format (I'm used to see .sk files all the time), or the right way to do it is to use an standard .sk file and then apply a correct joint mapping like "zebra2" between the custom skeleton and the SmartBody native one (excuse my ignorance but that's one of the parts that I do not have clear)?

5 To be able to use correctly animations exported from 3dsMax (I have read the "How To Export Skeleton/Animation From 3dsMax or Maya" section) for characters now working in SB and with a proper ".bip" joint mapping, do we have to retarget the animations?

 

thanks again for your help,

Alex

July 3, 2014
5:57 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

1. Those steps look right to me. SmartBody can read .dae files, but it doesn't have a .bip importer, so that conversion needs to take place. Make sure that the mesh and skeleton are united in 3dsmax so that the skinning/rigging information is inserted into the .dae file on export. You should be able to test that .dae file by drag-and-drop into the sbgui scene area - the character should appear.

 

2. We've tested this out before, but I can't find the old mapping script. If you send me the 3dsmax skeleton hierarchy, I can tell you what the mapping will be.

 

3. The purpose of the skeleton mapping is to (a) provide common names for joints for controllers that use those joints. For example, the gaze controller uses various spine and neck joints, so it needs to know what your name is for those joints, and (b) to provide a means for online retargeting between motions. When you set up a retargeting instance between two skeletons, the joint mapping essentially maps from one to another. The SmartBody 'skeleton' is mostly an intermediate reference; if all the skeletons can map to the SmartBody skeletons, then all the characters can have motions online retargeted to each other. If you don't have a mapping to a joint, then the retargeting data won't be copied over. Also, if the controllers don't have the joints that they need (for example, the gaze joints) then the controllers might not work properly.

 

4. SmartBody has a parser for each file type (.sk or .dae), they are both converted int an internal SBSkeleton instance, so the original source doesn't matter (if I had a .bip importer, those would be automatically converted as well). Again, you don't have to do a joint mapping, but if you don't, many of the controllers won't work and the online retargeting won't work either.

 

5. You have two choices: (a) you can do no joint mapping, then use your 3dsmax skeleton as is, and apply your 3dsmax motion on it, and it will work, or (b) apply a joint mapping to your skeleton and to your motion, and the motion will work on the skeleton, as well as all the controllers and other SmartBody functionality

Ari

July 3, 2014
5:58 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Found the old mapping script:

 

jointMapManager = scene.getJointMapManager()
bipedMap = jointMapManager.createJointMap("biped")
bipedMap.setMapping("Bip01", "base")
bipedMap.setMapping("Bip01_Neck", "spine4")
bipedMap.setMapping("Bip01_Head", "spine5")
bipedMap.setMapping("Bip01_HeadNub", "skullbase")
bipedMap.setMapping("Bip01_L_Clavicle", "l_sternoclavicular")
bipedMap.setMapping("Bip01_L_UpperArm", "l_shoulder")
bipedMap.setMapping("Bip01_L_Forearm", "l_elbow")
bipedMap.setMapping("Bip01_L_Hand", "l_wrist")
bipedMap.setMapping("Bip01_L_Finger0", "l_thumb1")
bipedMap.setMapping("Bip01_L_Finger01", "l_thumb2")
bipedMap.setMapping("Bip01_L_Finger02", "l_thumb4")
bipedMap.setMapping("Bip01_L_Finger1", "l_index1")
bipedMap.setMapping("Bip01_L_Finger11", "l_index2")
bipedMap.setMapping("Bip01_L_Finger12", "l_index4")
bipedMap.setMapping("Bip01_L_Finger2", "l_middle1")
bipedMap.setMapping("Bip01_L_Finger21", "l_middle2")
bipedMap.setMapping("Bip01_L_Finger22", "l_middle4")
bipedMap.setMapping("Bip01_L_Finger3", "l_ring1")
bipedMap.setMapping("Bip01_L_Finger31", "l_ring2")
bipedMap.setMapping("Bip01_L_Finger32", "l_ring4")
bipedMap.setMapping("Bip01_L_Finger4", "l_pinky1")
bipedMap.setMapping("Bip01_L_Finger41", "l_pinky2")
bipedMap.setMapping("Bip01_L_Finger42", "l_pinky4")
bipedMap.setMapping("Bip01_R_Clavicle", "r_sternoclavicular")
bipedMap.setMapping("Bip01_R_UpperArm", "r_shoulder")
bipedMap.setMapping("Bip01_R_Forearm", "r_elbow")
bipedMap.setMapping("Bip01_R_Hand", "r_wrist")
bipedMap.setMapping("Bip01_R_Finger0", "r_thumb1")
bipedMap.setMapping("Bip01_R_Finger01", "r_thumb2")
bipedMap.setMapping("Bip01_R_Finger02", "r_thumb4")
bipedMap.setMapping("Bip01_R_Finger1", "r_index1")
bipedMap.setMapping("Bip01_R_Finger11", "r_index2")
bipedMap.setMapping("Bip01_R_Finger12", "r_index4")
bipedMap.setMapping("Bip01_R_Finger2", "r_middle1")
bipedMap.setMapping("Bip01_R_Finger21", "r_middle2")
bipedMap.setMapping("Bip01_R_Finger22", "r_middle4")
bipedMap.setMapping("Bip01_R_Finger3", "r_ring1")
bipedMap.setMapping("Bip01_R_Finger31", "r_ring2")
bipedMap.setMapping("Bip01_R_Finger32", "r_ring4")
bipedMap.setMapping("Bip01_R_Finger4", "r_pinky1")
bipedMap.setMapping("Bip01_R_Finger41", "r_pinky2")
bipedMap.setMapping("Bip01_R_Finger42", "r_pinky4")
bipedMap.setMapping("Bip01_L_Thigh", "l_hip")
bipedMap.setMapping("Bip01_L_Calf", "l_knee")
bipedMap.setMapping("Bip01_L_Foot", "l_ankle")
bipedMap.setMapping("Bip01_L_Toe0", "l_forefoot")
#bipedMap.setMapping("Bip01_L_Toe0Nub", "l_toe")
bipedMap.setMapping("Bip01_R_Thigh", "r_hip")
bipedMap.setMapping("Bip01_R_Calf", "r_knee")
bipedMap.setMapping("Bip01_R_Foot", "r_ankle")
bipedMap.setMapping("Bip01_R_Toe0", "r_forefoot")
#bipedMap.setMapping("Bip01_R_Toe0Nub", "r_toe")
bipedMap.setMapping("Bip01_Spine2", "spine3")
bipedMap.setMapping("Bip01_Spine1", "spine2")
bipedMap.setMapping("Bip01_Spine", "spine1")

July 24, 2014
7:26 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Hi Ary, thank you very much for your help , I'm making progress but I have a couple of problems (hope the last of them :) ).

1. I have written code that tries to build the  Behavior set Kicking with only one animation (to test if our animation exporting process is ok) exported from 3ds Max, for a character which has a biped skeletal scheme.

The script BipedMapping.py does the skeletal mapping between the .bip used by 3ds Max and the native SmartBody skeletal format, it is based in the script you wrote above.

I have verified that the biped mapping works loading a character with biped skeleton and applying the Behavior set Kicking with the Retarget Viewer Window, the character moves properly.

The case is that the following code generates errors and warnings:
"SBAnimationBlend add sk motion failure, ChrGarza@Chut doesn't exist"
"Add motions before add correspondence points for state"
"num motions = 0, motion parameter = kick, interpolator type = RBF"

I have verified that the ChrGarza@Chut loads properly executing the sbgui.exe in debug mode and performing drag-and-drop with the corresponding ChrGarza@Chut.dae file.

I am trying to find the error(s) that could be present in the script but having no success. Could influence the fact that the character I'm loading has an skeleton in .dae format (it is loaded from the same .dae file which contains the geometry and skinned mesh)? for example, maybe some methods like "createMotionBlendBase()" only accept a skeleton in a separate file or in .sk format.
I have tried saving the character's skeleton as a .sk file but then I cannot see the skinned mesh when I load it using the .sk file instead of the .dae file (maybe I'm doing it wrong, but I tried using the .save method from the SBSkeleton class).

The code is the following:

assetManager = scene.getAssetManager()
assetManager.addAssetPath('motion', 'Pr4')
assetManager.addAssetPath('mesh', 'mesh')
assetManager.addAssetPath('script', 'scripts')
assetManager.loadAssets()

scene.setScale(1.0)
scene.getActiveCamera().reset()
bradSkeleton = scene.createSkeleton('Pr4.dae')
bradSkeleton.rescale(0.01)
scene.run('BipedMapping.py')

zebra2Map = scene.getJointMapManager().getJointMap('biped')
bradSkeleton = scene.getSkeleton('Pr4.dae')
bradSkeleton.rescale(0.01)
zebra2Map.applySkeleton(bradSkeleton)
zebra2Map.applyMotionRecurse('Pr4')
brad = scene.createCharacter('Pr4', '')

bradSkeleton = scene.createSkeleton('Pr4.dae')
brad.setSkeleton(bradSkeleton)
brad.createStandardControllers()
brad.setDoubleAttribute('deformableMeshScale', .01)
brad.setStringAttribute('deformableMesh', 'Pr4.dae')
brad.setStringAttribute('displayType', 'GPUmesh')

scene.addAssetPath("script", "behaviorsets")
scene.run("BehaviorSetCommon.py")

scene.addAssetPath("script", "behaviorsets/kickingBipedNew/scripts")
motionPath = "behaviorsets/kickingBipedNew/motions/"
skel = scene.getSkeleton("ChrGarza.sk")
if skel == None:
    scene.loadAssetsFromPath("behaviorsets/kicking/skeletons")
    
Biped2Map = scene.getJointMapManager().getJointMap("biped")
BipedSkel = scene.getSkeleton("ChrGarza.sk")
Biped2Map.applySkeleton(BipedSkel)

kickMotions = StringVec()
kickMotions.append("ChrGarza@Chut")

for i in range(0, len(kickMotions)):
    motion = scene.getMotion(kickMotions[i])
    if motion == None:
        assetManager.loadAsset(motionPath+kickMotions[i]+'.dae')
        motion = scene.getMotion(kickMotions[i])
    #print 'motionName = ' + locoMotions[i]
    if motion != None:
        motion.setMotionSkeletonName("Pr4.dae")
        Biped2Map.applyMotion(motion)

kickMotions.append("ChrGarza@Chut")    

sbChar = scene.getCharacter('Pr4')
if sbChar == None:
    print 'Fail 1'
skelName = sbChar.getSkeleton().getName()    
createRetargetInstance('Pr4.dae', skelName)

blendManager = scene.getBlendManager()
blendKicking = blendManager.createMotionBlendBase('' + "Kick", 'Pr4.dae', 3)
blendKicking.setBlendSkeleton('Pr4.dae')
originalMotions = StringVec()
originalMotions.append( "ChrGarza@Chut")

motions = StringVec()
assetManager = scene.getAssetManager()
for i in range(0, len(originalMotions)):
    motions.append('' + originalMotions[i])
    sbMotion = assetManager.getMotion(originalMotions[i])
    if sbMotion != None:
        sbMotion.setMotionSkeletonName('Pr4.dae')

para = DoubleVec();
for i in range(0,3):
    para.append(0)
para.append(0)
for i in range(0, len(motions)):
    blendKicking.addMotion(motions[i], para)        
    
points0 = DoubleVec()
points0.append(0)
blendKicking.addCorrespondencePoints(motions, points0)
points1 = DoubleVec()
points1.append(2.45) # ChrGarza@Chut
blendKicking.addCorrespondencePoints(motions, points1)
points2 = DoubleVec()
points2.append(4.63333) # ChrGarza@Chut
blendKicking.addCorrespondencePoints(motions, points2)

blendKicking.buildBlendBase("kick", "RBF" ,True);

 

The script for bipped mapping I'm using is the following:

def BipedMapping():
    # Mapping from Biped skeleton to SmartBody skeleton
    jointMapManager = scene.getJointMapManager()
    #Bipedmap = jointMapManager.getJointMap("biped")
    #if (Bipedmap == None):
    BipedMap = jointMapManager.createJointMap('biped')

    BipedMap.setMapping("Bip01", "base")
    BipedMap.setMapping("Bip01__Spine", "base1")
    BipedMap.setMapping("Bip01__Spine1", "spine1")
    BipedMap.setMapping("Bip01__Neck", "spine2")
    BipedMap.setMapping("Bip01__Head", "spine3")
    BipedMap.setMapping("Bip01__L_Clavicle", "l_sternoclavicular")
    BipedMap.setMapping("Bip01__L_UpperArm", "l_shoulder")
    BipedMap.setMapping("Bip01__L_Forearm", "l_elbow")
    BipedMap.setMapping("Bip01__L_Hand", "l_wrist")
    BipedMap.setMapping("Bip01__R_Clavicle", "r_sternoclavicular")
    BipedMap.setMapping("Bip01__R_UpperArm", "r_shoulder")
    BipedMap.setMapping("Bip01__R_Forearm", "r_elbow")
    BipedMap.setMapping("Bip01__R_Hand", "r_wrist")
    BipedMap.setMapping("Bip01__L_Thigh", "l_hip")
    BipedMap.setMapping("Bip01__L_Calf", "l_knee")
    BipedMap.setMapping("Bip01__L_Foot", "l_ankle")
    BipedMap.setMapping("Bip01__L_Toe0", "l_forefoot")
    BipedMap.setMapping("Bip01__R_Thigh", "r_hip")
    BipedMap.setMapping("Bip01__R_Calf", "r_knee")
    BipedMap.setMapping("Bip01__R_Foot", "r_ankle")
    BipedMap.setMapping("Bip01__R_Toe0", "r_forefoot")

BipedMapping()

2. The second question I have is about the steps required to take a character in .dae format (exported from 3ds Max) and give it a locomotion behavior set. I'm using the simplest I have found (BehaviourSetMaleLocomotion.py). I manage to load the animations, and the character plays them well in the motion editor window (so the skeleton mapping apparently goes well, the character has a biped skeleton from 3ds Max), but if I use IK constraints like addJointTrajectoryConstraint(), I get a crash. The warning "Pr4: Steering cannot work under example mode, reverting back to basic mode" also appears (being Pr4 the charater). Is there a way to build the simplest locomotion behavior set and start testing and fixing errors?

By the way, and if that helps, I have achieved GPU vertex skinning with SmartBody for Shader Model v2 and v3, where the number of limited registers being able in the vertex shader is limited to 1024. Basically, for each submesh I have a list of the matrices needed by that submesh to perform vertex skinning. I extract the quaternion representing the rotation and the translation for that matrix, and then supply one float4 array with those rotations, and one float3 with the translations when rendering each submesh. In the Vextex shader, I rebuild each matrix using Van Elfrinkhof's formula (explained in the web http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/) and adding the translation to the correct positions ([3][0], [3][1] and [3][2]). That way, you can perform GPU vertex skinning in devices with small number constant registers per vertex shader.

Thanks again for your help,

Alex

July 25, 2014
8:38 am
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Edit: I've fixed a couple of errors, but I still can't load the motion. Its something of strange after verifying in debug mode that the motion load is fine when drag-and-dropping it with the editor

Hi Ari, thank you very much for your help , I'm making progress but I have a couple of problems (hope the last of them :) ).

1. I have written code that tries to build the Behavior set Kicking with only one animation (to test if our animation exporting process is ok) exported from 3ds Max, for a character which has a biped skeletal scheme.
The script BipedMapping.py does the skeletal mapping between the .bip used by 3ds Max and the native SmartBody skeletal format, it is based in the script you wrote above.
I have verified that the biped mapping works loading a character with biped skeleton and applying the Behavior set Kicking with the Retarget Viewer Window, the character moves properly.

The case is that the following code generates errors and warnings:
"SBAnimationBlend add sk motion failure, ChrGarza@Chut doesn't exist"
"Add motions before add correspondence points for state"
"num motions = 0, motion parameter = kick, interpolator type = RBF"

I have verified that the ChrGarza@Chut loads properly executing the sbgui.exe in debug mode and performing drag-and-drop with the corresponding ChrGarza@Chut.dae file.
I am trying to find the error(s) that could be present in the script but having no success. Could influence the fact that the character I'm loading has an skeleton in .dae format (it is loaded from the same .dae file which contains the geometry and skinned mesh)? for example, maybe some methods like "createMotionBlendBase()" only accept a skeleton in a separate file or in .sk format.
I have tried saving the character's skeleton as a .sk file but then I cannot see the skinned mesh when I load it using the .sk file instead of the .dae file (maybe I'm doing it wrong, but I tried using the .save method from the SBSkeleton class).

The code is the following:
-----------------------------------------------------------------------
BaseScript
-----------------------------------------------------------------------
print 'media path = ' + scene.getMediaPath()
# Add asset paths
assetManager = scene.getAssetManager()
assetManager.addAssetPath('motion', 'Pr4')
assetManager.addAssetPath('mesh', 'mesh')
assetManager.addAssetPath('script', 'scripts')
# Load assets based on asset paths
assetManager.loadAssets()
# set scene scale and reset the camera
scene.setScale(1.0)
scene.getActiveCamera().reset()
bradSkeleton = scene.createSkeleton('Pr4.dae')
bradSkeleton.rescale(0.01)
# run a Python script file
scene.run('BipedMapping.py')
BipedMap = scene.getJointMapManager().getJointMap('biped')
bradSkeleton = scene.getSkeleton('Pr4.dae')
bradSkeleton.rescale(0.01)
BipedMap.applySkeleton(bradSkeleton)
BipedMap.applyMotionRecurse('Pr4')
# Set up Brad
brad = scene.createCharacter('Pr4', '')
bradSkeleton = scene.createSkeleton('Pr4.dae')
brad.setSkeleton(bradSkeleton)
# Set standard controller
brad.createStandardControllers()
brad.setDoubleAttribute('deformableMeshScale', .01)
brad.setStringAttribute('deformableMesh', 'Pr4.dae')
# show the character
brad.setStringAttribute('displayType', 'GPUmesh')

scene.addAssetPath("script", "behaviorsets")
scene.run("BehaviorSetKickingTest.py")
setupBehaviorSet()
retargetBehaviorSet('Pr4')
-----------------------------------------------------------------------

-----------------------------------------------------------------------
BehaviorSetKickingTes.py
-----------------------------------------------------------------------
scene.run("BehaviorSetCommon.py")
def setupBehaviorSet():
print "Setting up behavior set for Locomotion..."
scene.addAssetPath("script", "behaviorsets/kickingTest/scripts")

assetManager = scene.getAssetManager()
motionPath = "behaviorsets/kickingTest/motions/"
skel = scene.getSkeleton("Pr4.dae")
if skel == None:
scene.loadAssetsFromPath("behaviorsets/kickingTest/skeletons")
BipedMap = scene.getJointMapManager().getJointMap("biped")
BipedSkeleton = scene.getSkeleton("Pr4.dae")
BipedMap.applySkeleton(BipedSkeleton)
kickMotions = StringVec()

kickMotions.append("ChrGarza@Chut")
for i in range(0, len(kickMotions)):
motion = scene.getMotion(kickMotions[i])
if motion == None:
assetManager.loadAsset(motionPath+kickMotions[i]+'.dae')
motion = scene.getMotion(kickMotions[i])
#print 'motionName = ' + locoMotions[i]
if motion != None:
print 'motion != None ' + motionPath+kickMotions[i]+'.dae'
motion.setMotionSkeletonName("Pr4.dae")
BipedMap.applyMotion(motion)
if motion == None:
print 'MOTION == None ' + motionPath+kickMotions[i]+'.dae' #motion won't load

def retargetBehaviorSet(charName):
kickMotions = StringVec()

kickMotions.append("ChrGarza@Chut")
sbChar = scene.getCharacter(charName)
if sbChar == None:
return
skelName = sbChar.getSkeleton().getName()
createRetargetInstance('Pr4.dae', skelName)
scene.run("stateKicking.py")
kickingSetup('Pr4.dae','Pr4.dae', "base", '', '')
-----------------------------------------------------------------------

-----------------------------------------------------------------------
stateKicking.py
-----------------------------------------------------------------------
def kickingSetup(origSkelName, skeletonName, baseJoint, prefix, statePreFix):
blendManager = scene.getBlendManager()
blendKicking = blendManager.createMotionBlendBase(prefix + "Kick", skeletonName, 3)
blendKicking.setBlendSkeleton(skeletonName)
originalMotions = StringVec()
originalMotions.append( "ChrGarza@Chut")

motions = StringVec()
assetManager = scene.getAssetManager()
for i in range(0, len(originalMotions)):
motions.append(prefix + originalMotions[i])
print 'motion: ' + prefix + originalMotions[i]
sbMotion = assetManager.getMotion(originalMotions[i])
if sbMotion != None:
print '1'
sbMotion.setMotionSkeletonName(origSkelName)

para = DoubleVec();
for i in range(0,3):
para.append(0)
para.append(0)
for i in range(0, len(motions)):
print '2'
blendKicking.addMotion(motions[i], para)
print '3'

points0 = DoubleVec()
points0.append(0) # ChrGarza@Chut 0
blendKicking.addCorrespondencePoints(motions, points0)
points1 = DoubleVec()
points1.append(2.45) # ChrGarza@Chut 1
blendKicking.addCorrespondencePoints(motions, points1)
points2 = DoubleVec()
points2.append(4.63333) # ChrGarza@Chut 2
blendKicking.addCorrespondencePoints(motions, points2)

blendKicking.buildBlendBase("kick", "RBF" ,True);
-----------------------------------------------------------------------

The script for bipped mapping I'm using is the following:
def BipedMapping():
# Mapping from Biped skeleton to SmartBody skeleton
jointMapManager = scene.getJointMapManager()
#Bipedmap = jointMapManager.getJointMap("biped")
#if (Bipedmap == None):
BipedMap = jointMapManager.createJointMap('biped')
BipedMap.setMapping("Bip01", "base")
BipedMap.setMapping("Bip01__Spine", "base1")
BipedMap.setMapping("Bip01__Spine1", "spine1")
BipedMap.setMapping("Bip01__Neck", "spine2")
BipedMap.setMapping("Bip01__Head", "spine3")
BipedMap.setMapping("Bip01__L_Clavicle", "l_sternoclavicular")
BipedMap.setMapping("Bip01__L_UpperArm", "l_shoulder")
BipedMap.setMapping("Bip01__L_Forearm", "l_elbow")
BipedMap.setMapping("Bip01__L_Hand", "l_wrist")
BipedMap.setMapping("Bip01__R_Clavicle", "r_sternoclavicular")
BipedMap.setMapping("Bip01__R_UpperArm", "r_shoulder")
BipedMap.setMapping("Bip01__R_Forearm", "r_elbow")
BipedMap.setMapping("Bip01__R_Hand", "r_wrist")
BipedMap.setMapping("Bip01__L_Thigh", "l_hip")
BipedMap.setMapping("Bip01__L_Calf", "l_knee")
BipedMap.setMapping("Bip01__L_Foot", "l_ankle")
BipedMap.setMapping("Bip01__L_Toe0", "l_forefoot")
BipedMap.setMapping("Bip01__R_Thigh", "r_hip")
BipedMap.setMapping("Bip01__R_Calf", "r_knee")
BipedMap.setMapping("Bip01__R_Foot", "r_ankle")
BipedMap.setMapping("Bip01__R_Toe0", "r_forefoot")
BipedMapping()

2. The second question I have is about the steps required to take a character in .dae format (exported from 3ds Max) and give it a locomotion behavior set. I'm using the simplest I have found (BehaviourSetMaleLocomotion.py). I manage to load the animations, and the character plays them well in the motion editor window (so the skeleton mapping apparently goes well, the character has a biped skeleton from 3ds Max), but if I use IK constraints like addJointTrajectoryConstraint(), I get a crash. The warning "Pr4: Steering cannot work under example mode, reverting back to basic mode" also appears (being Pr4 the charater). Is there a way to build the simplest locomotion behavior set and start testing and fixing errors?
By the way, and if that helps, I have achieved GPU vertex skinning with SmartBody for Shader Model v2 and v3, where the number of limited registers being able in the vertex shader is limited to 1024. Basically, for each submesh I have a list of the matrices needed by that submesh to perform vertex skinning. I extract the quaternion representing the rotation and the translation for that matrix, and then supply one float4 array with those rotations, and one float3 with the translations when rendering each submesh. In the Vextex shader, I rebuild each matrix using Van Elfrinkhof's formula (explained in the web http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/) and adding the translation to the correct positions ([3][0], [3][1] and [3][2]). That way, you can perform GPU vertex skinning in devices with small number constant registers per vertex shader.

Thanks again for your help,

Alex

July 25, 2014
5:52 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Hi again Ari,

well, the animation load problem has been solved earlier than I believed. The mistake was in my script, SmartBody saves Motions with .dae extension as part of the resource name, so when getting a motion, I have only to add the ".dae" string and there's no problem in finding it.

So, I update my questions:

1. What would be the steps required to take a character in .dae format (exported from 3ds Max) and give it a locomotion behavior set? Is there a minimal scheme to start with for avoiding bugs?

2. I've loaded and exported animation from Max, the characater plays it properly at a "local level", i.e., its translations and rotations are incorrect. We think that it could be related to the requirement when exporting animations: the first frame must be the character in T pose. When doubt if the character must be in T pose with no orientation nor translation (i.e. at the origin of coordinates), or if it has to be in the same position and orientation as the character in the frame 1.

3. When playing an exported animation, the skin can barely be seen, skeleton is practically all we see. Could it have to do with the SmartBody native skeleton scaling used? (I have made an "one-exported-animation" Kicking behavior set, and this is what happens when playing the only animation)

thanks for your help,

best regards,

Alex

July 27, 2014
10:53 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

1. Load the .dae into SmartBody:

scene.loadAssetsFromPath("/path/to/my/file/mycharacter.dae")

# That will load the contents of the .dae into SmartBody (presumably, the .dae contains both the skeleton and the skinning information)

# Next, create a character and a skeleton using your .dae:

sk = scene.createSkeleton("mycharacter.dae")

mychar = scene.createCharacter("mycharacter", "")

mychar.setSkeleton(sk)

 

# create a joint map that translates from your own joint names to the SmartBody standard names:

myjointmap = scene.getJointMapManager().createJointMap("mymap)

myjointmap.addMapping("whatever", "base")

#etc.

 

#apply the joint map to the character's skeleton:

myjointmap.applySkeleton(mychar.getSkeleton())

 

#create the standard set of controllers for the character:

mychar.createStandardControllers()

 

#load the behaviorset:

scene.run('BehaviorSetMaleMocapLocomotion.py')
setupBehaviorSet()
retargetBehaviorSet('mycharacter')

 

2. The exported animation data should be relative to the t-pose. The first frame doesn't have to be the t-pose, but the data should represent an offset from the t-pose. I believe that this is fairly standard among game asset pipelines.

 

3. The mesh that is loaded (presumably from a .dae) will contain skin weight mappings. You can attach this to the skeleton by setting the deformableMesh attribute:

 

mycharacter.setStringAttribute("deformableMesh", "mycharacter.dae")

 

sometimes the units are not correct (.dae often exports in centimeters), so first you need to scale the mesh:

 

mycharacter.setDoubleAttribute("deformableMeshScale", .01)

mycharacter.setStringAttribute("deformableMesh", "mycharacter.dae")

Ari

July 28, 2014
3:01 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

thank you Ari, your help is highly appreciated

August 18, 2014
6:53 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Thank you Ari,

We've exported animations with Max and they load perfectly into SmartBody yet we have one problem: the character plays it facing the ground and advancing towards the floor. It has to do with the "up" direction (or at least is what we think), in Max it is the Z axis, but in OpenGL and DirectX (as well as in Maya), the up direction is the Y axis. Do you know any way to fix it? selecting a different up axis when exporting animations with the Open Collada exporter for Max does not work, for animations rotation matrices are involved and switching between the two axis is not enough.

And, another question, it has to do with retargeting. I would like to apply an existing locomotion to one of our biped exported characters from 3ds Max, to test motions and mesh skinning with the exported characters. I'm following the steps you gave me in the previous answer (thanks again for it), and taking as reference the "5_UsingBML.py" tutorial script, but I think that I have to map between the .skm animations native skeleton (zebra), and do a second skeleton mapping for the biped exported character. Is there any example script available? (or please, which would be the right steps for doing if?) I have a working script to map between biped and SmartBody native skeleton format, but don't know the steps to map from zebra to biped (if that's the right way to do it),

thank you very much again,

best regards,

Alex

August 19, 2014
5:53 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

You can perform a rotation on the skeleton in order to reorient the skeleton:

myskel = scene.getSkeleton("MySkeleton.bvh") # whatever the skeleton name is

joint = myskel.getJoint("base") # the root joint here

joint.setPrerotation(SrVec(1, 0, 0), -3.14159  / 2.0) # prerotate the root joint by 90 degree

 

The easiest way to do this is to:

1) Create a joint map for your character; this will convert your joint names into the SmartBody standard names

2) run the locomotion behavior set like this:

scene.run('BehaviorSetMaleMocapLocomotion.py')
setupBehaviorSet()
retargetBehaviorSet('MyCharacter')

which will handle all of the retargeting. Essentially, you want to 'convert' your skeletons and motions into the SmartBody naming convention. To perform a retargeting, you want to set up a retargeting instance between your skeleton and the skeleton that was used for the motion that you are interested in playing. Again, the behavior set code will do all of this for you.

Please let me know if that works for you.

Ari

 

August 20, 2014
9:23 am
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Thank you very much Ari, the base joint prerotation worked perfectly!

I made a small modification to the code regarding the parameters:

joint = BipedSkeleton.getJoint(0)
QuatPR = SrQuat(SrVec(1.0, 0.0, 0.0), -3.14159  / 2.0)
joint.setPrerotation(QuatPR)

And, about playing SmartBody motions with a biped... it worked too :)

best regards and thanks a lot,

Alex

August 21, 2014
7:45 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Glad it worked. Please let me know if you have any other problems or questions.

Ari

March 26, 2016
2:44 pm
Avatar
Member
Members
Forum Posts: 10
Member Since:
March 26, 2016
sp_UserOfflineSmall Offline

Greetings!

I just started using SmartBody, I have read the manual and some parts of this forum.

I exported a dae file from 3DSmax using opencollada, and when I drag and drop it to the scene nothing is generated.

---

 

I went about this differently, and used mixamo to rig it, and got a dae file from mixamo.

I drag and dropped the dae file and again, nothing is shown on the scene - this time however, the root displayed the models. When I checked the retarget viewer it mapped out the skeleton that mixamo had generated for me correctly. Still nothing is displayed on the scene. (I had checked for any camera distances / views / etc; it is literally not in the scene.)

March 27, 2016
8:17 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

What platform are you running on?

 

Press 'f' in the scene to bring the objects into focus, perhaps change the Scene scale to .01 (centimeters) (Scene object in outliner, 'scale' attribute is in lower left window).

 

Ari

March 27, 2016
10:52 pm
Avatar
Member
Members
Forum Posts: 10
Member Since:
March 26, 2016
sp_UserOfflineSmall Offline

hi, 

I'm running it on Windows. 

I followed the steps as specified in the manual (for Mixamo) but I still ended up with this:

Image EnlargerDrag and drop is not working with the openCollada file. So I exported it from 3DSMax and followed the mixamo steps instead.

Here are the files I am trying to add to my scene:

https://drive.google.com/folderview?id=0BwVWreXtuLVfdGRueFQ2R1VPdlk&usp=sharing

April 2, 2016
9:17 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

The dae format is one that the SmartBody parser cannot read. Was able to import it into Maya, select only the geometry and joints and then export to a dae to get it to work.

 

Ari

April 17, 2016
10:32 pm
Avatar
Member
Members
Forum Posts: 10
Member Since:
March 26, 2016
sp_UserOfflineSmall Offline

Hi Ari, 

Our idea is to make the teddy bear communicate with children --- do you think it would be possible to facially rig this bear model? (If yes, do you have any advice on how to do this? - I am new to the field of Modeling and Embodied Conversational Agents)

The model is still in progress, the idea is to make it very human-like; we would add eyebrows, eyelids, etc; but, still maintaining its cute qualities.

April 19, 2016
9:54 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

You can use any humanoid character that you like and any face-control mechanism that you choose. SmartBody needs the eyes to be rigged with joints, but the rest of the face can be rigged with either joints or blendshapes, the extent to which is determined by you. There are instructions for this in the SmartBody manual.

If the bear moves in a human-like way (bipedal) then it will work fine. SmartBody doesn't have controllers for quadrupeds, although you certainly could use quadrupedal animation on its own in SmartBody.

 

Ari

Forum Timezone: America/Los_Angeles

Most Users Ever Online: 733

Currently Online: Jamesnuh, gotselyuk1987mon, levinebarron45, koenig62ramos, krygerhagen69, coxgeorge3, doyle68bekker, ludvigsen62abbott, pachecostephansen23, shortstext78, cormierhopper5
69 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

jwwalker: 80

jyambao: 52

rbaral: 47

adiaz: 30

WargnierP: 29

lucky7456969: 28

mbarros: 28

avida.matt: 26

JonathanW: 24

laguerre: 23

Member Stats:

Guest Posters: 67

Members: 100502

Moderators: 3

Admins: 4

Forum Stats:

Groups: 1

Forums: 5

Topics: 460

Posts: 2403