University of Southern CaliforniaUSC
USC ICT TwitterUSC ICT FacebookUSC ICT YouTube

Problem setting blend triangles | 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
Problem setting blend triangles
September 17, 2014
12:04 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Hi Ary,

Thanks for all your help, I've been able to advance a lot with Smartbody.

I'm building simple blends and I've obtained a few of them which works fine, although when I try to build a more complex one I have a small problem with the triangles / tetrahedrons added to the blend.

I enclose you a sample script which builds a basic 2D motion from the kicking animations of the behavior set, I execute it from the command window and runs with no errors.

What I wanted to do is use the "low" and "high" animations to make the character cover all the area between low and high kicks with those motions using the blend, and the parameters to indicate the character which motions to blend. The problem (I think) I have is that I cannot correctly set the triangles of the blend and the character doesn't reach some parts.

The links to the images shows a particular case of the problem: the character is able to do a good forward and right high kick, but I cannot set the character to perform a "hight forward-right" kick when setting the specific parameter for direction between the forward and right kick, blending with low kick motions. I cannot figure out what I'm doing wrong after many attempts so I would ask you for your advice.

http://imageshack.com/f/hjM9fUesp

http://imageshack.com/f/pcHYpN9Tp

http://imageshack.com/f/p4J2Mcptp

Thanks a lot and best regards,

Alex

Script to test my "problematic" blend:

print 'media path = ' + scene.getMediaPath()
# Add asset paths
assetManager = scene.getAssetManager()
assetManager.addAssetPath('motion', 'ChrBrad')
assetManager.addAssetPath('mesh', 'mesh')
assetManager.addAssetPath('script', 'scripts')
# Load assets based on asset paths
assetManager.loadAssets()

# set the camera
scene.setScale(1.0)
scene.run('default-viewer.py')

# run a Python script file
scene.run('zebra2-map.py')
zebra2Map = scene.getJointMapManager().getJointMap('zebra2')
bradSkeleton = scene.getSkeleton('ChrBrad.sk')
zebra2Map.applySkeleton(bradSkeleton)
zebra2Map.applyMotionRecurse('ChrBrad')

# Set up Brad
brad = scene.createCharacter('ChrBrad', '')
bradSkeleton = scene.createSkeleton('ChrBrad.sk')
brad.setSkeleton(bradSkeleton)
# Set standard controller
brad.createStandardControllers()
# Deformable mesh
brad.setDoubleAttribute('deformableMeshScale', .01)
brad.setStringAttribute('deformableMesh', 'ChrBrad.dae')
# show the character
brad.setStringAttribute('displayType', 'GPUmesh')

##################################################################################
# Add behavior set for kicking
scene.addAssetPath("script", "behaviorsets/kicking/scripts")
    
motionPath = "behaviorsets/kicking/motions/"
skel = scene.getSkeleton("ChrGarza.sk")
if skel == None:
    scene.loadAssetsFromPath("behaviorsets/kicking/skeletons")
    
scene.run("zebra2-map.py")
zebra2Map = scene.getJointMapManager().getJointMap("zebra2")
zebra2Skeleton = scene.getSkeleton("ChrGarza.sk")
zebra2Map.applySkeleton(zebra2Skeleton)

kickMotions = StringVec()

kickMotions.append("ChrGarza@IdleFight01")    
kickMotions.append("ChrGarza@IdleFight01_KickBackHigh01")
kickMotions.append("ChrGarza@IdleFight01_KickBackLow01")
kickMotions.append("ChrGarza@IdleFight01_KickBackMedium01")
kickMotions.append("ChrGarza@IdleFight01_KickForwardHigh01")
kickMotions.append("ChrGarza@IdleFight01_KickForwardLow01")
kickMotions.append("ChrGarza@IdleFight01_KickForwardMedium01")
kickMotions.append("ChrGarza@IdleFight01_KickLeftSideHigh01")
kickMotions.append("ChrGarza@IdleFight01_KickLeftSideLow01")
kickMotions.append("ChrGarza@IdleFight01_KickLeftSideMedium01")
kickMotions.append("ChrGarza@IdleFight01_KickRightSideHigh01")
kickMotions.append("ChrGarza@IdleFight01_KickRightSideLow01")
kickMotions.append("ChrGarza@IdleFight01_KickRightSideMedium01")

for i in range(0, len(kickMotions)):
    motion = scene.getMotion(kickMotions[i])
    if motion == None:
        assetManager.loadAsset(motionPath+kickMotions[i]+'.skm')
        motion = scene.getMotion(kickMotions[i])
    if motion != None:
        motion.setMotionSkeletonName("ChrGarza.sk")
        zebra2Map.applyMotion(motion)

