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) {
578578
   // Sprite body colors
579579
   const spriteColors = [0xff6b9d, 0x9b59b6, 0x3498db, 0x2ecc71]
580580
 
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)
642
-  const shaft = new THREE.Mesh(shaftGeom, leatherMaterial)
643
-  shaft.position.set(0.25, 0.72, 0)
644
-  group.add(shaft)
645
-
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)
672
-  const tongue = new THREE.Mesh(tongueGeom, laceMaterial)
673
-  tongue.position.set(0.0, 0.55, 0.26)
674
-  tongue.rotation.x = 0.35
675
-  tongue.rotation.z = -0.1
581
+  // === BOOT STRUCTURE (Extruded 2D profile for smooth continuous shape) ===
582
+
583
+  // Create a boot profile as a 2D shape, then extrude it
584
+  // This creates ONE continuous mesh that looks like a real boot
585
+
586
+  const bootShape = new THREE.Shape()
587
+
588
+  // Boot profile (side view, starting from heel bottom, going clockwise)
589
+  // Scale: roughly 1 unit tall, 1.2 units long
590
+
591
+  // Start at heel bottom
592
+  bootShape.moveTo(0.45, 0)
593
+
594
+  // Sole - flat bottom with slight curve at toe
595
+  bootShape.lineTo(-0.35, 0)
596
+
597
+  // Toe curves up
598
+  bootShape.quadraticCurveTo(-0.55, 0, -0.55, 0.15)
599
+  bootShape.quadraticCurveTo(-0.55, 0.35, -0.4, 0.4)
600
+
601
+  // Vamp/instep - curves up toward ankle
602
+  bootShape.quadraticCurveTo(-0.15, 0.45, 0.05, 0.55)
603
+
604
+  // Front of ankle/shaft - rises up
605
+  bootShape.quadraticCurveTo(0.15, 0.65, 0.15, 0.95)
606
+
607
+  // Top opening - slight outward flare
608
+  bootShape.quadraticCurveTo(0.15, 1.05, 0.22, 1.08)
609
+
610
+  // Across the top opening
611
+  bootShape.lineTo(0.42, 1.08)
612
+
613
+  // Back of shaft curves down
614
+  bootShape.quadraticCurveTo(0.5, 1.05, 0.5, 0.95)
615
+  bootShape.quadraticCurveTo(0.5, 0.5, 0.48, 0.25)
616
+
617
+  // Heel curves to bottom
618
+  bootShape.quadraticCurveTo(0.48, 0.08, 0.45, 0)
619
+
620
+  // Extrude settings - depth gives the boot width, bevel rounds edges
621
+  const extrudeSettings = {
622
+    steps: 1,
623
+    depth: 0.45,
624
+    bevelEnabled: true,
625
+    bevelThickness: 0.08,
626
+    bevelSize: 0.06,
627
+    bevelOffset: 0,
628
+    bevelSegments: 4
629
+  }
630
+
631
+  const bootGeometry = new THREE.ExtrudeGeometry(bootShape, extrudeSettings)
632
+
633
+  // Center the boot (extrude goes in +Z, so offset by half depth)
634
+  bootGeometry.translate(0, 0, -0.225)
635
+
636
+  const bootMesh = new THREE.Mesh(bootGeometry, leatherMaterial)
637
+  group.add(bootMesh)
638
+
639
+  // === SOLE (darker strip along bottom) ===
640
+  const soleShape = new THREE.Shape()
641
+  soleShape.moveTo(0.45, 0)
642
+  soleShape.lineTo(-0.35, 0)
643
+  soleShape.quadraticCurveTo(-0.55, 0, -0.55, 0.08)
644
+  soleShape.lineTo(-0.5, 0.1)
645
+  soleShape.lineTo(0.45, 0.1)
646
+  soleShape.quadraticCurveTo(0.48, 0.08, 0.48, 0.05)
647
+  soleShape.lineTo(0.45, 0)
648
+
649
+  const soleExtrudeSettings = {
650
+    steps: 1,
651
+    depth: 0.48,
652
+    bevelEnabled: true,
653
+    bevelThickness: 0.03,
654
+    bevelSize: 0.02,
655
+    bevelSegments: 2
656
+  }
657
+
658
+  const soleGeometry = new THREE.ExtrudeGeometry(soleShape, soleExtrudeSettings)
659
+  soleGeometry.translate(0, 0, -0.24)
660
+  const soleMesh = new THREE.Mesh(soleGeometry, soleMaterial)
661
+  group.add(soleMesh)
662
+
663
+  // === HEEL TAB (back loop) ===
664
+  const heelTabGeom = new THREE.BoxGeometry(0.08, 0.12, 0.25)
665
+  const heelTab = new THREE.Mesh(heelTabGeom, darkLeatherMaterial)
666
+  heelTab.position.set(0.48, 1.0, 0)
667
+  group.add(heelTab)
668
+
669
+  // Heel tab loop
670
+  const heelLoopGeom = new THREE.TorusGeometry(0.04, 0.015, 6, 12, Math.PI)
671
+  const heelLoop = new THREE.Mesh(heelLoopGeom, darkLeatherMaterial)
672
+  heelLoop.position.set(0.52, 1.04, 0)
673
+  heelLoop.rotation.z = -Math.PI / 2
674
+  group.add(heelLoop)
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
676699
   group.add(tongue)
