Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

To build an agent type event, open the Atoms UI and make sure to have the "AgentTypeEvents" tab selected.

Click on "Add" and you will be prompted with a dialog asking if you want to edit your clip in GUI or script mode.


GUI mode

Give a name for your agent type (i.e. testRobot).

Select the skeleton and geo files you exported previously. The "Skeleton File" will point to your skeleton definition file (.atomsskel, .fbx or .usd), the "Geo Path" to your proxy geo file and , the "Skin Path" to your skinned geo file (.geos, .fbx or .usd) and the "Ragdoll Path" to your ragdoll file.

Set the state machine to "robotStateMachine" (you created this in the previous section) or select it from the drop down menu on the right side of the field.

You can edit the Agent Type scale multiplier if you want, but it's not necessary for this tutorial. 

Joint Tags

Atoms need some information on some joints to be able to place an agent correctly on a ground.


First, you need to tag all the pelvis. The first pelvis must the first joint for the hierarchy. In my case, the first joint is named "root ". Expand the pelvises tab, then write "root" inside the joint field and press the "add pelvis" button. It adds the pelvis tag to the root joint. If your skeleton is a quadruped, you need to tag also the second pelvis that is the joint that connect the front legs or if a creature with more legs tag any other pelvis.


Now we need to tag the legs. Expand the legs tab. You need to set here 4 input to define a leg. Inside the root field, write the start joint of a leg. In this case, for my left leg, I added LeftUpLeg. Then I need to fill the Ik field. It will be the joint of the ankle where Atoms adds the ik affector. In my case is the joint LeftFoot. Then we need to set the tip joint. It is the joint on the foot that checks the contact with the ground during the simulation. In my case, it's the LeftToeBase joint. The last parameter is the pole vector. Here you need to set the world position of the pole vector effector. For my left leg the root joint is around position (9.0, -9.0, 0.0) so a pole vector of (9.0, -9.0, 12.0) should be enough. If you don't want to pass a pole vector but let atoms compute automatically just set (0,0,0). At this point press the "Add leg "button to tag the leg joints. Do the same for the right leg.


The last thing to do is to add the skipIk tag. This tag is used to exclude joints from the computation of the ik. For example, if you have a joint between the leg root and the knee, or the knee and the ankle you usually want to exclude this joint from the ik computation, otherwise Atoms rotates as well this joint. So write the nake of the joint that you want to exclude inside the SkipIk tab and press the "Add SkipIk "button to tag this joint.

Your GUI should look like the one in the picture.
Click on the "Register" button or press CTRL+S.

Your agent type is now ready to be used.

Note

The Agent Type scale multiplier will affect all agents of this type. If you want to change the scale of a specific agent you should use the agent scale Behaviour Module.


Image RemovedImage Added


Script mode

In case you selected the script mode, you should edit your script so it looks like the following.

Then hit CTRL+S or click on the "Register" button. 

AgentType
Code Block
languagepy
themeEclipsefirstline1titleAgentType
import os
import AtomsMath
import AtomsCore
import Atoms
import AtomsUtils
from Atoms import GLOBAL_NAMES


class 
AgentTypeEvent2
AgentTypeEvent1(Atoms.SimulationEvent):
    eventName = '
testRobot
agentType1'
    skelFile = '
D:/projects/atomsDemo/configs/atomsRobot
path/file.atomsskel'
    geoPath = '
D:/projects/atomsDemo/configs/atomsRobot
path/file.geos'
    skinPath = '
D:/projects/atomsDemo/configs/atomsRobot_skin.geos
path/file.geos'
    ragdollSetupPath = 'path/file.atomsragdoll'
    characterSetupPath = 'path/file.atomscharacter'
    stateMachine = '
robotStateMachine
'
    scaleMultiplier = 1.0
    drawOptimization = {}
    pelvises = []
    skipIks = []
    legs = []

    def __init__(self):
        Atoms.SimulationEvent.__init__(self)
        self.setName(self.eventName)

    def load(self):
        AGENT_TYPE = GLOBAL_NAMES.AGENT_TYPE
        
        skel =
AtomsCore.Skeleton(1)
 Atoms.loadSkeleton(self.skelFile)
        for p in self.pelvises:
            id = skel.jointId(p)
            if id != -1:
                skel.addPelvis(id)

        for si in self.skipIks:
            id = skel.jointId(si)
           