# Trim frames for the kicking animations to generate "quick kicks"
vecTrimStart = []
vecTrimStart.append(1) # IdleFight01
vecTrimStart.append(55) # IdleFight01_KickBackHigh01
vecTrimStart.append(65) # IdleFight01_KickBackLow01
vecTrimStart.append(67) # IdleFight01_KickBackMedium01
vecTrimStart.append(42) # IdleFight01_KickForwardHigh01
vecTrimStart.append(48) # IdleFight01_KickForwardLow01
vecTrimStart.append(40) # IdleFight01_KickForwardMedium01
vecTrimStart.append(41) # IdleFight01_KickLeftSideHigh01
vecTrimStart.append(37) # IdleFight01_KickLeftSideLow01
vecTrimStart.append(51) # IdleFight01_KickLeftSideMedium01
vecTrimStart.append(40) # IdleFight01_KickRightSideHigh01
vecTrimStart.append(59) # IdleFight01_KickRightSideLow01
vecTrimStart.append(41) # IdleFight01_KickRightSideMedium01

vecTrimEnd = []
vecTrimEnd.append(146) # IdleFight01
vecTrimEnd.append(22) # IdleFight01_KickBackHigh01
vecTrimEnd.append(70) # IdleFight01_KickBackLow01
vecTrimEnd.append(59) # IdleFight01_KickBackMedium01
vecTrimEnd.append(31) # IdleFight01_KickForwardHigh01
vecTrimEnd.append(48) # IdleFight01_KickForwardLow01
vecTrimEnd.append(31) # IdleFight01_KickForwardMedium01
vecTrimEnd.append(52) # IdleFight01_KickLeftSideHigh01
vecTrimEnd.append(29) # IdleFight01_KickLeftSideLow01
vecTrimEnd.append(37) # IdleFight01_KickLeftSideMedium01
vecTrimEnd.append(41) # IdleFight01_KickRightSideHigh01
vecTrimEnd.append(38) # IdleFight01_KickRightSideLow01
vecTrimEnd.append(38) # IdleFight01_KickRightSideMedium01

for i in range(0, len(vecTrimStart)):
    motion     = scene.getMotion(kickMotions[i])
    iTrimStart = vecTrimStart[i]
    iTrimEnd   = vecTrimEnd[i]
    motion.trim(iTrimStart,iTrimEnd)

# Build a 2D blend with low and high kick positions
stateManager = scene.getStateManager()
blendstate0 = stateManager.createBlend2D("state0")
blendstate0.setBlendSkeleton('ChrBackovic.sk')
motions = StringVec()
motions.append("ChrGarza@IdleFight01_KickBackHigh01")
motions.append("ChrGarza@IdleFight01_KickBackLow01")
motions.append("ChrGarza@IdleFight01_KickForwardHigh01")
motions.append("ChrGarza@IdleFight01_KickForwardLow01")
motions.append("ChrGarza@IdleFight01_KickLeftSideHigh01")
motions.append("ChrGarza@IdleFight01_KickLeftSideLow01")
motions.append("ChrGarza@IdleFight01_KickRightSideHigh01")
motions.append("ChrGarza@IdleFight01_KickRightSideLow01")

# This param represents the angle in radians of the character when performing the action, starting from the +x axis and
# considering counter clockwise
paramsX = DoubleVec()
paramsX.append(4.71) # ChrGarza@IdleFight01_KickBackHigh01 Y
paramsX.append(4.71) # ChrGarza@IdleFight01_KickBackLow01 Y
paramsX.append(1.57) # ChrGarza@IdleFight01_KickForwardHigh01 Y
paramsX.append(1.57) # ChrGarza@IdleFight01_KickForwardLow01 Y
paramsX.append(3.14) # ChrGarza@IdleFight01_KickLeftSideHigh01 Y
paramsX.append(3.14) # ChrGarza@IdleFight01_KickLeftSideLow01 Y
paramsX.append(0.0) # ChrGarza@IdleFight01_KickRightSideHigh01 Y
paramsX.append(0.0) # ChrGarza@IdleFight01_KickRightSideLow01 Y

