@@ -281,6 +281,8 @@ export class EffectsManager {
281281
282282 /**
283283 * Add an object to the selected set (sticky selection).
284+ * The outline is added as a child of the object so it automatically
285+ * inherits all transformations (scale, rotation, position).
284286 * @param object The mesh object to be selected.
285287 */
286288 public selectObject ( object : Mesh ) {
@@ -291,7 +293,8 @@ export class EffectsManager {
291293 // Create outline helper for this object
292294 const outlineHelper = this . createOutlineHelper ( object ) ;
293295 this . selectedOutlines . set ( object , outlineHelper ) ;
294- this . scene . add ( outlineHelper ) ;
296+ // Add as child of the object so outline inherits all transformations
297+ object . add ( outlineHelper ) ;
295298 }
296299
297300 /**
@@ -301,7 +304,8 @@ export class EffectsManager {
301304 public deselectObject ( object : Mesh ) {
302305 const outlineHelper = this . selectedOutlines . get ( object ) ;
303306 if ( outlineHelper ) {
304- this . scene . remove ( outlineHelper ) ;
307+ // Remove from parent (the selected object) rather than scene
308+ outlineHelper . removeFromParent ( ) ;
305309 outlineHelper . geometry . dispose ( ) ;
306310 ( outlineHelper . material as ShaderMaterial ) . dispose ( ) ;
307311 this . selectedOutlines . delete ( object ) ;
@@ -327,37 +331,49 @@ export class EffectsManager {
327331 * Clear all selected objects.
328332 */
329333 public clearAllSelections ( ) {
330- const count = this . selectedOutlines . size ;
331334 for ( const [ object , outlineHelper ] of this . selectedOutlines ) {
332- this . scene . remove ( outlineHelper ) ;
335+ // Remove from parent (the selected object) rather than scene
336+ outlineHelper . removeFromParent ( ) ;
333337 outlineHelper . geometry . dispose ( ) ;
334338 ( outlineHelper . material as ShaderMaterial ) . dispose ( ) ;
335339 }
336340 this . selectedOutlines . clear ( ) ;
337341 }
338342
343+ /** Reference to the object currently being hovered (for cleanup) */
344+ private hoverTarget : Mesh | null = null ;
345+
339346 /**
340347 * Set hover outline for an object (temporary, non-sticky).
348+ * The outline is added as a child of the object so it automatically
349+ * inherits all transformations (scale, rotation, position).
341350 * @param object The mesh object to hover outline, or null to clear.
342351 */
343352 public setHoverOutline ( object : Mesh | null ) {
344353 // Clear existing hover outline
345354 if ( this . hoverOutline ) {
346- this . scene . remove ( this . hoverOutline ) ;
355+ // Remove from parent (the hovered object) rather than scene
356+ this . hoverOutline . removeFromParent ( ) ;
347357 this . hoverOutline . geometry . dispose ( ) ;
348358 ( this . hoverOutline . material as ShaderMaterial ) . dispose ( ) ;
349359 this . hoverOutline = null ;
360+ this . hoverTarget = null ;
350361 }
351362
352363 // Create new hover outline if object provided and not already selected
353364 if ( object && ! this . selectedOutlines . has ( object ) ) {
354365 this . hoverOutline = this . createOutlineHelper ( object , true ) ; // Different style for hover
355- this . scene . add ( this . hoverOutline ) ;
366+ this . hoverTarget = object ;
367+ // Add as child of the object so outline inherits all transformations
368+ object . add ( this . hoverOutline ) ;
356369 }
357370 }
358371
359372 /**
360373 * Create an outline helper for an object.
374+ * The outline uses identity transforms because it will be added as a child
375+ * of the target object, inheriting all transformations automatically.
376+ * This ensures outlines stay synchronized when objects are scaled/moved.
361377 * @param object The mesh object to create outline for.
362378 * @param isHover Whether this is a hover outline (affects styling).
363379 * @returns The created outline helper.
@@ -391,10 +407,12 @@ export class EffectsManager {
391407
392408 const outlineHelper = new LineSegments ( edges , lineMaterial ) ;
393409
394- // Copy the object's transformation exactly
395- outlineHelper . position . copy ( object . position ) ;
396- outlineHelper . rotation . copy ( object . rotation ) ;
397- outlineHelper . scale . copy ( object . scale ) ;
410+ // Use identity transform - the outline will be added as a child of the
411+ // target object and will automatically inherit all transformations.
412+ // This fixes the bug where outlines became desynced after scaling/moving objects.
413+ outlineHelper . position . set ( 0 , 0 , 0 ) ;
414+ outlineHelper . rotation . set ( 0 , 0 , 0 ) ;
415+ outlineHelper . scale . set ( 1 , 1 , 1 ) ;
398416
399417 return outlineHelper ;
400418 }
0 commit comments