zeroed-some/dougk / 2b9ade3

Browse files

continue to improve boot house

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
2b9ade3373fa1f7cd301a0a594ae808b9655a721
Parents
6184c04
Tree
1a8680b

1 changed file

StatusFile+-
M src/renderers/three/buildings.js 191 166
src/renderers/three/buildings.jsmodified
@@ -578,201 +578,226 @@ export function createBootHouse(gradientMap) {
578
   // Sprite body colors
578
   // Sprite body colors
579
   const spriteColors = [0xff6b9d, 0x9b59b6, 0x3498db, 0x2ecc71]
579
   const spriteColors = [0xff6b9d, 0x9b59b6, 0x3498db, 0x2ecc71]
580
 
580
 
581
-  // === BOOT STRUCTURE (Continuous realistic boot shape) ===
581
+  // === BOOT STRUCTURE (Extruded 2D profile for smooth continuous shape) ===
582
-
582
+
583
-  // The boot is built as overlapping shapes with the same material
583
+  // Create a boot profile as a 2D shape, then extrude it
584
-  // to create a seamless, continuous appearance
584
+  // This creates ONE continuous mesh that looks like a real boot
585
-
585
+
586
-  // --- SOLE (follows the boot footprint) ---
586
+  const bootShape = new THREE.Shape()
587
-  // Main sole - elongated with rounded ends
587
+
588
-  const soleLength = 1.1
588
+  // Boot profile (side view, starting from heel bottom, going clockwise)
589
-  const soleWidth = 0.5
589
+  // Scale: roughly 1 unit tall, 1.2 units long
590
-  const soleHeight = 0.1
590
+
591
-
591
+  // Start at heel bottom
592
-  // Sole base
592
+  bootShape.moveTo(0.45, 0)
593
-  const soleBaseGeom = new THREE.BoxGeometry(soleLength - 0.3, soleHeight, soleWidth - 0.1)
593
+
594
-  const soleBase = new THREE.Mesh(soleBaseGeom, soleMaterial)
594
+  // Sole - flat bottom with slight curve at toe
595
-  soleBase.position.set(0, soleHeight / 2, 0)
595
+  bootShape.lineTo(-0.35, 0)
596
-  group.add(soleBase)
596
+
597
-
597
+  // Toe curves up
598
-  // Sole toe cap (rounded front)
598
+  bootShape.quadraticCurveTo(-0.55, 0, -0.55, 0.15)
599
-  const soleToeGeom = new THREE.CylinderGeometry(soleWidth / 2 - 0.05, soleWidth / 2 - 0.05, soleHeight, 12)
599
+  bootShape.quadraticCurveTo(-0.55, 0.35, -0.4, 0.4)
600
-  soleToeGeom.rotateX(Math.PI / 2)
600
+
601
-  const soleToe = new THREE.Mesh(soleToeGeom, soleMaterial)
601
+  // Vamp/instep - curves up toward ankle
602
-  soleToe.position.set(-soleLength / 2 + 0.15, soleHeight / 2, 0)
602
+  bootShape.quadraticCurveTo(-0.15, 0.45, 0.05, 0.55)
603
-  group.add(soleToe)
603
+
604
-
604
+  // Front of ankle/shaft - rises up
605
-  // Sole heel cap (rounded back)
605
+  bootShape.quadraticCurveTo(0.15, 0.65, 0.15, 0.95)
606
-  const soleHeelGeom = new THREE.CylinderGeometry(soleWidth / 2 - 0.05, soleWidth / 2 - 0.05, soleHeight * 1.3, 12)
606
+
607
-  soleHeelGeom.rotateX(Math.PI / 2)
607
+  // Top opening - slight outward flare
608
-  const soleHeel = new THREE.Mesh(soleHeelGeom, soleMaterial)
608
+  bootShape.quadraticCurveTo(0.15, 1.05, 0.22, 1.08)
609
-  soleHeel.position.set(soleLength / 2 - 0.2, soleHeight * 0.65, 0)
609
+
610
-  group.add(soleHeel)
610
+  // Across the top opening
611
-
611
+  bootShape.lineTo(0.42, 1.08)
612
-  // --- FOOT PORTION (continuous with ankle) ---
612
+
613
-
613
+  // Back of shaft curves down
614
-  // Lower foot - the part that sits on the sole
614
+  bootShape.quadraticCurveTo(0.5, 1.05, 0.5, 0.95)
615
-  // Uses a squashed capsule shape tilted up at the toe
615
+  bootShape.quadraticCurveTo(0.5, 0.5, 0.48, 0.25)
616
-  const footBaseGeom = new THREE.CapsuleGeometry(0.22, 0.5, 8, 12)
616
+
617
-  footBaseGeom.rotateZ(Math.PI / 2) // Lay it horizontal
617
+  // Heel curves to bottom
618
-  footBaseGeom.scale(1, 0.75, 1) // Flatten slightly
618
+  bootShape.quadraticCurveTo(0.48, 0.08, 0.45, 0)
619
-  const footBase = new THREE.Mesh(footBaseGeom, leatherMaterial)
619
+
620
-  footBase.position.set(-0.1, 0.28, 0)
620
+  // Extrude settings - depth gives the boot width, bevel rounds edges
621
-  footBase.rotation.z = -0.15 // Tilt toe up slightly
621
+  const extrudeSettings = {
622
-  group.add(footBase)
622
+    steps: 1,
623
-
623
+    depth: 0.45,
624
-  // Toe box - rounded front that curves upward
624
+    bevelEnabled: true,
625
-  const toeBoxGeom = new THREE.SphereGeometry(0.28, 12, 10)
625
+    bevelThickness: 0.08,
626
-  toeBoxGeom.scale(0.9, 0.85, 1.0)
626
+    bevelSize: 0.06,
627
-  const toeBox = new THREE.Mesh(toeBoxGeom, leatherMaterial)
627
+    bevelOffset: 0,
628
-  toeBox.position.set(-0.48, 0.26, 0)
628
+    bevelSegments: 4
629
-  group.add(toeBox)
629
+  }
630
-
630
+
631
-  // --- ANKLE/SHAFT (rises from heel, connects to foot) ---
631
+  const bootGeometry = new THREE.ExtrudeGeometry(bootShape, extrudeSettings)
632
-
632
+
633
-  // Ankle transition - connects foot to shaft smoothly
633
+  // Center the boot (extrude goes in +Z, so offset by half depth)
634
-  const ankleTransitionGeom = new THREE.SphereGeometry(0.34, 12, 10)
634
+  bootGeometry.translate(0, 0, -0.225)
635
-  ankleTransitionGeom.scale(1.0, 0.8, 1.0)
635
+
636
-  const ankleTransition = new THREE.Mesh(ankleTransitionGeom, leatherMaterial)
636
+  const bootMesh = new THREE.Mesh(bootGeometry, leatherMaterial)
637
-  ankleTransition.position.set(0.25, 0.35, 0)
637
+  group.add(bootMesh)
638
-  group.add(ankleTransition)
638
+
639
-
639
+  // === SOLE (darker strip along bottom) ===
640
-  // Main shaft (ankle part) - tapers slightly upward
640
+  const soleShape = new THREE.Shape()
641
-  const shaftGeom = new THREE.CylinderGeometry(0.28, 0.34, 0.75, 14)
641
+  soleShape.moveTo(0.45, 0)
642
-  const shaft = new THREE.Mesh(shaftGeom, leatherMaterial)
642
+  soleShape.lineTo(-0.35, 0)
643
-  shaft.position.set(0.25, 0.72, 0)
643
+  soleShape.quadraticCurveTo(-0.55, 0, -0.55, 0.08)
644
-  group.add(shaft)
644
+  soleShape.lineTo(-0.5, 0.1)
645
-
645
+  soleShape.lineTo(0.45, 0.1)
646
-  // Shaft top rim
646
+  soleShape.quadraticCurveTo(0.48, 0.08, 0.48, 0.05)
647
-  const shaftTopGeom = new THREE.TorusGeometry(0.30, 0.04, 8, 20)
647
+  soleShape.lineTo(0.45, 0)
648
-  const shaftTop = new THREE.Mesh(shaftTopGeom, leatherMaterial)
648
+
649
-  shaftTop.position.set(0.25, 1.1, 0)
649
+  const soleExtrudeSettings = {
650
-  shaftTop.rotation.x = Math.PI / 2
650
+    steps: 1,
651
-  group.add(shaftTop)
651
+    depth: 0.48,
652
-
652
+    bevelEnabled: true,
653
-  // --- INSTEP/VAMP (connects toe to ankle on top) ---
653
+    bevelThickness: 0.03,
654
-
654
+    bevelSize: 0.02,
655
-  // This fills the gap between toe and shaft on top of the foot
655
+    bevelSegments: 2
656
-  const vampGeom = new THREE.CapsuleGeometry(0.18, 0.35, 6, 10)
656
+  }
657
-  vampGeom.rotateZ(Math.PI / 2)
657
+
658
-  vampGeom.scale(1, 0.7, 0.9)
658
+  const soleGeometry = new THREE.ExtrudeGeometry(soleShape, soleExtrudeSettings)
659
-  const vamp = new THREE.Mesh(vampGeom, leatherMaterial)
659
+  soleGeometry.translate(0, 0, -0.24)
660
-  vamp.position.set(-0.08, 0.38, 0)
660
+  const soleMesh = new THREE.Mesh(soleGeometry, soleMaterial)
661
-  vamp.rotation.z = -0.4 // Angle down toward toe
661
+  group.add(soleMesh)
662
-  group.add(vamp)
662
+
663
-
663
+  // === HEEL TAB (back loop) ===
664
-  // --- HEEL COUNTER (back of heel, reinforcement) ---
664
+  const heelTabGeom = new THREE.BoxGeometry(0.08, 0.12, 0.25)
665
-  const heelCounterGeom = new THREE.CylinderGeometry(0.26, 0.3, 0.25, 14, 1, false, -Math.PI * 0.6, Math.PI * 1.2)
665
+  const heelTab = new THREE.Mesh(heelTabGeom, darkLeatherMaterial)
666
-  const heelCounter = new THREE.Mesh(heelCounterGeom, darkLeatherMaterial)
666
+  heelTab.position.set(0.48, 1.0, 0)
667
-  heelCounter.position.set(0.35, 0.22, 0)
667
+  group.add(heelTab)
668
-  group.add(heelCounter)
668
+
669
-
669
+  // Heel tab loop
670
-  // --- TONGUE ---
670
+  const heelLoopGeom = new THREE.TorusGeometry(0.04, 0.015, 6, 12, Math.PI)
671
-  const tongueGeom = new THREE.CapsuleGeometry(0.08, 0.25, 4, 8)
671
+  const heelLoop = new THREE.Mesh(heelLoopGeom, darkLeatherMaterial)
672
-  const tongue = new THREE.Mesh(tongueGeom, laceMaterial)
672
+  heelLoop.position.set(0.52, 1.04, 0)
673
-  tongue.position.set(0.0, 0.55, 0.26)
673
+  heelLoop.rotation.z = -Math.PI / 2
674
-  tongue.rotation.x = 0.35
674
+  group.add(heelLoop)
675
-  tongue.rotation.z = -0.1
675
+
676
+  // === TONGUE ===
677
+  const tongueShape = new THREE.Shape()
678
+  tongueShape.moveTo(-0.06, 0)
679
+  tongueShape.lineTo(-0.07, 0.25)
680
+  tongueShape.quadraticCurveTo(-0.07, 0.35, 0, 0.38)
681
+  tongueShape.quadraticCurveTo(0.07, 0.35, 0.07, 0.25)
682
+  tongueShape.lineTo(0.06, 0)
683
+  tongueShape.lineTo(-0.06, 0)
684
+
685
+  const tongueExtrudeSettings = {
686
+    steps: 1,
687
+    depth: 0.04,
688
+    bevelEnabled: true,
689
+    bevelThickness: 0.015,
690
+    bevelSize: 0.01,
691
+    bevelSegments: 2
692
+  }
693
+
694
+  const tongueGeometry = new THREE.ExtrudeGeometry(tongueShape, tongueExtrudeSettings)
695
+  tongueGeometry.translate(0, 0, -0.02)
696
+  const tongue = new THREE.Mesh(tongueGeometry, laceMaterial)
697
+  tongue.position.set(0.0, 0.55, 0.18)
698
+  tongue.rotation.x = 0.3
676
   group.add(tongue)
699
   group.add(tongue)
677
 
700
 
678
-  // --- LACING DETAILS ---
701
+  // === LACING ===
679
   const laceCordMaterial = new THREE.MeshToonMaterial({
702
   const laceCordMaterial = new THREE.MeshToonMaterial({
680
     color: 0xf5deb3,
703
     color: 0xf5deb3,
681
     gradientMap
704
     gradientMap
682
   })
705
   })
683
 
706
 
684
-  // Lace eyelets (holes)
707
+  // Lace eyelets
685
-  const eyeletGeom = new THREE.TorusGeometry(0.025, 0.008, 6, 12)
708
+  const eyeletGeom = new THREE.TorusGeometry(0.02, 0.006, 6, 10)
686
   for (let i = 0; i < 4; i++) {
709
   for (let i = 0; i < 4; i++) {
687
-    const y = 0.42 + i * 0.12
710
+    const y = 0.58 + i * 0.1
688
-    const z = 0.28 - i * 0.02
711
+    const x = 0.08 - i * 0.015
689
 
712
 
690
     const eyeletL = new THREE.Mesh(eyeletGeom, darkLeatherMaterial)
713
     const eyeletL = new THREE.Mesh(eyeletGeom, darkLeatherMaterial)
691
-    eyeletL.position.set(-0.06, y, z)
714
+    eyeletL.position.set(x - 0.07, y, 0.2)
692
     eyeletL.rotation.x = Math.PI / 2 - 0.3
715
     eyeletL.rotation.x = Math.PI / 2 - 0.3
693
     group.add(eyeletL)
716
     group.add(eyeletL)
694
 
717
 
695
     const eyeletR = new THREE.Mesh(eyeletGeom, darkLeatherMaterial)
718
     const eyeletR = new THREE.Mesh(eyeletGeom, darkLeatherMaterial)
696
-    eyeletR.position.set(0.08, y, z)
719
+    eyeletR.position.set(x + 0.07, y, 0.2)
697
     eyeletR.rotation.x = Math.PI / 2 - 0.3
720
     eyeletR.rotation.x = Math.PI / 2 - 0.3
698
     group.add(eyeletR)
721
     group.add(eyeletR)
699
   }
722
   }
700
 
723
 
701
-  // Cross-laces
724
+  // Cross laces
702
-  for (let i = 0; i < 3; i++) {
725
+  for (let i = 0; i < 4; i++) {
703
-    const y = 0.48 + i * 0.12
726
+    const y = 0.58 + i * 0.1
704
-    const z = 0.30 - i * 0.02
727
+    const x = 0.08 - i * 0.015
705
-    const cordGeom = new THREE.CylinderGeometry(0.008, 0.008, 0.16, 4)
728
+    const cordGeom = new THREE.CylinderGeometry(0.006, 0.006, 0.14, 4)
706
     const cord = new THREE.Mesh(cordGeom, laceCordMaterial)
729
     const cord = new THREE.Mesh(cordGeom, laceCordMaterial)
707
-    cord.position.set(0.01, y, z)
730
+    cord.position.set(x, y, 0.21)
708
     cord.rotation.z = Math.PI / 2
731
     cord.rotation.z = Math.PI / 2
709
-    cord.rotation.y = 0.3
710
     group.add(cord)
732
     group.add(cord)
711
   }
733
   }
712
 
734
 
713
-  // Bow at top of lacing
735
+  // Bow loops
714
-  const bowLoopGeom = new THREE.TorusGeometry(0.04, 0.012, 6, 12, Math.PI)
736
+  const bowLoopGeom = new THREE.TorusGeometry(0.035, 0.01, 6, 10, Math.PI)
715
   const bowL = new THREE.Mesh(bowLoopGeom, laceCordMaterial)
737
   const bowL = new THREE.Mesh(bowLoopGeom, laceCordMaterial)
716
-  bowL.position.set(-0.04, 0.82, 0.24)
738
+  bowL.position.set(-0.03, 0.95, 0.19)
717
   bowL.rotation.y = Math.PI / 2
739
   bowL.rotation.y = Math.PI / 2
718
-  bowL.rotation.x = 0.5
740
+  bowL.rotation.x = 0.4
719
   group.add(bowL)
741
   group.add(bowL)
720
 
742
 
721
   const bowR = new THREE.Mesh(bowLoopGeom, laceCordMaterial)
743
   const bowR = new THREE.Mesh(bowLoopGeom, laceCordMaterial)
722
-  bowR.position.set(0.06, 0.82, 0.24)
744
+  bowR.position.set(0.08, 0.95, 0.19)
723
   bowR.rotation.y = -Math.PI / 2
745
   bowR.rotation.y = -Math.PI / 2
724
-  bowR.rotation.x = 0.5
746
+  bowR.rotation.x = 0.4
725
   group.add(bowR)
747
   group.add(bowR)
726
 
748
 
727
   // Bow tails
749
   // Bow tails
728
-  const tailGeom = new THREE.CylinderGeometry(0.01, 0.006, 0.12, 4)
750
+  const tailGeom = new THREE.CylinderGeometry(0.008, 0.005, 0.1, 4)
729
   const tailL = new THREE.Mesh(tailGeom, laceCordMaterial)
751
   const tailL = new THREE.Mesh(tailGeom, laceCordMaterial)
730
-  tailL.position.set(-0.06, 0.76, 0.26)
752
+  tailL.position.set(-0.04, 0.9, 0.2)
731
-  tailL.rotation.z = 0.4
753
+  tailL.rotation.z = 0.5
732
-  tailL.rotation.x = 0.3
733
   group.add(tailL)
754
   group.add(tailL)
734
 
755
 
735
   const tailR = new THREE.Mesh(tailGeom, laceCordMaterial)
756
   const tailR = new THREE.Mesh(tailGeom, laceCordMaterial)
736
-  tailR.position.set(0.08, 0.76, 0.26)
757
+  tailR.position.set(0.09, 0.9, 0.2)
737
-  tailR.rotation.z = -0.4
758
+  tailR.rotation.z = -0.5
738
-  tailR.rotation.x = 0.3
739
   group.add(tailR)
759
   group.add(tailR)
740
 
760
 
741
   // === WINDOWS ===
761
   // === WINDOWS ===
742
 
762
 
743
-  // Round window on toe
763
+  // Round window on toe (front of boot)
744
-  const toeWindowGeom = new THREE.CircleGeometry(0.07, 12)
764
+  const toeWindowGeom = new THREE.CircleGeometry(0.06, 12)
745
   const toeWindow = new THREE.Mesh(toeWindowGeom, windowMaterial)
765
   const toeWindow = new THREE.Mesh(toeWindowGeom, windowMaterial)
746
-  toeWindow.position.set(-0.72, 0.28, 0)
766
+  toeWindow.position.set(-0.48, 0.25, 0)
747
   toeWindow.rotation.y = -Math.PI / 2
767
   toeWindow.rotation.y = -Math.PI / 2
748
   group.add(toeWindow)
768
   group.add(toeWindow)
749
 
769
 
750
-  // Window frame
770
+  const toeFrameGeom = new THREE.TorusGeometry(0.06, 0.01, 4, 14)
751
-  const toeFrameGeom = new THREE.TorusGeometry(0.07, 0.012, 4, 16)
752
   const toeFrame = new THREE.Mesh(toeFrameGeom, darkLeatherMaterial)
771
   const toeFrame = new THREE.Mesh(toeFrameGeom, darkLeatherMaterial)
753
-  toeFrame.position.set(-0.71, 0.28, 0)
772
+  toeFrame.position.set(-0.47, 0.25, 0)
754
   toeFrame.rotation.y = -Math.PI / 2
773
   toeFrame.rotation.y = -Math.PI / 2
755
   group.add(toeFrame)
774
   group.add(toeFrame)
756
 
775
 
757
-  // Windows on shaft (2 on sides)
776
+  // Side windows on the shaft
758
-  for (let i = 0; i < 2; i++) {
777
+  const sideWindowGeom = new THREE.CircleGeometry(0.05, 10)
759
-    const angle = (i === 0) ? Math.PI * 0.65 : -Math.PI * 0.65
778
+  const sideFrameGeom = new THREE.TorusGeometry(0.05, 0.008, 4, 12)
760
-    const wx = 0.25 + Math.sin(angle) * 0.29
779
+
761
-    const wz = Math.cos(angle) * 0.29
780
+  // Left side window
762
-
781
+  const windowL = new THREE.Mesh(sideWindowGeom, windowMaterial)
763
-    const shaftWindowGeom = new THREE.CircleGeometry(0.06, 10)
782
+  windowL.position.set(0.3, 0.75, -0.2)
764
-    const shaftWindow = new THREE.Mesh(shaftWindowGeom, windowMaterial)
783
+  windowL.rotation.y = Math.PI / 2
765
-    shaftWindow.position.set(wx, 0.7, wz)
784
+  group.add(windowL)
766
-    shaftWindow.rotation.y = angle + Math.PI
785
+
767
-    group.add(shaftWindow)
786
+  const frameL = new THREE.Mesh(sideFrameGeom, darkLeatherMaterial)
768
-
787
+  frameL.position.set(0.29, 0.75, -0.2)
769
-    // Frame
788
+  frameL.rotation.y = Math.PI / 2
770
-    const frameGeom = new THREE.TorusGeometry(0.06, 0.01, 4, 12)
789
+  group.add(frameL)
771
-    const frame = new THREE.Mesh(frameGeom, darkLeatherMaterial)
790
+
772
-    frame.position.set(wx, 0.7, wz)
791
+  // Right side window
773
-    frame.rotation.y = angle + Math.PI
792
+  const windowR = new THREE.Mesh(sideWindowGeom, windowMaterial)
774
-    group.add(frame)
793
+  windowR.position.set(0.3, 0.75, 0.2)
775
-  }
794
+  windowR.rotation.y = -Math.PI / 2
795
+  group.add(windowR)
796
+
797
+  const frameR = new THREE.Mesh(sideFrameGeom, darkLeatherMaterial)
798
+  frameR.position.set(0.29, 0.75, 0.2)
799
+  frameR.rotation.y = -Math.PI / 2
800
+  group.add(frameR)
776
 
801
 
777
   // === BENDY CHIMNEY ===
802
   // === BENDY CHIMNEY ===
778
 
803
 
@@ -832,36 +857,36 @@ export function createBootHouse(gradientMap) {
832
   }
857
   }