677700
 
678
-  // --- LACING DETAILS ---
701
+  // === LACING ===
679702
   const laceCordMaterial = new THREE.MeshToonMaterial({
680703
     color: 0xf5deb3,
681704
     gradientMap
682705
   })
683706
 
684
-  // Lace eyelets (holes)
685
-  const eyeletGeom = new THREE.TorusGeometry(0.025, 0.008, 6, 12)
707
+  // Lace eyelets
708
+  const eyeletGeom = new THREE.TorusGeometry(0.02, 0.006, 6, 10)
686709
   for (let i = 0; i < 4; i++) {
687
-    const y = 0.42 + i * 0.12
688
-    const z = 0.28 - i * 0.02
710
+    const y = 0.58 + i * 0.1
711
+    const x = 0.08 - i * 0.015
689712
 
690713
     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)
692715
     eyeletL.rotation.x = Math.PI / 2 - 0.3
693716
     group.add(eyeletL)
694717
 
695718
     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)
697720
     eyeletR.rotation.x = Math.PI / 2 - 0.3
698721
     group.add(eyeletR)
699722
   }
700723
 
701
-  // Cross-laces
702
-  for (let i = 0; i < 3; i++) {
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)
724
+  // Cross laces
725
+  for (let i = 0; i < 4; i++) {
726
+    const y = 0.58 + i * 0.1
727
+    const x = 0.08 - i * 0.015
728
+    const cordGeom = new THREE.CylinderGeometry(0.006, 0.006, 0.14, 4)
706729
     const cord = new THREE.Mesh(cordGeom, laceCordMaterial)
707
-    cord.position.set(0.01, y, z)
730
+    cord.position.set(x, y, 0.21)
708731
     cord.rotation.z = Math.PI / 2
709
-    cord.rotation.y = 0.3
710732
     group.add(cord)
711733
   }
712734
 
713
-  // Bow at top of lacing
714
-  const bowLoopGeom = new THREE.TorusGeometry(0.04, 0.012, 6, 12, Math.PI)
735
+  // Bow loops
736
+  const bowLoopGeom = new THREE.TorusGeometry(0.035, 0.01, 6, 10, Math.PI)
715737
   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)
717739
   bowL.rotation.y = Math.PI / 2
718
-  bowL.rotation.x = 0.5
740
+  bowL.rotation.x = 0.4
719741
   group.add(bowL)
720742
 
721743
   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)
723745
   bowR.rotation.y = -Math.PI / 2
724
-  bowR.rotation.x = 0.5
746
+  bowR.rotation.x = 0.4
725747
   group.add(bowR)
726748
 
727749
   // 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)
729751
   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
752
+  tailL.position.set(-0.04, 0.9, 0.2)
753
+  tailL.rotation.z = 0.5
733754
   group.add(tailL)
734755
 
735756
   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
757
+  tailR.position.set(0.09, 0.9, 0.2)
758
+  tailR.rotation.z = -0.5
739759
   group.add(tailR)
740760
 
741761
   // === WINDOWS ===
742762
 
743
-  // Round window on toe
744
-  const toeWindowGeom = new THREE.CircleGeometry(0.07, 12)
763
+  // Round window on toe (front of boot)
764
+  const toeWindowGeom = new THREE.CircleGeometry(0.06, 12)
745765
   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)
747767
   toeWindow.rotation.y = -Math.PI / 2
748768
   group.add(toeWindow)
749769
 
750
-  // Window frame
751
-  const toeFrameGeom = new THREE.TorusGeometry(0.07, 0.012, 4, 16)
770
+  const toeFrameGeom = new THREE.TorusGeometry(0.06, 0.01, 4, 14)
752771
   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)
754773
   toeFrame.rotation.y = -Math.PI / 2
755774
   group.add(toeFrame)
756775
 
