SmartBody is a character animation platform originally developed at the University of Southern California Institute for Creative Technologies. SmartBody provides locomotion, steering, object manipulation, lip syncing, gazing and nonverbal behavior in real time.
SmartBody is written in C++ and can be incorporated into most game and simulation engines. SmartBody is a Behavioral Markup Language (BML) realization engine that transforms BML behavior descriptions into realtime animations. SmartBody runs on Windows, Linux, OSx as well as the iPhone and Android devices.
I want to use this to control the character animations for a video game made in Unity3D.
The package does say this it can work with
- Unity
- Ogre
- Unreal
- Panda3D
- GameBryo
Goal: To send BML messages to a control characters in SmartBody via TCP or UDP messages.
Tasks:
- Get and Compile SmartBody ( For Windows and Linux )
- Familiarize self with SmartBody examples
- Learn how to use TCP in Python.
- Produce code to control SmartBody character from python code combining what was learned from 2 and 3.
import random
import select
import socket
import sys
service = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = ('localhost', 3850)
print >> sys.stderr, 'connecting to %s port %s' % server_address
service.connect(server_address)
print "|--------------------------------------------|"
print "| Starting Locomotion Type Demo |"
print "|--------------------------------------------|"
smartBodyRelitivePath = "../../smartbody/data/"
# Add asset paths
scene.addAssetPath('script',smartBodyRelitivePath + 'sbm-common/scripts')
scene.addAssetPath('mesh', smartBodyRelitivePath + 'mesh')
scene.addAssetPath('mesh', smartBodyRelitivePath + 'retarget/mesh')
scene.addAssetPath('motion', smartBodyRelitivePath + 'ChrBrad')
scene.addAssetPath('motion', smartBodyRelitivePath + 'ChrRachel')
scene.addAssetPath('motion', smartBodyRelitivePath + 'retarget\motion')
scene.addAssetPath('motion', smartBodyRelitivePath + 'sbm-common/common-sk')
scene.loadAssets()
# Set scene parameters and camera
print 'Configuring scene parameters and camera'
scene.setScale(1.0)
scene.setBoolAttribute('internalAudio', True)
scene.run('default-viewer.py')
camera = getCamera()
camera.setEye(0, 2.87, 11.67)
camera.setCenter(0, 2.14, 9.81)
camera.setUpVector(SrVec(0, 1, 0))
camera.setScale(1)
camera.setFov(1.0472)
camera.setFarPlane(100)
camera.setNearPlane(0.1)
camera.setAspectRatio(0.966897)
scene.getPawn('camera').setPosition(SrVec(0, -5, 0))
# Set joint map for Brad
print 'Setting up joint map for Brad'
scene.run('zebra2-map.py')
zebra2Map = scene.getJointMapManager().getJointMap('zebra2')
bradSkeleton = scene.getSkeleton('ChrBrad.sk')
zebra2Map.applySkeleton(bradSkeleton)
zebra2Map.applyMotionRecurse('ChrBrad')
# Retarget setup
scene.run('motion-retarget.py')
# Animation setup
scene.run('init-param-animation.py')
# Set up 3 Brads
print 'Adding characters into scene'
posX = -200
for i in range(1): # Only add one brad
baseName = 'ChrBrad%s' % i
brad = scene.createCharacter(baseName, '')
bradSkeleton = scene.createSkeleton('ChrBrad.sk')
brad.setSkeleton(bradSkeleton)
# Set position
bradPos = SrVec((posX + (i * 200))/100, 0, 0)
brad.setPosition(bradPos)
# Set up standard controllers
brad.createStandardControllers()
# Set deformable mesh
brad.setDoubleAttribute('deformableMeshScale', .01)
brad.setStringAttribute('deformableMesh', 'ChrBrad')
# Play idle animation
bml.execBML(baseName, '')
# Retarget character
retargetCharacter(baseName, 'ChrBrad.sk', False)
# Turn on GPU deformable geometry for all
for name in scene.getCharacterNames():
scene.command("char %s viewer deformableGPU" % name)
# Whether character has reached its target
brad1Reached = True
# Paths for characters
brad1Path = [SrVec(-2, 8, 0), SrVec(-2, -8, 0)]
bradCur = 0
pathAmt = 2
class LocomotionDemo(SBScript):
def update(self, time):
# Select is a creative way of checking to see if a service has data ready to read,
# ready to write to or an exceptional condition.
r, w, e = select.select([service], [], [], 0.0)
if r: # There is something to read
data = service.recv(256)
character = 'ChrBrad0'
# The last 0 in the target is zero just so the character stays on the plane
bmlMessage = ''
print "BML Message for " + character + ": " + bmlMessage
bml.execBML(character, bmlMessage)
# Run the update script
scene.removeScript('locomotiondemo')
locomotiondemo = LocomotionDemo()
scene.addScript('locomotiondemo', locomotiondemo)