Three.js 3D Model System Documentation
Overview
The Three.js 3D model system provides a flexible architecture for storing, managing, and customizing 3D models for boats, rods, reels, and equipment. The system supports dynamic scaling, user customizations, and model variants.
Architecture
Core Entities
ThreeJsModel
The base 3D model entity that stores:
- Model Data: URL to GLTF/GLB file, embedded JSON, or Base64 data
- Reference Dimensions: Length, width, height, diameter at scale 1.0
- Anchor Point: Where the model's origin (0,0,0) is located
- Default Transformations: Rotation and scale defaults
- Metadata: Author, license, version, preview images, complexity metrics
ModelVariant
Pre-defined variants of a base model (e.g., different sizes):
- Links to base
ThreeJsModel - Variant-specific dimensions
- Calculated scale factors relative to base model
- Optional variant-specific model data
UserModelCustomization
User-specific customizations:
- User's actual dimensions (what they want the model to represent)
- Calculated scale factors (based on reference vs custom dimensions)
- Custom transformations (rotation, position offset)
- Material/color overrides
Linking Entities
RodModel
Links rods to their 3D models:
- Can link to specific
Rodor genericRodType - Default length for the rod type
- Configuration JSON for additional details
ReelModel
Links reels to their 3D models:
- Can link to specific
Reelor genericReelType - Default size for the reel type
EquipmentModel
Links boat equipment to 3D models:
- Links to
BoatEquipmentTypeor specificBoatEquipment - Default size for equipment type
BoatStyleModel (Updated)
Now links to ThreeJsModel:
- Legacy
ModelDataJsonfield retained for backward compatibility - Preferred: Use
ThreeJsModelrelationship
Scaling System
How Scaling Works
-
Reference Dimensions: Each
ThreeJsModelhas reference dimensions at scale 1.0- Example: Boat model with
ReferenceLengthFt = 20.0represents a 20ft boat at scale 1.0
- Example: Boat model with
-
User Customization: User provides their actual dimensions
- Example: User's boat is 22ft long
- Scale factor =
22.0 / 20.0 = 1.1
-
Applied Scaling: Frontend applies scale factors to Three.js model
// Pseudo-code
const scaleX = userCustomLength / modelReferenceLength;
const scaleY = userCustomWidth / modelReferenceWidth;
const scaleZ = userCustomHeight / modelReferenceHeight;
model.scale.set(scaleX, scaleY, scaleZ);
Example: Boat Scaling
Base Model:
ReferenceLengthFt = 20.0ReferenceWidthFt = 8.0ReferenceHeightFt = 3.0
User's Boat:
CustomLengthFt = 22.0CustomWidthFt = 8.5CustomHeightFt = 3.2
Calculated Scales:
ScaleX = 22.0 / 20.0 = 1.1ScaleY = 8.5 / 8.0 = 1.0625ScaleZ = 3.2 / 3.0 = 1.067
Example: Rod Scaling
Base Model:
ReferenceLengthFt = 7.0ReferenceDiameterInches = 0.5
User's Rod:
CustomLengthFt = 7.5CustomDiameterInches = 0.6
Calculated Scales:
ScaleX = 7.5 / 7.0 = 1.071(length)ScaleY = ScaleZ = 0.6 / 0.5 = 1.2(diameter)
Model Storage Options
Option 1: External URL (Preferred)
ModelUrl = "https://cdn.example.com/models/center-console.glb"
- Best for large models
- CDN caching
- No database bloat
Option 2: Embedded JSON
ModelJson = "{ \"vertices\": [...], \"faces\": [...] }"
- Good for small/medium models
- Self-contained
- Can be stored in database
Option 3: Base64 Encoded
ModelDataBase64 = "data:model/gltf-binary;base64,..."
- For very small models
- Self-contained
- Can be embedded in API responses
Anchor Points
Anchor points determine where the model's origin (0,0,0) is located:
- CenterBottom: Center of bottom face (default for boats)
- Center: Center of model (default for reels)
- BottomFront: Bottom front corner
- BottomBack: Bottom back corner
- TopCenter: Top center
- Custom: Custom anchor point (stored in metadata)
Usage Examples
Getting a Boat Model with User Customization
// Get boat's 3D model
var boat = context.Boats
.Include(b => b.BoatStyleModel)
.ThenInclude(bsm => bsm.ThreeJsModel)
.FirstOrDefault(b => b.Id == boatId);
var baseModel = boat.BoatStyleModel.ThreeJsModel;
// Get user customization (if exists)
var customization = context.UserModelCustomizations
.FirstOrDefault(umc => umc.UserId == userId && umc.BaseModelId == baseModel.Id);
// Calculate scales
var scaleX = customization?.CustomLengthFt / baseModel.ReferenceLengthFt ?? 1.0f;
var scaleY = customization?.CustomWidthFt / baseModel.ReferenceWidthFt ?? 1.0f;
var scaleZ = customization?.CustomHeightFt / baseModel.ReferenceHeightFt ?? 1.0f;
Getting Rod/Reel Models for Equipment Placement
// Get rod model
var rodModel = context.RodModels
.Include(rm => rm.ThreeJsModel)
.FirstOrDefault(rm => rm.RodId == rodId ||
(rm.RodType == rodType && rm.IsDefault));
// Get reel model
var reelModel = context.ReelModels
.Include(rm => rm.ThreeJsModel)
.FirstOrDefault(rm => rm.ReelId == reelId ||
(rm.ReelType == reelType && rm.IsDefault));
Seeding Base Models
The ThreeJsModelSeeder seeds generic base models for:
- Boats: Center Console, Bass Boat, Jon Boat, Kayak, Pontoon
- Rods: Various lengths and types (Spinning, Baitcasting, Trolling, Fly)
- Reels: Various sizes (1000, 2500, 3000, 4000, etc.)
- Equipment: Outriggers, Downriggers, Cannon Balls, Rod Holders, Batteries, etc.
These base models can be customized by users to match their actual equipment dimensions.
Future Enhancements
- Model Marketplace: Allow users to upload/share custom models
- Model Versioning: Track model updates and migrations
- LOD (Level of Detail): Multiple detail levels for performance
- Animation Support: Store animation data for moving parts
- Material Library: Shared material definitions
- Model Validation: Validate GLTF/GLB files on upload