757
-  // Windows on shaft (2 on sides)
758
-  for (let i = 0; i < 2; i++) {
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
762
-
763
-    const shaftWindowGeom = new THREE.CircleGeometry(0.06, 10)
764
-    const shaftWindow = new THREE.Mesh(shaftWindowGeom, windowMaterial)
765
-    shaftWindow.position.set(wx, 0.7, wz)
766
-    shaftWindow.rotation.y = angle + Math.PI
767
-    group.add(shaftWindow)
768
-
769
-    // Frame
770
-    const frameGeom = new THREE.TorusGeometry(0.06, 0.01, 4, 12)
771
-    const frame = new THREE.Mesh(frameGeom, darkLeatherMaterial)
772
-    frame.position.set(wx, 0.7, wz)
773
-    frame.rotation.y = angle + Math.PI
774
-    group.add(frame)
775
-  }
776
+  // Side windows on the shaft
777
+  const sideWindowGeom = new THREE.CircleGeometry(0.05, 10)
778
+  const sideFrameGeom = new THREE.TorusGeometry(0.05, 0.008, 4, 12)
779
+
780
+  // Left side window
781
+  const windowL = new THREE.Mesh(sideWindowGeom, windowMaterial)
782
+  windowL.position.set(0.3, 0.75, -0.2)
783
+  windowL.rotation.y = Math.PI / 2
784
+  group.add(windowL)
785
+
786
+  const frameL = new THREE.Mesh(sideFrameGeom, darkLeatherMaterial)
787
+  frameL.position.set(0.29, 0.75, -0.2)
788
+  frameL.rotation.y = Math.PI / 2
789
+  group.add(frameL)
790
+
791
+  // Right side window
792
+  const windowR = new THREE.Mesh(sideWindowGeom, windowMaterial)
793
+  windowR.position.set(0.3, 0.75, 0.2)
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)
776801
 
777802
   // === BENDY CHIMNEY ===
778803
 
@@ -832,36 +857,36 @@ export function createBootHouse(gradientMap) {
832857
   }
833858
   chimneyGroup.add(smokeGroup)
834859
 
835
-  chimneyGroup.position.set(0.15, 1.1, -0.12)
860
+  chimneyGroup.position.set(0.35, 1.08, 0)
836861
   group.add(chimneyGroup)
837862
 
838863
   // === DOOR ===
839864
 
840865
   const doorGroup = new THREE.Group()
841866
 
842
-  // Arched door on the side of the toe/vamp area
843
-  const doorGeom = new THREE.BoxGeometry(0.12, 0.22, 0.03)
867
+  // Arched door on the toe area
868
+  const doorGeom = new THREE.BoxGeometry(0.1, 0.18, 0.03)
844869
   const door = new THREE.Mesh(doorGeom, darkLeatherMaterial)
845
-  door.position.y = 0.11
870
+  door.position.y = 0.09
846871
   doorGroup.add(door)
847872
 
848873
   // 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)
850875
   const doorArch = new THREE.Mesh(doorArchGeom, darkLeatherMaterial)
851
-  doorArch.position.y = 0.22
876
+  doorArch.position.y = 0.18
852877
   doorArch.rotation.x = Math.PI
853878
   doorGroup.add(doorArch)
854879
 
855880
   // Door knob
856
-  const knobGeom = new THREE.SphereGeometry(0.015, 6, 4)
881
+  const knobGeom = new THREE.SphereGeometry(0.012, 6, 4)
857882
   const knobMat = new THREE.MeshToonMaterial({ color: 0xffd700, gradientMap })
858883
   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)
860885
   doorGroup.add(knob)
861886
 
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
887
+  // Position door on the side of the toe
888
+  doorGroup.position.set(-0.4, 0.1, 0.18)
889
+  doorGroup.rotation.y = -0.6
865890
   group.add(doorGroup)
866891
 
867892
   // === YARD WITH TALL GRASS PATCHES ===
@@ -871,12 +896,12 @@ export function createBootHouse(gradientMap) {
871896
 
872897
   // Create grass patches around the boot
873898
   const grassPositions = [
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 }
899
+    { x: -0.7, z: 0.4, count: 8 },
900
+    { x: -0.7, z: -0.4, count: 6 },
901
+    { x: 0.65, z: 0.4, count: 7 },
902
+    { x: 0.65, z: -0.4, count: 5 },
903
+    { x: -0.1, z: -0.55, count: 6 },
904
+    { x: -0.1, z: 0.55, count: 5 }
880905
   ]
881906
 
882907
   for (const patch of grassPositions) {
@@ -968,11 +993,11 @@ export function createBootHouse(gradientMap) {
968993
     sprite.add(pupilR)
969994
 
970995
     // Animation data
971
-    sprite.userData.orbitRadius = 0.6 + Math.random() * 0.25
996
+    sprite.userData.orbitRadius = 0.55 + Math.random() * 0.2
972997
     sprite.userData.orbitSpeed = 0.8 + Math.random() * 0.6
973998
     sprite.userData.orbitPhase = (i / 4) * Math.PI * 2
974999
     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
9761001
     sprite.userData.orbitCenterZ = 0
9771002
 
9781003
     // Initial position