VR-Engage  2.2
Loading...
Searching...
No Matches
Human Art Part Actuator Example

Overview

Purpose: This example demonstrates how to control articulated parts on DI-Guy human characters in VR-Forces simulations. It shows the pattern for implementing an actuator component that animates human joints, specifically the left shoulder joint with sinusoidal motion.

Observable Behavior: When running this example, you will see:

  • Human character's left shoulder joint animates automatically
  • Shoulder rotates through elevation angles (0° to 90°)
  • Smooth sinusoidal motion over 4-second intervals
  • Animation pauses when simulation is paused
  • Motion applies to DI-Guy characters with articulated part definitions

Prerequisites:

  • Understanding of VR-Forces simulation architecture
  • Familiarity with actuator component patterns
  • Knowledge of articulated parts and DIS representation
  • Basic understanding of DI-Guy human character system

Related Examples:

  • VR-Forces articulated parts documentation
  • DI-Guy character integration guides

Key Concepts Demonstrated

This example demonstrates:

  1. Actuator Component Pattern - Implementing DtActuatorComponent for entity behavior
    • Inherits from DtActuatorComponent base class
    • Per-frame tick processing for continuous animation
    • Unique aspect: Direct manipulation of human joint angles
  2. Articulated Part Control - Accessing and modifying DIS articulated parts
    • Uses DtPlatformLocalObjectFacade to access platform-specific data
    • Retrieves articulated part repositories by DIS art part type
    • Sets joint angles and angular rates each frame
  3. DI-Guy Integration - Working with DI-Guy character skeleton
    • Art part types defined in DtDiGuyArtPartLinkMapper.h
    • Maps DIS articulated parts to DI-Guy skeleton joints
    • Requires entity definition to specify available articulated parts
  4. Time-Based Animation - Creating smooth periodic motion
    • Sinusoidal motion computed from simulation time
    • Angular rate calculated for smooth visual interpolation
    • Handles simulation pause/resume correctly

Code Walkthrough

Actuator Component Structure

The actuator inherits from DtActuatorComponent and maintains animation state:

// File: examples/humanArtPartActuator/exampleHumanArtPartActuator.h
class DtExampleHumanArtPartActuator : public DtActuatorComponent
{
public:
DtExampleHumanArtPartActuator(const DtString& name, DtLocalObject* owner,
DtSimulationServices* simManager,
DtComponentDescriptor* desc = 0,
DtReaderWriterRegistry* parentRegistry = 0);
virtual bool init() override;
virtual void tick() override;
virtual const char* type() const override;
static DtSimComponent* creator(const DtString& name, DtLocalObject* owner,
DtSimulationServices* simManager,
DtComponentDescriptor* desc = 0,
DtReaderWriterRegistry* parentRegistry = 0);
protected:
DtPlatformLocalObjectFacade myPlatformLocalObjectFacade; // Access to platform data
makVrf::DtArticulatedPartStateRepository* myLeftShoulder; // Joint control interface
double myAnimationInterval; // Time for one complete animation cycle
double myTimeInInterval; // Current position in animation cycle
};

Key Points:

  • DtPlatformLocalObjectFacade provides platform-specific data access
  • DtArticulatedPartStateRepository controls individual joint state
  • Animation timing maintained independently of frame rate
  • Static creator() enables factory instantiation

Accessing Articulated Parts

The tick method retrieves the shoulder joint on first access:

// File: examples/humanArtPartActuator/exampleHumanArtPartActuator.cxx
void DtExampleHumanArtPartActuator::tick()
{
if (!myLeftShoulder)
{
// Look up articulated part for left shoulder
myLeftShoulder = myPlatformLocalObjectFacade.nextFramePart(
static_cast<DtArtPartType>(makVrv::DiGuyDisArtPartShoulderLeft));
}
if (!myLeftShoulder)
{
return; // Part not available on this entity
}
// Animate the joint...
}

Why This Matters:

  • DiGuyDisArtPartShoulderLeft is a DIS articulated part type constant
  • Part lookup deferred until first tick (entity may not be fully initialized at init())
  • Null check handles entities without this articulated part defined
  • nextFramePart() retrieves the repository for modifying joint state

Sinusoidal Joint Animation

The joint angle and rate are computed using trigonometry:

