- 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.
9.6 KiB
Owen Animation System
A comprehensive Three.js animation system for character state management with clean architecture principles, dependency injection, and factory patterns.
🎯 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, andSleepstates - 😊 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.gltfwith 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.REACT, 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 loopwait_quirk1_Q- Wait state quirk animationreact_angry2type_an_T- Transition from react to type with angry emotiontype_happy_L- Type state with happy emotion loopsleep_wakeup_T- Sleep wake up transition
Animation Types
L- Loop animationQ- Quirk animationT- Transition animationNL- Nested loopNQ- Nested quirk
Emotions
an- Angrysh- Shockedha- Happysa- Sad
🏗️ Architecture
Dependency Injection
OwenAnimationContextreceives 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 parsingStateFactory- Creates state handlers dynamicallyOwenSystemFactory- 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
├── .eslintrc.json
├── 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 servernpm run build- Build for productionnpm run preview- Preview production buildnpm run lint- Run ESLintnpm run lint:fix- Fix ESLint issuesnpm 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:
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
- "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
- State transitions not working
- Verify that transition animations exist in your model
- Check console for error messages about missing clips
- 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
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Commit your changes:
git commit -am 'Add new feature' - Push to the branch:
git push origin feature/new-feature - 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