zeroed-some/dougk / 6184c04

Browse files

improve boot house

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
6184c04ce4545c00a503c3254d7bae55b523997a
Parents
5a6a9e7
Tree
3c20125

1 changed file

StatusFile+-
M src/renderers/three/buildings.js 174 83
src/renderers/three/buildings.jsmodified
@@ -578,109 +578,198 @@ export function createBootHouse(gradientMap) {
578578
   // Sprite body colors
579579
   const spriteColors = [0xff6b9d, 0x9b59b6, 0x3498db, 0x2ecc71]
580580
 
581
-  // === BOOT STRUCTURE ===
582
-
583
-  // Boot sole (the base)
584
-  const soleGeom = new THREE.BoxGeometry(1.0, 0.12, 0.6)
585
-  soleGeom.translate(0.1, 0, 0) // Offset for toe curve
586
-  const sole = new THREE.Mesh(soleGeom, soleMaterial)
587
-  sole.position.y = 0.06
588
-  group.add(sole)
589
-
590
-  // Toe section - curved front of boot (rounded box)
591
-  const toeGeom = new THREE.SphereGeometry(0.35, 10, 8)
592
-  toeGeom.scale(1.2, 0.7, 1.0)
593
-  const toe = new THREE.Mesh(toeGeom, leatherMaterial)
594
-  toe.position.set(-0.35, 0.25, 0)
595
-  group.add(toe)
596
-
597
-  // Main boot body (the ankle/shaft part) - this is the house
598
-  const shaftGeom = new THREE.CylinderGeometry(0.32, 0.38, 0.9, 10)
581
+  // === BOOT STRUCTURE (Continuous realistic boot shape) ===
582
+
583
+  // The boot is built as overlapping shapes with the same material
584
+  // to create a seamless, continuous appearance
585
+
586
+  // --- SOLE (follows the boot footprint) ---
587
+  // Main sole - elongated with rounded ends
588
+  const soleLength = 1.1
589
+  const soleWidth = 0.5
590
+  const soleHeight = 0.1
591
+
592
+  // Sole base
593
+  const soleBaseGeom = new THREE.BoxGeometry(soleLength - 0.3, soleHeight, soleWidth - 0.1)
594
+  const soleBase = new THREE.Mesh(soleBaseGeom, soleMaterial)
595
+  soleBase.position.set(0, soleHeight / 2, 0)
596
+  group.add(soleBase)
597
+
598
+  // Sole toe cap (rounded front)
599
+  const soleToeGeom = new THREE.CylinderGeometry(soleWidth / 2 - 0.05, soleWidth / 2 - 0.05, soleHeight, 12)
600
+  soleToeGeom.rotateX(Math.PI / 2)
601
+  const soleToe = new THREE.Mesh(soleToeGeom, soleMaterial)
602
+  soleToe.position.set(-soleLength / 2 + 0.15, soleHeight / 2, 0)
603
+  group.add(soleToe)
604
+
605
+  // Sole heel cap (rounded back)
606
+  const soleHeelGeom = new THREE.CylinderGeometry(soleWidth / 2 - 0.05, soleWidth / 2 - 0.05, soleHeight * 1.3, 12)
607
+  soleHeelGeom.rotateX(Math.PI / 2)
608
+  const soleHeel = new THREE.Mesh(soleHeelGeom, soleMaterial)
609
+  soleHeel.position.set(soleLength / 2 - 0.2, soleHeight * 0.65, 0)
610
+  group.add(soleHeel)
611
+
612
+  // --- FOOT PORTION (continuous with ankle) ---
613
+
614
+  // Lower foot - the part that sits on the sole
615
+  // Uses a squashed capsule shape tilted up at the toe
616
+  const footBaseGeom = new THREE.CapsuleGeometry(0.22, 0.5, 8, 12)
617
+  footBaseGeom.rotateZ(Math.PI / 2) // Lay it horizontal
618
+  footBaseGeom.scale(1, 0.75, 1) // Flatten slightly
619
+  const footBase = new THREE.Mesh(footBaseGeom, leatherMaterial)
620
+  footBase.position.set(-0.1, 0.28, 0)
621
+  footBase.rotation.z = -0.15 // Tilt toe up slightly
622
+  group.add(footBase)
623
+
624
+  // Toe box - rounded front that curves upward
625
+  const toeBoxGeom = new THREE.SphereGeometry(0.28, 12, 10)
626
+  toeBoxGeom.scale(0.9, 0.85, 1.0)
627
+  const toeBox = new THREE.Mesh(toeBoxGeom, leatherMaterial)
628
+  toeBox.position.set(-0.48, 0.26, 0)
629
+  group.add(toeBox)
630
+
631
+  // --- ANKLE/SHAFT (rises from heel, connects to foot) ---
632
+
633
+  // Ankle transition - connects foot to shaft smoothly
634
+  const ankleTransitionGeom = new THREE.SphereGeometry(0.34, 12, 10)
635
+  ankleTransitionGeom.scale(1.0, 0.8, 1.0)
636
+  const ankleTransition = new THREE.Mesh(ankleTransitionGeom, leatherMaterial)
637
+  ankleTransition.position.set(0.25, 0.35, 0)
638
+  group.add(ankleTransition)
639
+
640
+  // Main shaft (ankle part) - tapers slightly upward
641
+  const shaftGeom = new THREE.CylinderGeometry(0.28, 0.34, 0.75, 14)
599642
   const shaft = new THREE.Mesh(shaftGeom, leatherMaterial)
600
-  shaft.position.set(0.25, 0.6, 0)
643
+  shaft.position.set(0.25, 0.72, 0)
601644
   group.add(shaft)
602645
 
603
-  // Boot rim/collar at top
604
-  const rimGeom = new THREE.TorusGeometry(0.34, 0.05, 6, 16)
605
-  const rim = new THREE.Mesh(rimGeom, darkLeatherMaterial)
606
-  rim.position.set(0.25, 1.05, 0)
607
-  rim.rotation.x = Math.PI / 2
608
-  group.add(rim)
609
-
610
-  // Tongue (extending from shaft toward toe)
611
-  const tongueGeom = new THREE.BoxGeometry(0.18, 0.4, 0.08)
646
+  // Shaft top rim
647
+  const shaftTopGeom = new THREE.TorusGeometry(0.30, 0.04, 8, 20)
648
+  const shaftTop = new THREE.Mesh(shaftTopGeom, leatherMaterial)
649
+  shaftTop.position.set(0.25, 1.1, 0)
650
+  shaftTop.rotation.x = Math.PI / 2
651
+  group.add(shaftTop)
652
+
653
+  // --- INSTEP/VAMP (connects toe to ankle on top) ---
654
+
655
+  // This fills the gap between toe and shaft on top of the foot
656
+  const vampGeom = new THREE.CapsuleGeometry(0.18, 0.35, 6, 10)
657
+  vampGeom.rotateZ(Math.PI / 2)
658
+  vampGeom.scale(1, 0.7, 0.9)
659
+  const vamp = new THREE.Mesh(vampGeom, leatherMaterial)
660
+  vamp.position.set(-0.08, 0.38, 0)
661
+  vamp.rotation.z = -0.4 // Angle down toward toe
662
+  group.add(vamp)
663
+
664
+  // --- HEEL COUNTER (back of heel, reinforcement) ---
665
+  const heelCounterGeom = new THREE.CylinderGeometry(0.26, 0.3, 0.25, 14, 1, false, -Math.PI * 0.6, Math.PI * 1.2)
666
+  const heelCounter = new THREE.Mesh(heelCounterGeom, darkLeatherMaterial)
667
+  heelCounter.position.set(0.35, 0.22, 0)
668
+  group.add(heelCounter)
669
+
670
+  // --- TONGUE ---
671
+  const tongueGeom = new THREE.CapsuleGeometry(0.08, 0.25, 4, 8)
612672
   const tongue = new THREE.Mesh(tongueGeom, laceMaterial)
613
-  tongue.position.set(0.05, 0.5, 0.32)
614
-  tongue.rotation.x = 0.3
673
+  tongue.position.set(0.0, 0.55, 0.26)
674
+  tongue.rotation.x = 0.35
675
+  tongue.rotation.z = -0.1
615676
   group.add(tongue)
616677
 
617
-  // Lace holes (decorative dots)
618
-  const holeGeom = new THREE.CylinderGeometry(0.025, 0.025, 0.02, 8)
619
-  for (let i = 0; i < 4; i++) {
620
-    const holeL = new THREE.Mesh(holeGeom, soleMaterial)
621
-    holeL.position.set(-0.05, 0.35 + i * 0.15, 0.36)
622
-    holeL.rotation.x = Math.PI / 2
623
-    group.add(holeL)
624
-
625
-    const holeR = new THREE.Mesh(holeGeom, soleMaterial)
626
-    holeR.position.set(0.15, 0.35 + i * 0.15, 0.36)
627
-    holeR.rotation.x = Math.PI / 2
628
-    group.add(holeR)
629
-  }
630
-
631
-  // Cross-laces between holes
678
+  // --- LACING DETAILS ---
632679
   const laceCordMaterial = new THREE.MeshToonMaterial({
633680
     color: 0xf5deb3,
634681
     gradientMap
635682
   })
683
+
684
+  // Lace eyelets (holes)
685
+  const eyeletGeom = new THREE.TorusGeometry(0.025, 0.008, 6, 12)
686
+  for (let i = 0; i < 4; i++) {
687
+    const y = 0.42 + i * 0.12
688
+    const z = 0.28 - i * 0.02
689
+
690
+    const eyeletL = new THREE.Mesh(eyeletGeom, darkLeatherMaterial)
691
+    eyeletL.position.set(-0.06, y, z)
692
+    eyeletL.rotation.x = Math.PI / 2 - 0.3
693
+    group.add(eyeletL)
694
+
695
+    const eyeletR = new THREE.Mesh(eyeletGeom, darkLeatherMaterial)
696
+    eyeletR.position.set(0.08, y, z)
697
+    eyeletR.rotation.x = Math.PI / 2 - 0.3
698
+    group.add(eyeletR)
699
+  }
700
+
701
+  // Cross-laces
636702
   for (let i = 0; i < 3; i++) {
637
-    const cordGeom = new THREE.CylinderGeometry(0.01, 0.01, 0.22, 4)
703
+    const y = 0.48 + i * 0.12
704
+    const z = 0.30 - i * 0.02
705
+    const cordGeom = new THREE.CylinderGeometry(0.008, 0.008, 0.16, 4)
638706
     const cord = new THREE.Mesh(cordGeom, laceCordMaterial)
639
-    cord.position.set(0.05, 0.42 + i * 0.15, 0.37)
707
+    cord.position.set(0.01, y, z)
640708
     cord.rotation.z = Math.PI / 2
641
-    cord.rotation.x = 0.3
709
+    cord.rotation.y = 0.3
642710
     group.add(cord)
643711
   }
644712
 
645
-  // Heel bump
646
-  const heelGeom = new THREE.SphereGeometry(0.18, 8, 6)
647
-  heelGeom.scale(1.0, 0.8, 0.6)
648
-  const heel = new THREE.Mesh(heelGeom, soleMaterial)
649
-  heel.position.set(0.55, 0.1, 0)
650
-  group.add(heel)
713
+  // Bow at top of lacing
714
+  const bowLoopGeom = new THREE.TorusGeometry(0.04, 0.012, 6, 12, Math.PI)
715
+  const bowL = new THREE.Mesh(bowLoopGeom, laceCordMaterial)
716
+  bowL.position.set(-0.04, 0.82, 0.24)
717
+  bowL.rotation.y = Math.PI / 2
718
+  bowL.rotation.x = 0.5
719
+  group.add(bowL)
720
+
721
+  const bowR = new THREE.Mesh(bowLoopGeom, laceCordMaterial)
722
+  bowR.position.set(0.06, 0.82, 0.24)
723
+  bowR.rotation.y = -Math.PI / 2
724
+  bowR.rotation.x = 0.5
725
+  group.add(bowR)
726
+
727
+  // Bow tails
728
+  const tailGeom = new THREE.CylinderGeometry(0.01, 0.006, 0.12, 4)
729
+  const tailL = new THREE.Mesh(tailGeom, laceCordMaterial)
730
+  tailL.position.set(-0.06, 0.76, 0.26)
731
+  tailL.rotation.z = 0.4
732
+  tailL.rotation.x = 0.3
733
+  group.add(tailL)
734
+
735
+  const tailR = new THREE.Mesh(tailGeom, laceCordMaterial)
736
+  tailR.position.set(0.08, 0.76, 0.26)
737
+  tailR.rotation.z = -0.4
738
+  tailR.rotation.x = 0.3
739
+  group.add(tailR)
651740
 
652741
   // === WINDOWS ===
653742
 
654743
   // Round window on toe
655
-  const toeWindowGeom = new THREE.CircleGeometry(0.08, 10)
744
+  const toeWindowGeom = new THREE.CircleGeometry(0.07, 12)
656745
   const toeWindow = new THREE.Mesh(toeWindowGeom, windowMaterial)
657
-  toeWindow.position.set(-0.58, 0.3, 0)
746
+  toeWindow.position.set(-0.72, 0.28, 0)
658747
   toeWindow.rotation.y = -Math.PI / 2
659748
   group.add(toeWindow)
660749
 
661750
   // Window frame
662
-  const toeFrameGeom = new THREE.TorusGeometry(0.08, 0.015, 4, 16)
751
+  const toeFrameGeom = new THREE.TorusGeometry(0.07, 0.012, 4, 16)
663752
   const toeFrame = new THREE.Mesh(toeFrameGeom, darkLeatherMaterial)
664
-  toeFrame.position.set(-0.57, 0.3, 0)
753
+  toeFrame.position.set(-0.71, 0.28, 0)
665754
   toeFrame.rotation.y = -Math.PI / 2
666755
   group.add(toeFrame)
667756
 
668
-  // Windows on shaft (2 small ones)
757
+  // Windows on shaft (2 on sides)
669758
   for (let i = 0; i < 2; i++) {
670
-    const angle = (i === 0) ? Math.PI * 0.7 : -Math.PI * 0.7
671
-    const wx = 0.25 + Math.sin(angle) * 0.33
672
-    const wz = Math.cos(angle) * 0.33
759
+    const angle = (i === 0) ? Math.PI * 0.65 : -Math.PI * 0.65
760
+    const wx = 0.25 + Math.sin(angle) * 0.29
761
+    const wz = Math.cos(angle) * 0.29
673762
 
674
-    const shaftWindowGeom = new THREE.PlaneGeometry(0.12, 0.15)
763
+    const shaftWindowGeom = new THREE.CircleGeometry(0.06, 10)
675764
     const shaftWindow = new THREE.Mesh(shaftWindowGeom, windowMaterial)
676
-    shaftWindow.position.set(wx, 0.6, wz)
765
+    shaftWindow.position.set(wx, 0.7, wz)
677766
     shaftWindow.rotation.y = angle + Math.PI
678767
     group.add(shaftWindow)
679768
 
680769
     // Frame
681
-    const frameGeom = new THREE.BoxGeometry(0.14, 0.17, 0.02)
770
+    const frameGeom = new THREE.TorusGeometry(0.06, 0.01, 4, 12)
682771
     const frame = new THREE.Mesh(frameGeom, darkLeatherMaterial)
683
-    frame.position.set(wx, 0.6, wz)
772
+    frame.position.set(wx, 0.7, wz)
684773
     frame.rotation.y = angle + Math.PI
685774
     group.add(frame)
686775
   }
@@ -743,34 +832,36 @@ export function createBootHouse(gradientMap) {
743832
   }
744833
   chimneyGroup.add(smokeGroup)
745834
 
746
-  chimneyGroup.position.set(0.1, 1.0, -0.15)
835
+  chimneyGroup.position.set(0.15, 1.1, -0.12)
747836
   group.add(chimneyGroup)
748837
 
749838
   // === DOOR ===
750839
 
751840
   const doorGroup = new THREE.Group()
752841
 
753
-  // Arched door on the toe
754
-  const doorGeom = new THREE.BoxGeometry(0.15, 0.25, 0.03)
842
+  // Arched door on the side of the toe/vamp area
843
+  const doorGeom = new THREE.BoxGeometry(0.12, 0.22, 0.03)
755844
   const door = new THREE.Mesh(doorGeom, darkLeatherMaterial)
756
-  door.position.y = 0.125
845
+  door.position.y = 0.11
757846
   doorGroup.add(door)
758847
 
759848
   // Door arch
760
-  const doorArchGeom = new THREE.SphereGeometry(0.075, 8, 4, 0, Math.PI * 2, 0, Math.PI / 2)
849
+  const doorArchGeom = new THREE.SphereGeometry(0.06, 8, 4, 0, Math.PI * 2, 0, Math.PI / 2)
761850
   const doorArch = new THREE.Mesh(doorArchGeom, darkLeatherMaterial)
762
-  doorArch.position.y = 0.25
851
+  doorArch.position.y = 0.22
763852
   doorArch.rotation.x = Math.PI
764853
   doorGroup.add(doorArch)
765854
 
766855
   // Door knob
767
-  const knobGeom = new THREE.SphereGeometry(0.018, 6, 4)
856
+  const knobGeom = new THREE.SphereGeometry(0.015, 6, 4)
768857
   const knobMat = new THREE.MeshToonMaterial({ color: 0xffd700, gradientMap })
769858
   const knob = new THREE.Mesh(knobGeom, knobMat)
770
-  knob.position.set(0.05, 0.12, 0.02)
859
+  knob.position.set(0.04, 0.1, 0.02)
771860
   doorGroup.add(knob)
772861
 
773
-  doorGroup.position.set(-0.25, 0.12, 0.35)
862
+  // Position door on the front-side of the boot
863
+  doorGroup.position.set(-0.32, 0.1, 0.22)
864
+  doorGroup.rotation.y = -0.4
774865
   group.add(doorGroup)
775866
 
776867
   // === YARD WITH TALL GRASS PATCHES ===
@@ -780,12 +871,12 @@ export function createBootHouse(gradientMap) {
780871
 
781872
   // Create grass patches around the boot
782873
   const grassPositions = [
783
-    { x: -0.7, z: 0.4, count: 8 },
784
-    { x: -0.6, z: -0.35, count: 6 },
785
-    { x: 0.7, z: 0.35, count: 7 },
786
-    { x: 0.65, z: -0.3, count: 5 },
787
-    { x: -0.1, z: -0.5, count: 6 },
788
-    { x: 0.4, z: 0.5, count: 5 }
874
+    { x: -0.8, z: 0.35, count: 8 },
875
+    { x: -0.75, z: -0.35, count: 6 },
876
+    { x: 0.7, z: 0.4, count: 7 },
877
+    { x: 0.75, z: -0.35, count: 5 },
878
+    { x: 0.0, z: -0.55, count: 6 },
879
+    { x: 0.0, z: 0.55, count: 5 }
789880
   ]
790881
 
791882
   for (const patch of grassPositions) {
@@ -877,11 +968,11 @@ export function createBootHouse(gradientMap) {
877968
     sprite.add(pupilR)
878969
 
879970
     // Animation data
880
-    sprite.userData.orbitRadius = 0.5 + Math.random() * 0.3
971
+    sprite.userData.orbitRadius = 0.6 + Math.random() * 0.25
881972
     sprite.userData.orbitSpeed = 0.8 + Math.random() * 0.6
882973
     sprite.userData.orbitPhase = (i / 4) * Math.PI * 2
883974
     sprite.userData.bobPhase = Math.random() * Math.PI * 2
884
-    sprite.userData.orbitCenterX = 0.1 // Roughly center of boot
975
+    sprite.userData.orbitCenterX = 0.0 // Center of boot footprint
885976
     sprite.userData.orbitCenterZ = 0
886977
 
887978
     // Initial position