// File: examples/humanArtPartActuator/exampleHumanArtPartActuator.cxx
void DtExampleHumanArtPartActuator::tick()
{
// Update animation time
myTimeInInterval += dT();
if (myTimeInInterval > myAnimationInterval)
{
myTimeInInterval = 0; // Reset for next cycle
}
// Compute angle using sine wave (0 to maxAngle to 0)
double maxAngle = M_PI_2; // 90 degrees
double theta = myTimeInInterval / myAnimationInterval * 2 * M_PI;
double newPartAngle = maxAngle * sin(theta);
double newPartAngleRate = (4 * maxAngle / myAnimationInterval) * cos(theta);
// Update the joint
myLeftShoulder->setElevation(newPartAngle);
myLeftShoulder->setElevationRate(newPartAngleRate);
myLeftShoulder->setAzimuth(0);
myLeftShoulder->setAzimuthRate(0);
myLeftShoulder->setRotation(0);
myLeftShoulder->setRotationRate(0);
}

Why This Matters:

  • dT() provides frame delta time in seconds
  • Theta ranges from 0 to 2π over the animation interval
  • Sine wave produces smooth up-down motion
  • Angular rate (derivative of sine) enables smooth interpolation on remote clients
  • All three joint degrees of freedom (azimuth, elevation, rotation) must be set

Handling Simulation Pause

The actuator detects when simulation is paused and stops motion:

// File: examples/humanArtPartActuator/exampleHumanArtPartActuator.cxx
void DtExampleHumanArtPartActuator::tick()
{
if (DtIsZero<double>(dT()))
{
// Simulation paused - stop joint motion
if (myLeftShoulder)
{
myLeftShoulder->setAzimuthRate(0);
myLeftShoulder->setElevationRate(0);
myLeftShoulder->setRotationRate(0);
}
return;
}
// Normal animation continues...
}

Key Points:

  • Zero delta time indicates simulation pause
  • Angular rates set to zero to stop motion
  • Joint angles retained (freeze in current position)
  • Animation timer does not advance during pause

Component Factory Registration

The plugin registers the actuator with VR-Forces component factory:

// File: examples/humanArtPartActuator/plugin.cxx
DT_VRF_DLL_PLUGIN bool DtInitializeVrfPlugin(DtCgf* cgf)
{
DtFactoryManager* factoryManager = cgf->factoryManager();
// Register actuator component
factoryManager->componentFactory()->addCreatorFcn(
DtExampleHumanArtPartActuatorType,
DtExampleHumanArtPartActuator::creator);
return true;
}

Why This Matters:

  • Type string DtExampleHumanArtPartActuatorType identifies the component
  • Factory enables instantiation from entity configuration files
  • Registration during plugin initialization phase

Deployment and Testing

Installation

Build the example (see Environment Setup & Build Guide):

cd examples\build
cmake --build . --config RelWithDebInfo --target humanArtPartActuator

Install the plugin to the VR-Engage installation:

cmake --install . --config RelWithDebInfo

This copies the plugin to <VR-Engage-Install-Dir>\plugins64\vrForces\release\exampleHumanArtPartActuator.dll

Verify installation:

dir "<VR-Engage-Install-Dir>\plugins64\vrForces\release\exampleHumanArtPartActuator.dll"

Configuration

Backend plugin loads automatically: The VR-Engage toolkit installer automatically installs the backend plugin configuration file appData/plugins/exampleHumanArtPartActuator.xml which tells VR-Forces to load the DLL. No manual plugin configuration is required.

Add actuator to entity definition (.entity file):

<entity name="AnimatedHuman">
<entityType domain="1" kind="3" country="225" category="11" subcategory="1"/>
<!-- Define articulated parts available on this entity -->
<articulatedParts>
<part id="1" type="ShoulderLeft" typeClass="4"/>
<!-- Add other joints as needed -->
</articulatedParts>
<!-- Add the actuator component -->
<components>
<component type="vre-example-human-art-part-actuator"/>
</components>
</entity>

Note: The articulated part must be defined in the entity file for the actuator to control it. See TestHuman.entity in the VR-Forces installation for a complete example.

Testing Procedure

  1. Launch VR-Forces with the plugin loaded
  2. Create entity using the configured entity type with the actuator
  3. Start simulation
  4. Expected Behavior:
    • Human character appears in scene
    • Left shoulder joint begins animating immediately
    • Shoulder moves smoothly between 0° and 90° elevation
    • Animation completes one cycle every 4 seconds
    • Motion stops when simulation paused
  5. Network Verification (if using DIS/HLA):
    • Articulated parts PDUs transmitted for the entity
    • Remote visualization shows synchronized joint motion
    • Angular rates enable smooth interpolation