833
   chimneyGroup.add(smokeGroup)
858
   chimneyGroup.add(smokeGroup)
834
 
859
 
835
-  chimneyGroup.position.set(0.15, 1.1, -0.12)
860
+  chimneyGroup.position.set(0.35, 1.08, 0)
836
   group.add(chimneyGroup)
861
   group.add(chimneyGroup)
837
 
862
 
838
   // === DOOR ===
863
   // === DOOR ===
839
 
864
 
840
   const doorGroup = new THREE.Group()
865
   const doorGroup = new THREE.Group()
841
 
866
 
842
-  // Arched door on the side of the toe/vamp area
867
+  // Arched door on the toe area
843
-  const doorGeom = new THREE.BoxGeometry(0.12, 0.22, 0.03)
868
+  const doorGeom = new THREE.BoxGeometry(0.1, 0.18, 0.03)
844
   const door = new THREE.Mesh(doorGeom, darkLeatherMaterial)
869
   const door = new THREE.Mesh(doorGeom, darkLeatherMaterial)
845
-  door.position.y = 0.11
870
+  door.position.y = 0.09
846
   doorGroup.add(door)
871
   doorGroup.add(door)
847
 
872
 
848
   // Door arch
873
   // Door arch
849
-  const doorArchGeom = new THREE.SphereGeometry(0.06, 8, 4, 0, Math.PI * 2, 0, Math.PI / 2)
874
+  const doorArchGeom = new THREE.SphereGeometry(0.05, 8, 4, 0, Math.PI * 2, 0, Math.PI / 2)
850
   const doorArch = new THREE.Mesh(doorArchGeom, darkLeatherMaterial)