# High = 1, low = 0
paramsY = DoubleVec()
paramsY.append(1.0) # ChrGarza@IdleFight01_KickBackHigh01 Y
paramsY.append(0.0) # ChrGarza@IdleFight01_KickBackLow01 Y
paramsY.append(1.0) # ChrGarza@IdleFight01_KickForwardHigh01 Y
paramsY.append(0.0) # ChrGarza@IdleFight01_KickForwardLow01 Y
paramsY.append(1.0) # ChrGarza@IdleFight01_KickLeftSideHigh01 Y
paramsY.append(0.0) # ChrGarza@IdleFight01_KickLeftSideLow01 Y
paramsY.append(1.0) # ChrGarza@IdleFight01_KickRightSideHigh01 Y
paramsY.append(0.0) # ChrGarza@IdleFight01_KickRightSideLow01 Y

for i in range(0, len(motions)):
    blendstate0.addMotion(motions[i], paramsX[i], paramsY[i])

# Add correspondence points
points0 = DoubleVec()
points0.append(0) # ChrGarza@IdleFight01_KickBackHigh01 0
points0.append(0) # ChrGarza@IdleFight01_KickBackLow01 0
points0.append(0) # ChrGarza@IdleFight01_KickForwardHigh01 0
points0.append(0) # ChrGarza@IdleFight01_KickForwardLow01 0
points0.append(0) # ChrGarza@IdleFight01_KickLeftSideHigh01 0
points0.append(0) # ChrGarza@IdleFight01_KickLeftSideLow01 0
points0.append(0) # ChrGarza@IdleFight01_KickRightSideHigh01 0
points0.append(0) # ChrGarza@IdleFight01_KickRightSideLow01 0
blendstate0.addCorrespondencePoints(motions, points0)

points1 = DoubleVec()
points1.append(0.62) # ChrGarza@IdleFight01_KickBackHigh01 1
points1.append(0.51) # ChrGarza@IdleFight01_KickBackLow01 1
points1.append(0.84) # ChrGarza@IdleFight01_KickForwardHigh01 1
points1.append(0.63) # ChrGarza@IdleFight01_KickForwardLow01 1
points1.append(0.66) # ChrGarza@IdleFight01_KickLeftSideHigh01 1
points1.append(0.59) # ChrGarza@IdleFight01_KickLeftSideLow01 1
points1.append(0.65) # ChrGarza@IdleFight01_KickRightSideHigh01 1
points1.append(0.58) # ChrGarza@IdleFight01_KickRightSideLow01 1
blendstate0.addCorrespondencePoints(motions, points1)

points2 = DoubleVec()
points2.append(2.06667) # ChrGarza@IdleFight01_KickBackHigh01 2
points2.append(1.46667) # ChrGarza@IdleFight01_KickBackLow01 2
points2.append(1.7) # ChrGarza@IdleFight01_KickForwardHigh01 2
points2.append(1.46667) # ChrGarza@IdleFight01_KickForwardLow01 2
points2.append(1.56667) # ChrGarza@IdleFight01_KickLeftSideHigh01 2
points2.append(1.1) # ChrGarza@IdleFight01_KickLeftSideLow01 2
points2.append(1.6) # ChrGarza@IdleFight01_KickRightSideHigh01 2
points2.append(1.4) # ChrGarza@IdleFight01_KickRightSideLow01 2
blendstate0.addCorrespondencePoints(motions, points2)

# Add triangles, what are the right options to allow true uniform blending between low and high kicks
#blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardLow01","ChrGarza@IdleFight01_KickLeftSideLow01","ChrGarza@IdleFight01_KickBackLow01")
#blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardLow01","ChrGarza@IdleFight01_KickRightSideLow01","ChrGarza@IdleFight01_KickBackLow01")
#blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01","ChrGarza@IdleFight01_KickLeftSideHigh01","ChrGarza@IdleFight01_KickBackHigh01")
#blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01","ChrGarza@IdleFight01_KickRightSideHigh01","ChrGarza@IdleFight01_KickBackHigh01")

blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01","ChrGarza@IdleFight01_KickLeftSideHigh01","ChrGarza@IdleFight01_KickForwardLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01","ChrGarza@IdleFight01_KickLeftSideHigh01","ChrGarza@IdleFight01_KickLeftSideLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01","ChrGarza@IdleFight01_KickRightSideHigh01","ChrGarza@IdleFight01_KickForwardLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01","ChrGarza@IdleFight01_KickRightSideHigh01","ChrGarza@IdleFight01_KickRightSideLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickBackHigh01","ChrGarza@IdleFight01_KickLeftSideHigh01","ChrGarza@IdleFight01_KickBackLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickBackHigh01","ChrGarza@IdleFight01_KickLeftSideHigh01","ChrGarza@IdleFight01_KickLeftSideLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickBackHigh01","ChrGarza@IdleFight01_KickRightSideHigh01","ChrGarza@IdleFight01_KickBackLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickBackHigh01","ChrGarza@IdleFight01_KickRightSideHigh01","ChrGarza@IdleFight01_KickRightSideLow01")
##################################################################################