skeletonArchive
 if id != -1:
                skipIkMeta = AtomsCore.
Archive
BoolMetadata(True)
        
if skeletonArchive.readFromFile(self.skelFile):
        skel.addJointMetadata(id, "skipIk", skipIkMeta)

        for f in self.legs:
            if not isinstance(f, (tuple, list)) or not len(f) == 4:
                continue
          
skel.deserialise(skeletonArchive)
  root = skel.jointId(f[0])
            ik = skel.jointId(f[1])
            tip = skel.jointId(f[2])
            if root == -1 or tip == -1 or ik == -1:
                continue
            skel.addFoot(ik, root, tip)
            poleVector = AtomsMath.V3d(f[3][0], f[3][1], f[3][2])
            poleVectorMeta = AtomsCore.Vector3Metadata(poleVector)
            skel.addJointMetadata(root, "poleVector", poleVectorMeta)
        if self.legs or 
else
self.pelvises:
            
return
skel.buildIkData()

        aType = Atoms.AgentType()
        aType.setSkeleton(skel)

        meshMap = Atoms.loadMesh(self.geoPath)
        if meshMap:
            aType.metadata()[AGENT_TYPE.LOW_GEO] = meshMap
        elif self.geoPath != "":
            AtomsUtils.Logger.warning("Could not read geo file: " + str(self.geoPath))

        skinMap = Atoms.loadMesh(self.skinPath)
        if skinMap:
            aType.metadata()[AGENT_TYPE.SKIN_GEO] = skinMap
        elif self.skinPath != "":
            AtomsUtils.Logger.warning("Could not read skin geo file: " + str(self.skinPath))

        ragdoll_setup = AtomsCore.MapMetadata()
        
typeArchive
if self.ragdollSetupPath:
            ark = AtomsCore.Archive()
            if 
typeArchive
ark.readFromFile(AtomsUtils.solvePath(self.
geoPath
ragdollSetupPath)):
                
meshMap
ragdoll_setup.deserialise(
typeArchive
ark)

        aType.metadata()[AGENT_TYPE.
LOW_GEO
RAGDOLL] = 
meshMap
ragdoll_setup

        
skinMap
character_setup = AtomsCore.MapMetadata()
        if self.characterSetupPath:
            
skinArchive
ark = AtomsCore.Archive()
            if 
skinArchive
ark.readFromFile(AtomsUtils.solvePath(self.
skinPath
characterSetupPath)):
                
skinMap
character_setup.deserialise(
skinArchive
ark)
                aType.metadata()[AGENT_TYPE.
SKIN_GEO
CHARACTER] = character_setup
        else:
            character_setup = Atoms.createCharacterizationFromSkeleton(self.skelFile)
            if character_setup:
                aType.metadata()[AGENT_TYPE.CHARACTER] = 
skinMap
character_setup

        aType.metadata()[AGENT_TYPE.STATE_MACHINE] = AtomsCore.StringMetadata(self.stateMachine)
        aType.metadata()[AGENT_TYPE.SCALE_MULTIPLIER] = AtomsCore.DoubleMetadata(self.scaleMultiplier)

        lod_levels = [0]
        lod_values = []

        for lod_key in ['B', 'C', 'D']:
            if lod_key in self.drawOptimization:
                lod_levels.append(self.drawOptimization[lod_key][0])
                lod_values.append(self.drawOptimization[lod_key][1])

        lod_levels_meta = AtomsCore.IntArrayMetadata()
        lod_levels_meta.set(lod_levels)
        aType.metadata()[AGENT_TYPE.LOD_LEVELS] = lod_levels_meta

        lod_values_meta = AtomsCore.DoubleArrayMetadata()
        lod_values_meta.set(lod_values)
        aType.metadata()[AGENT_TYPE.LOD_DISTANCES] = lod_values_meta

        lod_mode_meta = AtomsCore.IntMetadata(0)
        if 'mode' in self.drawOptimization:
            lod_mode_meta.set(self.drawOptimization['mode'])
        aType.metadata()[AGENT_TYPE.LOD_MODE] = lod_mode_meta

        Atoms.AgentTypes.instance().addAgentType(self.eventName, aType)

    
def unload(self):
        Atoms.AgentTypes.instance().removeAgentType(self.eventName)