875
   const doorArch = new THREE.Mesh(doorArchGeom, darkLeatherMaterial)
851
-  doorArch.position.y = 0.22
876
+  doorArch.position.y = 0.18
852
   doorArch.rotation.x = Math.PI
877
   doorArch.rotation.x = Math.PI
853
   doorGroup.add(doorArch)
878
   doorGroup.add(doorArch)
854
 
879
 
855
   // Door knob
880
   // Door knob
856
-  const knobGeom = new THREE.SphereGeometry(0.015, 6, 4)
881
+  const knobGeom = new THREE.SphereGeometry(0.012, 6, 4)
857
   const knobMat = new THREE.MeshToonMaterial({ color: 0xffd700, gradientMap })
882
   const knobMat = new THREE.MeshToonMaterial({ color: 0xffd700, gradientMap })
858
   const knob = new THREE.Mesh(knobGeom, knobMat)
883
   const knob = new THREE.Mesh(knobGeom, knobMat)
859
-  knob.position.set(0.04, 0.1, 0.02)
884
+  knob.position.set(0.03, 0.08, 0.02)
860
   doorGroup.add(knob)
885
   doorGroup.add(knob)
861
 
886
 
862
-  // Position door on the front-side of the boot
887
+  // Position door on the side of the toe
863
-  doorGroup.position.set(-0.32, 0.1, 0.22)
888
+  doorGroup.position.set(-0.4, 0.1, 0.18)
864
-  doorGroup.rotation.y = -0.4
889
+  doorGroup.rotation.y = -0.6
865
   group.add(doorGroup)
