Files
Owen/README.md
Kaj Kowalski d513e80c07 refactor: rename states for clarity and consistency
- Updated state names in constants and related files from WAIT, REACT, TYPE, SLEEP to WAITING, REACTING, TYPING, SLEEPING.
- Adjusted all references to the renamed states across the codebase, including state handlers and transition logic.
- Ensured that logging messages reflect the new state names for better readability.
2025-05-24 04:16:02 +02:00

10 KiB

Owen Animation System

A comprehensive Three.js animation system for character state management with clean architecture principles, dependency injection, and factory patterns.

Gitea Issues Gitea Pull Requests Gitea Release

🎯 Overview

The Owen Animation System is a sophisticated character animation framework built for Three.js that manages complex state machines, emotional responses, and animation transitions. It's designed with clean architecture principles to be maintainable, extensible, and testable.

Key Features

  • 🤖 State Machine Implementation - Complete state management system with Wait, React, Type, and Sleep states
  • 😊 Emotional Response System - Analyzes user input to determine appropriate emotional animations
  • 🔄 Animation Transition Management - Smooth transitions between states with fade in/out support
  • 📝 Animation Naming Convention Parser - Automatically parses animation metadata from naming conventions
  • 🏗️ Clean Architecture - Uses dependency injection, factory patterns, and separation of concerns
  • Performance Optimized - Efficient animation caching and resource management
  • 🧩 Extensible Design - Easy to add new states, emotions, and animation types

🚀 Installation

Prerequisites

  • Node.js 16.0.0 or higher
  • Three.js compatible 3D model with animations (GLTF/GLB format recommended)

Install Dependencies

# Clone the repository
git clone https://gitea.kajkowalski.nl/kjanat/Owen.git
cd Owen

# Install dependencies
npm install

# Install dev dependencies
npm install --include dev

📖 Usage

Basic Usage

import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OwenSystemFactory } from "owen";

// Load your 3D model
const loader = new GLTFLoader();
const gltf = await loader.loadAsync("path/to/your-model.gltf");

// Create a Three.js scene
const scene = new THREE.Scene();
scene.add(gltf.scene);

// Create the Owen animation system
const owenSystem = await OwenSystemFactory.createOwenSystem(gltf, scene);

// Handle user messages
await owenSystem.handleUserMessage("Hello Owen!");

