Files
Owen/README.md
Kaj Kowalski ad8dbb95dd
Some checks failed
CI/CD Pipeline / Test & Lint (16.x) (push) Has been cancelled
CI/CD Pipeline / Test & Lint (18.x) (push) Has been cancelled
CI/CD Pipeline / Test & Lint (20.x) (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Release (push) Has been cancelled
Release / Validate Version (push) Has been cancelled
Release / Build and Test (push) Has been cancelled
Release / Create Release (push) Has been cancelled
Release / Publish to NPM (push) Has been cancelled
Release / Deploy Demo (push) Has been cancelled
Animation Processing Pipeline / Validate Animation Names (push) Has been cancelled
Animation Processing Pipeline / Process Blender Animation Assets (push) Has been cancelled
Animation Processing Pipeline / Update Animation Documentation (push) Has been cancelled
Animation Processing Pipeline / Deploy Animation Demo (push) Has been cancelled
Implement multi-scheme animation name mapper for Owen Animation System
- Added AnimationNameMapper class to handle conversion between different animation naming schemes (legacy, artist, hierarchical, semantic).
- Included methods for initialization, pattern matching, conversion, and validation of animation names.
- Developed comprehensive unit tests for the animation name converter and demo pages using Playwright.
- Created a Vite configuration for the demo application, including asset handling and optimization settings.
- Enhanced the demo with features for batch conversion, performance metrics, and responsive design.
2025-05-24 05:40:03 +02:00

392 lines
13 KiB
Markdown

# Owen Animation System
A comprehensive Three.js animation system for character state management with clean architecture principles, dependency injection, and factory patterns.
[![Gitea Issues](https://img.shields.io/gitea/issues/all/kjanat/Owen?gitea_url=https%3A%2F%2Fgitea.kajkowalski.nl%2F)](https://gitea.kajkowalski.nl/kjanat/Owen/issues)
[![Gitea Pull Requests](https://img.shields.io/gitea/pull-requests/all/kjanat/Owen?gitea_url=https%3A%2F%2Fgitea.kajkowalski.nl%2F)](https://gitea.kajkowalski.nl/kjanat/Owen/pulls)
[![Gitea Release](https://img.shields.io/gitea/v/release/kjanat/Owen?gitea_url=https%3A%2F%2Fgitea.kajkowalski.nl&include_prereleases&sort=semver)](https://gitea.kajkowalski.nl/kjanat/Owen/tags)
## 🎯 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
- **📝 Multi-Scheme Animation Naming** - Supports legacy, artist-friendly, hierarchical, and semantic naming schemes
- **🎨 Artist-Friendly Workflow** - Blender-compatible naming for 3D artists (`Owen_WaitIdle`, `Owen_ReactHappy`)
- **👨‍💻 Developer Experience** - Type-safe constants and semantic naming (`OwenWaitIdleLoop`, `OwenReactAngryTransition`)
- **🏗️ 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
- **🔄 Backward Compatibility** - Legacy naming scheme continues to work alongside new schemes
## 🚀 Installation
### Prerequisites
- Node.js 16.0.0 or higher
- Three.js compatible 3D model with animations (GLTF/GLB format recommended)
### Install Dependencies
```bash
# 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
```javascript
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
```javascript
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);
```
## 🎨 Multi-Scheme Animation Naming
Owen supports **four different animation naming schemes** to accommodate different workflows and preferences:
### Naming Schemes
| Scheme | Format | Example | Use Case |
| ---------------- | ---------------------------- | --------------------------- | ------------------------------- |
| **Legacy** | `{state}_{emotion}_{type}` | `wait_idle_L` | Backward compatibility |
| **Artist** | `Owen_{Action}` | `Owen_WaitIdle` | Blender-friendly for 3D artists |
| **Hierarchical** | `owen.{category}.{state}...` | `owen.state.wait.idle.loop` | Structured projects |
| **Semantic** | `Owen{StateAction}{Type}` | `OwenWaitIdleLoop` | Developer-friendly |
### Usage Examples
```javascript
// All of these refer to the same animation:
const clip1 = owenSystem.getClip('wait_idle_L'); // Legacy
const clip2 = owenSystem.getClip('Owen_WaitIdle'); // Artist
const clip3 = owenSystem.getClip('owen.state.wait.idle.loop'); // Hierarchical
const clip4 = owenSystem.getClip('OwenWaitIdleLoop'); // Semantic
// Convert between schemes
import { convertAnimationName, SemanticAnimations } from 'owen';
const artistName = convertAnimationName('wait_idle_L', 'artist');
// Returns: 'Owen_WaitIdle'
// Use type-safe constants
const animation = SemanticAnimations.WAIT_IDLE_LOOP; // 'OwenWaitIdleLoop'
```
### For 3D Artists (Blender Workflow)
```javascript
// Use artist-friendly names in Blender:
// Owen_WaitIdle, Owen_ReactHappy, Owen_TypeFast, etc.
// System automatically handles conversion!
const clip = owenSystem.getClip('Owen_ReactAngry'); // Just works!
```
> [!TIP]
> See the [Multi-Scheme Guide](./MULTI_SCHEME_GUIDE.md) for complete documentation and examples.
## 🎮 Animation Naming Convention (Legacy)
The system maintains backward compatibility with the original naming convention:
The system expects animations to follow this naming convention:
```txt
[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
```sh
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
```bash
# 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
```bash
# Build the project
npm run build
```
### Linting
```bash
# Run ESLint
npm run lint
# Fix linting issues automatically
npm run lint:fix
```
### Generating Documentation
```bash
# 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:
```javascript
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:
```javascript
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
2. **State transitions not working**
- Verify that transition animations exist in your model
- Check console for error messages about missing clips
3. **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](LICENSE.AGPL) file for details.
- **Commercial/Enterprise Use**: Commercial License - see the [LICENSE.COMMERCIAL](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][Three.js]
- Inspired by modern character animation systems
- Uses clean architecture principles from Robert C. Martin
<!-- LINK DEFINITIONS -->
[Three.js]: https://threejs.org/ "Three.js - JavaScript 3D Library"