# Starting the simulation
sim.start()
# set posture
bml.execBML('ChrBrad', '<body posture="ChrBrad@Idle01"/>')
sim.resume()

September 18, 2014
7:41 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Thanks for the test script; makes it easy to replicate your problem.

1) Your parameterized spaces are a bit too convoluted for good results. Try using this set instead:

 

blendstate0.addTriangle("ChrGarza@IdleFight01_KickBackHigh01", "ChrGarza@IdleFight01_KickBackLow01", "ChrGarza@IdleFight01_KickLeftSideHigh01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickBackLow01", "ChrGarza@IdleFight01_KickLeftSideHigh01", "ChrGarza@IdleFight01_KickLeftSideLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardLow01", "ChrGarza@IdleFight01_KickRightSideHigh01", "ChrGarza@IdleFight01_KickRightSideLow01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01", "ChrGarza@IdleFight01_KickForwardLow01", "ChrGarza@IdleFight01_KickRightSideHigh01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardHigh01", "ChrGarza@IdleFight01_KickForwardLow01", "ChrGarza@IdleFight01_KickLeftSideHigh01")
blendstate0.addTriangle("ChrGarza@IdleFight01_KickForwardLow01", "ChrGarza@IdleFight01_KickLeftSideHigh01", "ChrGarza@IdleFight01_KickLeftSideLow01")

 

You can see a screen capture of it here:

http://smartbody.ict.usc.edu/s.....d_kick.png

 

2) Since some of the kicks are 'back kicks', they won't blend very well with the front kicks. You should separate completely the back kicks from the front kicks (perhaps even as a separate blend), since 50% of a back kick + 50% of a front kick will give you something that is neither one.

 

Ari

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

Hi Ary,

you're welcome, giving scripts that replicate the problems is the best way to get helped.

Thanks for your clarification, now the blend works like charm and I have a better idea of how the topology of parameterized spaces should be.

I also have one question: is it possible to use any of the Smartbody inverse kinematics features with the feet of the characters? (for example, a touch or reach behavior that takes one foot of the character and carries it to a particular spatial position).

 

Thanks a lot and best regards,

Alex

September 23, 2014
10:57 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

There is an IK controller for the feet (mycharacter_postprocessController) that works with locomotion. You can turn it on and off like this:

 

c = scene.getCharacter("mycharacter")

ikcontroller = c.getControllerByName(c.getName() + "_postprocessController")

ikcontroller.setBoolAttribute("enable", False)

 

You can also use the contraints mechanism to attach foot parts to something:

 

bml.execBML('*', '<sbm:constraint effector="l_ankle" sbm:effector-root="l_hip" sbm:fade-in="1" sbm:handle="myconstraint2" target="pawn0"/>')

I this case we are attaching the left ankle, starting from the hip, to the pawn named 'pawn0' over a period of 1 second, but I can't guarantee the naturalness of the movement. It's primarily meant to make small changes in position.

 

Ari

September 24, 2014
12:41 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Thanks for your help Ari,

I've tried the constraint mechanism (of course works perfect), and I would like to try the IK controller for the feet.

I've identified the controller in the C++ source (SbmCharacter::postprocess_ct of type MeCtPosePostProcessing*). The case is that I don't know exactly how to set the constraint. There's a method in the MeCtPosePostProcessing class inherited from MeCtConstraint, "addEffectorJointPair(...)", is that the right method to be used? (in that case, I'm afraid I get a link error from Visual Studio 2010: "error LNK2001...", the method seems not to be available in the dll for some reason, I've dumped into a .txt file all the functions available in the dll files present in the SmartBody/bin and the lib files present in SmartBody/lib directories and I'm afraid that function is not present and therefore not available for calling). There's also BML::parse_bml_constraint() which can call "addEffectorJointPair()", maybe that is the way I should do it.

Are there any examples or scripts available for the IK controller with locomotion?

 

Thanks a lot and best regards,

Alex

Forum Timezone: America/Los_Angeles

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: 69

Members: 122211

Moderators: 3

Admins: 4

Forum Stats:

Groups: 1

Forums: 5

Topics: 531

Posts: 2495