890
   group.add(doorGroup)
866
 
891
 
867
   // === YARD WITH TALL GRASS PATCHES ===
892
   // === YARD WITH TALL GRASS PATCHES ===
@@ -871,12 +896,12 @@ export function createBootHouse(gradientMap) {
871
 
896
 
872
   // Create grass patches around the boot
897
   // Create grass patches around the boot
873
   const grassPositions = [
898
   const grassPositions = [
874
-    { x: -0.8, z: 0.35, count: 8 },
899
+    { x: -0.7, z: 0.4, count: 8 },
875
-    { x: -0.75, z: -0.35, count: 6 },
900
+    { x: -0.7, z: -0.4, count: 6 },
876
-    { x: 0.7, z: 0.4, count: 7 },
901
+    { x: 0.65, z: 0.4, count: 7 },
877
-    { x: 0.75, z: -0.35, count: 5 },
902
+    { x: 0.65, z: -0.4, count: 5 },
878
-    { x: 0.0, z: -0.55, count: 6 },
903
+    { x: -0.1, z: -0.55, count: 6 },
879
-    { x: 0.0, z: 0.55, count: 5 }
904
+    { x: -0.1, z: 0.55, count: 5 }
880
   ]
905
   ]
881
 
906
 
882
   for (const patch of grassPositions) {
907
   for (const patch of grassPositions) {
@@ -968,11 +993,11 @@ export function createBootHouse(gradientMap) {
968
     sprite.add(pupilR)
993
     sprite.add(pupilR)
969
 
994
 
970
     // Animation data
995
     // Animation data
971
-    sprite.userData.orbitRadius = 0.6 + Math.random() * 0.25
996
+    sprite.userData.orbitRadius = 0.55 + Math.random() * 0.2
972
     sprite.userData.orbitSpeed = 0.8 + Math.random() * 0.6
997
     sprite.userData.orbitSpeed = 0.8 + Math.random() * 0.6
973
     sprite.userData.orbitPhase = (i / 4) * Math.PI * 2
998
     sprite.userData.orbitPhase = (i / 4) * Math.PI * 2
974
     sprite.userData.bobPhase = Math.random() * Math.PI * 2
999
     sprite.userData.bobPhase = Math.random() * Math.PI * 2
975
-    sprite.userData.orbitCenterX = 0.0 // Center of boot footprint
1000
+    sprite.userData.orbitCenterX = -0.05 // Center of boot footprint
976
     sprite.userData.orbitCenterZ = 0
1001
     sprite.userData.orbitCenterZ = 0
977
 
1002
 
978
     // Initial position
1003
     // Initial position