Implement Owen Animation System with core classes, loaders, and state handlers

- Added OwenSystemFactory for creating the animation system.
- Introduced OwenAnimationContext to manage animations and states.
- Created AnimationLoader and GLTFAnimationLoader for loading animations.
- Developed state handlers: WaitStateHandler, ReactStateHandler, TypeStateHandler, SleepStateHandler.
- Implemented StateFactory for managing state handlers.
- Defined constants for clip types, states, and emotions.
- Added type definitions for TypeScript support.
- Configured Vite for building and serving the project.
- Added licenses (dual) to project.
This commit is contained in:
2025-05-23 21:36:52 +02:00
parent 9e5f576b68
commit 658e1e64b2
29 changed files with 6902 additions and 907 deletions

352
README.md
View File

@ -1,53 +1,337 @@
# Owen
# Owen Animation System
> Looking at this animation brief for Owen, I'll create a Three.js animation system that handles the state machine, animation clips, and transitions described in the document. This will use clean architecture principles with dependency injection and factory patterns.
>
> I've created a comprehensive Three.js animation system for Owen that implements the state machine and animation handling described in your brief. Here are the key architectural features:
A comprehensive Three.js animation system for character state management with clean architecture principles, dependency injection, and factory patterns.
## **Clean Architecture Principles:**
## 🎯 Overview
### **Dependency Injection:**
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.
- `OwenAnimationContext` receives its dependencies (mixer, factory, etc.) through constructor injection
- State handlers are injected with the context they need
- Animation loaders are injected into factories
## ✨ Key Features
### **Factory Patterns:**
- **🤖 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
- `AnimationClipFactory` - Creates animation clips with proper metadata parsing
- `StateFactory` - Creates state handlers dynamically
- `OwenSystemFactory` - Main factory that assembles the entire system
## 🚀 Installation
### **State Machine Implementation:**
### Prerequisites
- Each state (`Wait`, `React`, `Type`, `Sleep`) has its own handler class
- States manage their own entry/exit logic and transitions
- Emotional transitions are handled with proper animation sequencing
- Node.js 16.0.0 or higher
- Three.js compatible 3D model with animations (GLTF/GLB format recommended)
## **Key Features:**
### Install Dependencies
1. **Animation Naming Convention Parser** - Automatically parses the naming convention from your brief (e.g., `wait_idle_L`, `react_angry2type_an_T`)
```bash
# Clone the repository
git clone https://gitea.kajkowalski.nl/kjanat/Owen.git
cd Owen
2. **Emotional State Management** - Handles emotional transitions like angry typing or shocked reactions
# Install dependencies
npm install
3. **Nested Animation Support** - Supports the nested sequences described in your brief
# Install dev dependencies
npm install --include dev
```
4. **Activity Monitoring** - Automatically transitions to sleep after inactivity
## 📖 Usage
5. **Message Analysis** - Analyzes user messages to determine appropriate emotional responses
### Basic Usage
6. **Clean Separation of Concerns:**
- Animation loading is separate from clip management
- State logic is isolated in individual handlers
- The main context orchestrates everything without tight coupling
```javascript
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OwenSystemFactory } from "owen";
## **Usage:**
// Load your 3D model
const loader = new GLTFLoader();
const gltf = await loader.loadAsync("path/to/your-model.gltf");
The system is designed to be easily extensible. You can:
// Create a Three.js scene
const scene = new THREE.Scene();
scene.add(gltf.scene);
- Add new states by creating new handler classes
- Modify emotional analysis logic
- Swap out animation loaders for different formats
- Add new animation types by extending the factory
// Create the Owen animation system
const owenSystem = await OwenSystemFactory.createOwenSystem(gltf, scene);
The code follows the workflows described in your brief, handling the transitions between Wait → React → Type → Wait states, with proper emotional branching and nested animation support.
// 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.REACT, Emotions.HAPPY);
```
## 🎮 Animation 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
├── .eslintrc.json
├── 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 ESLint
- `npm run lint:fix` - Fix ESLint issues
- `npm run docs` - Generate JSDoc documentation
## 🎮 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"