namespace Sandbox; public partial class ModelRenderer { bool _createAttachments = false; internal readonly Dictionary attachmentToGameObject = new(); /// /// Get the GameObject of a specific attachment. /// public GameObject GetAttachmentObject( string name ) { if ( Model is null ) return null; var attachment = Model.Attachments.Get( name ); return GetAttachmentObject( attachment ); } /// /// Get the GameObject of a specific attachment. /// public GameObject GetAttachmentObject( ModelAttachments.Attachment attachment ) { if ( attachment is null ) return null; return attachmentToGameObject.GetValueOrDefault( attachment ); } public virtual GameObject GetBoneObject( BoneCollection.Bone bone ) { return default; } void BuildAttachmentHierarchy() { ClearAttachmentHierarchy(); if ( Model is null ) return; if ( CreateAttachments ) { foreach ( var a in Model.Attachments.All ) { attachmentToGameObject[a] = CreateAttachment( a ); } } } void ClearAttachmentHierarchy() { if ( attachmentToGameObject.Count == 0 ) return; foreach ( var attachment in attachmentToGameObject ) { if ( !attachment.Value.IsValid() ) continue; attachment.Value.Flags &= ~GameObjectFlags.Attachment; } attachmentToGameObject.Clear(); } GameObject CreateAttachment( ModelAttachments.Attachment a ) { Assert.NotNull( a ); var parent = GameObject; var go = parent.Children.Where( x => a.IsNamed( x.Name ) && !x.Flags.Contains( GameObjectFlags.Bone ) ).FirstOrDefault(); if ( !go.IsValid() ) { go = Scene.CreateObject( true ); } go.Parent = parent; go.Name = a.Name; go.Flags |= GameObjectFlags.Attachment; go.LocalTransform = a.WorldTransform; return go; } }