// Update in your render loop
function animate() {
  const deltaTime = clock.getDelta() * 1000; // Convert to milliseconds
  owenSystem.update(deltaTime);

  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

Note

Replace path/to/your-model.gltf with the actual path to your 3D character model. The system is designed to work with any GLTF model that follows the animation naming convention.

Advanced Usage

import { OwenSystemFactory, States, Emotions, StateHandler } from "owen";

// Create custom state handler
class CustomStateHandler extends StateHandler {
  async enter(fromState, emotion) {
    console.log(`Entering custom state from ${fromState}`);
    // Your custom logic here
  }

  async exit(toState, emotion) {
    console.log(`Exiting custom state to ${toState}`);
    // Your custom logic here
  }
}

// Register custom states
const customStates = new Map();
customStates.set("custom", CustomStateHandler);

// Create system with custom states
const owenSystem = await OwenSystemFactory.createCustomOwenSystem(gltfModel, scene, customStates);

// Manual state transitions
await owenSystem.transitionTo(States.REACTING, Emotions.HAPPY);

🎮 Animation Naming Convention

The system expects animations to follow this naming convention:

[state]_[action]_[type]
[state]_[action]2[toState]_[emotion]_T

Examples

  • wait_idle_L - Wait state idle loop
  • wait_quirk1_Q - Wait state quirk animation
  • react_angry2type_an_T - Transition from react to type with angry emotion
  • type_happy_L - Type state with happy emotion loop
  • sleep_wakeup_T - Sleep wake up transition

Animation Types

  • L - Loop animation
  • Q - Quirk animation
  • T - Transition animation
  • NL - Nested loop
  • NQ - Nested quirk

Emotions

  • an - Angry
  • sh - Shocked
  • ha - Happy
  • sa - Sad

🏗️ Architecture

Dependency Injection

  • OwenAnimationContext receives dependencies through constructor injection
  • State handlers are injected with required context
  • Animation loaders are injected into factories

Factory Patterns

  • AnimationClipFactory - Creates animation clips with metadata parsing
  • StateFactory - Creates state handlers dynamically
  • OwenSystemFactory - Main factory that assembles the complete system

State Machine

  • Each state has its own handler class with entry/exit logic
  • States manage their own transitions and behaviors
  • Emotional transitions are handled with proper animation sequencing

📁 Project Structure

Owen/
├── src/
│   ├── constants.js              # Animation types, states, emotions
│   ├── index.js                  # Main entry point
│   ├── animation/
│   │   └── AnimationClip.js      # Core animation classes
│   ├── core/
│   │   └── OwenAnimationContext.js # Main system controller
│   ├── factories/
│   │   └── OwenSystemFactory.js  # System factory
│   ├── loaders/
│   │   └── AnimationLoader.js    # Animation loading interfaces
│   └── states/
│       ├── StateHandler.js       # Base state handler
│       ├── StateFactory.js       # State factory
│       ├── WaitStateHandler.js   # Wait state implementation
│       ├── ReactStateHandler.js  # React state implementation
│       ├── TypeStateHandler.js   # Type state implementation
│       └── SleepStateHandler.js  # Sleep state implementation
├── examples/
│   ├── index.html        # Demo HTML page
│   └── basic-demo.js     # Basic usage example
├── package.json
├── vite.config.js
├── jsdoc.config.json
└── README.md

🛠️ Development

Running the Development Server

# Start the development server
npm run dev

This will start a Vite development server and open the basic demo at http://localhost:3000.

Building for Production

# Build the project
npm run build

Linting

# Run ESLint
npm run lint

# Fix linting issues automatically
npm run lint:fix

Generating Documentation

# Generate JSDoc documentation
npm run docs

Documentation will be generated in the docs/ directory.

Project Scripts

  • npm run dev - Start development server
  • npm run build - Build for production
  • npm run preview - Preview production build
  • npm run lint - Run StandardJS linting
  • npm run lint:fix - Fix StandardJS issues
  • npm run docs - Generate JSDoc documentation
  • npm run format - Format code with Prettier

🎮 Demo Controls

The basic demo includes these keyboard controls:

  • 1 - Transition to Wait state
  • 2 - Transition to React state
  • 3 - Transition to Type state
  • 4 - Transition to Sleep state
  • Space - Send random test message
  • Click - Register user activity

🔧 Configuration

Customizing Emotions

You can extend the emotion system by modifying the message analysis:

import { ReactStateHandler } from "owen";

class CustomReactHandler extends ReactStateHandler {
  analyzeMessageEmotion(message) {
    // Your custom emotion analysis logic
    if (message.includes("excited")) {
      return Emotions.HAPPY;
    }
    return super.analyzeMessageEmotion(message);
  }
}

Adjusting Timing

Configure timing values in your application:

import { Config } from "owen";

// Modify default values
Config.QUIRK_INTERVAL = 8000; // 8 seconds between quirks
Config.INACTIVITY_TIMEOUT = 120000; // 2 minutes until sleep

🐛 Troubleshooting

Common Issues

  1. "Animation not found" errors
  • Ensure your 3D model contains animations with the correct naming convention
  • Check that animations are properly exported in your GLTF file
  1. State transitions not working
  • Verify that transition animations exist in your model
  • Check console for error messages about missing clips
  1. Performance issues
  • Ensure you're calling owenSystem.update() in your render loop
  • Check that unused animations are properly disposed

Debug Mode

Enable debug logging by opening browser console. The system logs state transitions and important events.

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Commit your changes: git commit -am 'Add new feature'
  4. Push to the branch: git push origin feature/new-feature
  5. Submit a pull request

Code Style

  • Follow the existing ESLint configuration
  • Add JSDoc comments for all public methods
  • Write unit tests for new features
  • Maintain the existing architecture patterns

📄 License

This project is dual-licensed under your choice of:

  • Open Source/Non-Commercial Use: AGPL-3.0 - see the LICENSE.AGPL file for details.
  • Commercial/Enterprise Use: Commercial License - see the LICENSE.COMMERCIAL file for details. Requires a paid commercial license. Please contact us at [email] for pricing and terms.

Quick Guide

  • Personal/educational use → Use under AGPL-3.0
  • Open source projects → Use under AGPL-3.0
  • Commercial/proprietary use → Purchase commercial license
  • SaaS without source disclosure → Purchase commercial license

🙏 Acknowledgments

  • Built with Three.js
  • Inspired by modern character animation systems
  • Uses clean architecture principles from Robert C. Martin