zeroed-some/dougk / cf7cd1e

Browse files

fix some ollie things

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
cf7cd1e209773abf25c8b10f2e17aadf407fa00f
Parents
806496f
Tree
0bb5836

1 changed file

StatusFile+-
M src/renderers/three/octopus.js 89 49
src/renderers/three/octopus.jsmodified
@@ -89,33 +89,36 @@ export function createOllie(scene, gradientMap) {
8989
   rightShine.position.set(0.35, 0.4, -0.38)
9090
   group.add(rightShine)
9191
 
92
-  // Create 8 tentacles
92
+  // Create 8 tentacles - splayed outward evenly around the body like \./
9393
   const tentacles = []
9494
   const tentacleGroup = new THREE.Group()
95
-  tentacleGroup.position.y = -0.3
95
+  tentacleGroup.position.y = -0.05 // Raised up so tentacles emerge above water
9696
 
9797
   for (let i = 0; i < 8; i++) {
9898
     const angle = (i / 8) * Math.PI * 2
9999
     const tentacle = createTentacle(bodyMaterial, suckerMaterial, gradientMap)
100
+
101
+    // Position at edge of lower body
100102
     tentacle.position.x = Math.cos(angle) * 0.35
101103
     tentacle.position.z = Math.sin(angle) * 0.35
102
-    tentacle.rotation.y = -angle + Math.PI / 2
103
-    // Splay outward slightly
104
-    tentacle.rotation.z = 0.3
104
+
105
+    // Simply rotate around Y to spread evenly - tentacles extend in +Z and curve up
106
+    tentacle.rotation.y = angle
107
+
105108
     tentacles.push(tentacle)
106109
     tentacleGroup.add(tentacle)
107110
   }
108111
 
109112
   group.add(tentacleGroup)
110113
 
111
-  // Magnifying glass - attached to front-right tentacle (index 1)
114
+  // Magnifying glass - will be attached to front tentacle (index 0)
112115
   const magGlassGroup = new THREE.Group()
113116
 
114
-  // Handle
115
-  const handleGeom = new THREE.CylinderGeometry(0.02, 0.025, 0.3, 6)
117
+  // Handle - longer and thicker for visibility
118
+  const handleGeom = new THREE.CylinderGeometry(0.03, 0.035, 0.25, 6)
116119
   const handle = new THREE.Mesh(handleGeom, glassRimMaterial)
117120
   handle.rotation.z = Math.PI / 2
118
-  handle.position.x = -0.15
121
+  handle.position.x = -0.18
119122
   magGlassGroup.add(handle)
120123
 
121124
   // Rim
@@ -129,10 +132,30 @@ export function createOllie(scene, gradientMap) {
129132
   lens.position.z = 0.01
130133
   magGlassGroup.add(lens)
131134
 
132
-  // Position magnifying glass at end of front-right tentacle
133
-  magGlassGroup.position.set(0.9, -0.5, -0.3)
134
-  magGlassGroup.rotation.y = -0.5
135
-  group.add(magGlassGroup)
135
+  // Back of lens for visibility from other side
136
+  const lensBack = new THREE.Mesh(lensGeom, glassMaterial)
137
+  lensBack.position.z = -0.01
138
+  lensBack.rotation.y = Math.PI
139
+  magGlassGroup.add(lensBack)
140
+
141
+  // Attach magnifying glass to the TIP of tentacle 2 (side tentacle, away from body)
142
+  // Navigate to the last joint of that tentacle
143
+  let magTentacle = tentacles[2]
144
+  let lastJoint = magTentacle.children[0] // First joint
145
+  while (lastJoint.children.length > 1 || (lastJoint.children[0] && lastJoint.children[0].type === 'Group')) {
146
+    // Find the child that is a Group (the next joint)
147
+    const nextJoint = lastJoint.children.find(c => c.type === 'Group')
148
+    if (nextJoint) {
149
+      lastJoint = nextJoint
150
+    } else {
151
+      break
152
+    }
153
+  }
154
+
155
+  // Position at the tip of the last segment
156
+  magGlassGroup.position.set(0, 0.05, 0.15)
157
+  magGlassGroup.rotation.x = 0.5 // Angle it forward/up for visibility
158
+  lastJoint.add(magGlassGroup)
136159
 
137160
   // Ollie starts hidden below the water
138161
   group.position.y = -3
@@ -150,42 +173,54 @@ export function createOllie(scene, gradientMap) {
150173
   }
151174
 
152175
   function createTentacle(bodyMat, suckerMat, gradient) {
176
+    // Build tentacle as a chain of segments, each one a child of the previous
177
+    // This creates a smooth curve by rotating each joint
153178
     const tentacleObj = new THREE.Group()
154179
 
155
-    // 3 segments, getting smaller
156
-    const segments = [
157
-      { radius: 0.08, length: 0.35 },
158
-      { radius: 0.06, length: 0.3 },
159
-      { radius: 0.04, length: 0.25 }
160
-    ]
180
+    const numSegments = 5
181
+    let currentParent = tentacleObj
182
+
183
+    for (let idx = 0; idx < numSegments; idx++) {
184
+      const radius = 0.065 - idx * 0.01
185
+      const length = 0.18 - idx * 0.015
186
+
187
+      // Create a joint group for this segment
188
+      const joint = new THREE.Group()
189
+
190
+      // Position joint at end of parent (except first one at origin)
191
+      if (idx > 0) {
192
+        joint.position.z = 0.16 - (idx - 1) * 0.012 // Length of previous segment
193
+      }
194
+
195
+      // Rotate joint to curve upward - more curve toward the tip
196
+      joint.rotation.x = -0.28 - idx * 0.08
197
+
198
+      // Create the segment mesh
199
+      const segGeom = new THREE.CylinderGeometry(radius * 0.7, radius, length, 6)
200
+      segGeom.rotateX(Math.PI / 2) // Lay along Z axis
201
+      segGeom.translate(0, 0, length / 2) // Move so base is at origin
161202
 
162
-    let yOffset = 0
163
-    segments.forEach((seg, idx) => {
164
-      const segGeom = new THREE.CylinderGeometry(seg.radius * 0.7, seg.radius, seg.length, 6)
165203
       const segMesh = new THREE.Mesh(segGeom, bodyMat)
166
-      segMesh.position.y = yOffset - seg.length / 2
167
-      tentacleObj.add(segMesh)
168
-
169
-      // Add suckers on underside (only first two segments)
170
-      if (idx < 2) {
171
-        for (let s = 0; s < 2; s++) {
172
-          const suckerGeom = new THREE.SphereGeometry(0.015, 4, 4)
173
-          const sucker = new THREE.Mesh(suckerGeom, suckerMat)
174
-          sucker.position.set(-seg.radius * 0.8, yOffset - seg.length * 0.3 - s * 0.12, 0)
175
-          sucker.scale.set(1, 0.5, 1)
176
-          tentacleObj.add(sucker)
177
-        }
204
+      joint.add(segMesh)
205
+
206
+      // Add suckers on underside
207
+      if (idx < 4) {
208
+        const suckerGeom = new THREE.SphereGeometry(0.015, 4, 4)
209
+        const sucker = new THREE.Mesh(suckerGeom, suckerMat)
210
+        sucker.position.set(0, -radius * 0.85, length * 0.5)
211
+        sucker.scale.set(1, 0.5, 1)
212
+        joint.add(sucker)
178213
       }
179214
 
180
-      yOffset -= seg.length
181
-    })
215
+      currentParent.add(joint)
216
+      currentParent = joint
217
+    }
182218
 
183
-    // Curly tip
184
-    const tipGeom = new THREE.SphereGeometry(0.03, 6, 4)
185
-    tipGeom.scale(1, 1.5, 1)
219
+    // Curly tip at the end
220
+    const tipGeom = new THREE.SphereGeometry(0.02, 6, 4)
186221
     const tip = new THREE.Mesh(tipGeom, bodyMat)
187
-    tip.position.y = yOffset - 0.03
188
-    tentacleObj.add(tip)
222
+    tip.position.z = 0.12
223
+    currentParent.add(tip)
189224
 
190225
     return tentacleObj
191226
   }
@@ -228,15 +263,17 @@ export function createOllie(scene, gradientMap) {
228263
     // Animate tentacles (always, when visible)
229264
     if (group.visible) {
230265
       tentacles.forEach((t, i) => {
266
+        const baseAngle = (i / 8) * Math.PI * 2
231267
         const phase = i * (Math.PI / 4)
232
-        // Wave motion
233
-        t.rotation.x = 0.3 + Math.sin(elapsed * 2 + phase) * 0.25
234
-        t.rotation.z = 0.3 + Math.cos(elapsed * 1.5 + phase) * 0.15
268
+        // Gentle swaying - each tentacle waves side to side
269
+        t.rotation.y = baseAngle + Math.sin(elapsed * 1.5 + phase) * 0.12
270
+        // Slight up/down bob
271
+        t.rotation.x = Math.sin(elapsed * 2 + phase) * 0.08
235272
       })
236273
 
237
-      // Magnifying glass sway
238
-      magGlassGroup.rotation.z = Math.sin(elapsed * 3) * 0.15
239
-      magGlassGroup.rotation.x = Math.sin(elapsed * 2.5) * 0.1
274
+      // Magnifying glass gets a little extra wobble for curious inspection look
275
+      magGlassGroup.rotation.z = Math.sin(elapsed * 3) * 0.1
276
+      magGlassGroup.rotation.y = Math.sin(elapsed * 2) * 0.15
240277
     }
241278
 
242279
     switch (state.mode) {
@@ -315,10 +352,13 @@ export function createOllie(scene, gradientMap) {
315352
         const easeIn = Math.pow(submergeProgress, 2)
316353
         group.position.y = 0.2 - easeIn * 2.5
317354
 
318
-        // Tentacles curl inward as submerging
355
+        // Tentacles curl as submerging
319356
         tentacles.forEach((t, i) => {
357
+          const baseAngle = (i / 8) * Math.PI * 2
320358
           const phase = i * (Math.PI / 4)
321
-          t.rotation.x = 0.3 + easeIn * 0.5 + Math.sin(elapsed * 2 + phase) * 0.15
359
+          t.rotation.y = baseAngle + Math.sin(elapsed * 2 + phase) * 0.05
360
+          // Curl downward as sinking
361
+          t.rotation.x = easeIn * 0.4 + Math.sin(elapsed * 2 + phase) * 0.05
322362
         })
323363
 
324364
         // Add ripples as submerging