Verification:

  • Check VR-Forces log for plugin initialization:
    [Plugin] Loaded exampleHumanArtPartActuator
    [Component Factory] Registered vre-example-human-art-part-actuator
  • Enable articulated parts visualization in VR-Vantage
  • Use network capture tools to verify articulated parts PDUs

Troubleshooting

Plugin not loading:

  • Verify DLL is in <VR-Engage-Install-Dir>\plugins64\vrForces\release\
  • Check plugin package configuration includes correct path
  • Review VR-Forces log for load errors

Joint not animating:

  • Symptom: Entity appears but shoulder doesn't move
  • Cause: Articulated part not defined in entity file
  • Solution: Add <part id="1" type="ShoulderLeft" typeClass="4"/> to entity definition

Jerky motion:

  • Symptom: Joint animation appears stuttering or discontinuous
  • Cause: Network latency or missing angular rate
  • Solution: Verify angular rates are set correctly, check network conditions

Wrong joint moving:

  • Symptom: Different joint animates instead of left shoulder
  • Cause: Articulated part ID mismatch between code and entity definition
  • Solution: Ensure DIS art part type matches entity file part definition


Technical Reference

File Structure

examples/humanArtPartActuator/
├── CMakeLists.txt # Build configuration
├── README.md # This documentation
├── plugin.cxx # VR-Forces plugin entry point
├── exampleHumanArtPartActuator.h # Actuator class declaration
└── exampleHumanArtPartActuator.cxx # Actuator implementation

Key Classes

Class Base Class Purpose Header
DtExampleHumanArtPartActuator DtActuatorComponent Animates human shoulder joint exampleHumanArtPartActuator.h
DtPlatformLocalObjectFacade N/A Facade for accessing platform-specific data vrfobjcore/platformLocalObjectFacade.h
DtArticulatedPartStateRepository N/A Interface for controlling joint state VR-Forces core

API Methods Used

  • DtActuatorComponent::tick() - Per-frame update for actuator behavior
  • DtActuatorComponent::dT() - Frame delta time in seconds
  • DtPlatformLocalObjectFacade::nextFramePart() - Retrieve articulated part by type
  • DtArticulatedPartStateRepository::setElevation() - Set joint elevation angle (radians)
  • DtArticulatedPartStateRepository::setElevationRate() - Set joint angular rate (radians/second)
  • DtArticulatedPartStateRepository::setAzimuth() - Set joint azimuth angle
  • DtArticulatedPartStateRepository::setRotation() - Set joint rotation angle
  • DtFactoryManager::componentFactory() - Access component factory for registration

DI-Guy Articulated Part Types

Common DIS art part types for DI-Guy characters (from DtDiGuyArtPartLinkMapper.h):

Joint DIS Art Part Type Constant
Left Shoulder DiGuyDisArtPartShoulderLeft
Right Shoulder DiGuyDisArtPartShoulderRight
Left Elbow DiGuyDisArtPartElbowLeft
Right Elbow DiGuyDisArtPartElbowRight
Left Hip DiGuyDisArtPartHipLeft
Right Hip DiGuyDisArtPartHipRight
Left Knee DiGuyDisArtPartKneeLeft
Right Knee DiGuyDisArtPartKneeRight
Neck DiGuyDisArtPartNeck
Head DiGuyDisArtPartHead

Joint Degrees of Freedom

Each articulated part has three rotational degrees of freedom:

Axis Description Zero Position
Azimuth Rotation about vertical axis Forward-facing
Elevation Rotation about lateral axis Arm at side (shoulder), straight (elbow)
Rotation Rotation about longitudinal axis Neutral/natural position

All angles specified in radians. Positive angles follow right-hand rule.

Build Targets

  • Plugin: exampleHumanArtPartActuator.dll (Windows)
  • Install Location: plugins64/vrForces/release/

Related Documentation:

  • VR-Engage Examples Overview
  • VR-Forces Articulated Parts System Documentation
  • DI-Guy Character Integration Guide
  • VR-Forces Actuator Component Development
  • DIS Articulated Parts PDU Specification