feat: Redesign TurtleModel with enhanced shell, head, and leg details; add LED indicators and ambient glow
This commit is contained in:
@@ -154,78 +154,194 @@ function TurtleModel({ turtle, isSelected, onClick }) {
|
|||||||
return (
|
return (
|
||||||
<group ref={groupRef} position={[position.x, position.y, position.z]} rotation={rotation} onClick={onClick}>
|
<group ref={groupRef} position={[position.x, position.y, position.z]} rotation={rotation} onClick={onClick}>
|
||||||
<group>
|
<group>
|
||||||
{/* Shell (main body) */}
|
{/* Main shell body - rounded edges */}
|
||||||
<mesh position={[0, 0.2, 0]}>
|
<mesh position={[0, 0.2, 0]} castShadow>
|
||||||
<boxGeometry args={[0.8, 0.5, 0.9]} />
|
<boxGeometry args={[0.9, 0.6, 1.0]} />
|
||||||
<meshStandardMaterial
|
<meshStandardMaterial
|
||||||
color={color}
|
color={color}
|
||||||
emissive={color}
|
emissive={color}
|
||||||
emissiveIntensity={isSelected ? 0.4 : 0.2}
|
emissiveIntensity={isSelected ? 0.5 : 0.25}
|
||||||
roughness={0.4}
|
roughness={0.3}
|
||||||
|
metalness={0.2}
|
||||||
/>
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
{/* Head */}
|
{/* Shell pattern - hexagonal plates */}
|
||||||
<mesh position={[0, 0.15, 0.55]}>
|
<mesh position={[0, 0.5, 0]}>
|
||||||
<boxGeometry args={[0.5, 0.35, 0.3]} />
|
<boxGeometry args={[0.5, 0.05, 0.6]} />
|
||||||
<meshStandardMaterial color={color} roughness={0.3} />
|
<meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[-0.25, 0.5, 0.3]}>
|
||||||
|
<boxGeometry args={[0.3, 0.05, 0.3]} />
|
||||||
|
<meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0.25, 0.5, 0.3]}>
|
||||||
|
<boxGeometry args={[0.3, 0.05, 0.3]} />
|
||||||
|
<meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[-0.25, 0.5, -0.3]}>
|
||||||
|
<boxGeometry args={[0.3, 0.05, 0.3]} />
|
||||||
|
<meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0.25, 0.5, -0.3]}>
|
||||||
|
<boxGeometry args={[0.3, 0.05, 0.3]} />
|
||||||
|
<meshStandardMaterial color="#333" roughness={0.4} metalness={0.6} />
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
{/* Eyes */}
|
{/* Head with visor */}
|
||||||
<mesh position={[-0.12, 0.2, 0.7]}>
|
<mesh position={[0, 0.15, 0.6]} castShadow>
|
||||||
<boxGeometry args={[0.1, 0.1, 0.05]} />
|
<boxGeometry args={[0.55, 0.4, 0.35]} />
|
||||||
<meshStandardMaterial color="#ffffff" emissive="#ffff00" emissiveIntensity={0.5} />
|
<meshStandardMaterial color={color} roughness={0.3} metalness={0.1} />
|
||||||
</mesh>
|
|
||||||
<mesh position={[0.12, 0.2, 0.7]}>
|
|
||||||
<boxGeometry args={[0.1, 0.1, 0.05]} />
|
|
||||||
<meshStandardMaterial color="#ffffff" emissive="#ffff00" emissiveIntensity={0.5} />
|
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
{/* Legs */}
|
{/* Visor/Face plate */}
|
||||||
<mesh position={[-0.3, -0.15, 0.25]}>
|
<mesh position={[0, 0.2, 0.78]}>
|
||||||
<boxGeometry args={[0.2, 0.2, 0.2]} />
|
<boxGeometry args={[0.45, 0.25, 0.02]} />
|
||||||
<meshStandardMaterial color="#666" />
|
<meshStandardMaterial
|
||||||
</mesh>
|
color="#1a1a1a"
|
||||||
<mesh position={[0.3, -0.15, 0.25]}>
|
emissive="#111"
|
||||||
<boxGeometry args={[0.2, 0.2, 0.2]} />
|
roughness={0.1}
|
||||||
<meshStandardMaterial color="#666" />
|
metalness={0.9}
|
||||||
</mesh>
|
/>
|
||||||
<mesh position={[-0.3, -0.15, -0.25]}>
|
|
||||||
<boxGeometry args={[0.2, 0.2, 0.2]} />
|
|
||||||
<meshStandardMaterial color="#666" />
|
|
||||||
</mesh>
|
|
||||||
<mesh position={[0.3, -0.15, -0.25]}>
|
|
||||||
<boxGeometry args={[0.2, 0.2, 0.2]} />
|
|
||||||
<meshStandardMaterial color="#666" />
|
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
{/* Tail */}
|
{/* Eyes/LED indicators */}
|
||||||
<mesh position={[0, 0.1, -0.55]}>
|
<mesh position={[-0.13, 0.22, 0.79]}>
|
||||||
<boxGeometry args={[0.15, 0.15, 0.2]} />
|
<boxGeometry args={[0.08, 0.08, 0.01]} />
|
||||||
<meshStandardMaterial color={color} />
|
<meshStandardMaterial
|
||||||
|
color="#00ff00"
|
||||||
|
emissive={mode === 'mining' ? "#00ff00" : mode === 'returning' ? "#ffaa00" : "#00aaff"}
|
||||||
|
emissiveIntensity={1.5}
|
||||||
|
toneMapped={false}
|
||||||
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
|
<mesh position={[0.13, 0.22, 0.79]}>
|
||||||
|
<boxGeometry args={[0.08, 0.08, 0.01]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
color="#00ff00"
|
||||||
|
emissive={mode === 'mining' ? "#00ff00" : mode === 'returning' ? "#ffaa00" : "#00aaff"}
|
||||||
|
emissiveIntensity={1.5}
|
||||||
|
toneMapped={false}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
|
||||||
|
{/* LED glow */}
|
||||||
|
<pointLight
|
||||||
|
position={[0, 0.2, 0.85]}
|
||||||
|
color={mode === 'mining' ? "#00ff00" : mode === 'returning' ? "#ffaa00" : "#00aaff"}
|
||||||
|
intensity={0.5}
|
||||||
|
distance={2}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Legs - more mechanical looking */}
|
||||||
|
<mesh position={[-0.32, -0.15, 0.3]} castShadow>
|
||||||
|
<boxGeometry args={[0.18, 0.25, 0.18]} />
|
||||||
|
<meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0.32, -0.15, 0.3]} castShadow>
|
||||||
|
<boxGeometry args={[0.18, 0.25, 0.18]} />
|
||||||
|
<meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[-0.32, -0.15, -0.3]} castShadow>
|
||||||
|
<boxGeometry args={[0.18, 0.25, 0.18]} />
|
||||||
|
<meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0.32, -0.15, -0.3]} castShadow>
|
||||||
|
<boxGeometry args={[0.18, 0.25, 0.18]} />
|
||||||
|
<meshStandardMaterial color="#555" roughness={0.4} metalness={0.7} />
|
||||||
|
</mesh>
|
||||||
|
|
||||||
|
{/* Feet */}
|
||||||
|
<mesh position={[-0.32, -0.35, 0.3]}>
|
||||||
|
<boxGeometry args={[0.22, 0.08, 0.25]} />
|
||||||
|
<meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0.32, -0.35, 0.3]}>
|
||||||
|
<boxGeometry args={[0.22, 0.08, 0.25]} />
|
||||||
|
<meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[-0.32, -0.35, -0.3]}>
|
||||||
|
<boxGeometry args={[0.22, 0.08, 0.25]} />
|
||||||
|
<meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0.32, -0.35, -0.3]}>
|
||||||
|
<boxGeometry args={[0.22, 0.08, 0.25]} />
|
||||||
|
<meshStandardMaterial color="#444" roughness={0.5} metalness={0.6} />
|
||||||
|
</mesh>
|
||||||
|
|
||||||
|
{/* Tool/Mining arm - only show when mining */}
|
||||||
|
{mode === 'mining' && (
|
||||||
|
<>
|
||||||
|
<mesh position={[0, 0.1, 0.7]}>
|
||||||
|
<boxGeometry args={[0.1, 0.1, 0.3]} />
|
||||||
|
<meshStandardMaterial color="#888" metalness={0.8} roughness={0.2} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0, 0.1, 0.9]}>
|
||||||
|
<boxGeometry args={[0.15, 0.15, 0.1]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
color="#ff6b00"
|
||||||
|
emissive="#ff6b00"
|
||||||
|
emissiveIntensity={0.5}
|
||||||
|
metalness={0.7}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Antenna */}
|
||||||
|
<mesh position={[0, 0.5, -0.2]}>
|
||||||
|
<cylinderGeometry args={[0.02, 0.02, 0.4, 8]} />
|
||||||
|
<meshStandardMaterial color="#666" metalness={0.8} />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={[0, 0.72, -0.2]}>
|
||||||
|
<sphereGeometry args={[0.06, 8, 8]} />
|
||||||
|
<meshStandardMaterial
|
||||||
|
color="#ff0000"
|
||||||
|
emissive="#ff0000"
|
||||||
|
emissiveIntensity={0.8}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
|
||||||
|
{/* Ambient glow around turtle */}
|
||||||
|
<pointLight
|
||||||
|
position={[0, 0.2, 0]}
|
||||||
|
color={color}
|
||||||
|
intensity={isSelected ? 1 : 0.3}
|
||||||
|
distance={3}
|
||||||
|
/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
{/* Selection indicator */}
|
{/* Selection indicator */}
|
||||||
{isSelected && (
|
{isSelected && (
|
||||||
<>
|
<>
|
||||||
<mesh position={[0, 1.2, 0]}>
|
<mesh position={[0, 1.3, 0]}>
|
||||||
<coneGeometry args={[0.3, 0.5, 4]} />
|
<coneGeometry args={[0.25, 0.4, 4]} />
|
||||||
<meshStandardMaterial color="#ffffff" emissive="#ffffff" emissiveIntensity={0.8} />
|
<meshStandardMaterial
|
||||||
|
color="#ffffff"
|
||||||
|
emissive="#ffffff"
|
||||||
|
emissiveIntensity={1.2}
|
||||||
|
transparent
|
||||||
|
opacity={0.8}
|
||||||
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
{/* Selection ring */}
|
{/* Animated selection ring */}
|
||||||
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
|
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.4, 0]}>
|
||||||
<ringGeometry args={[1, 1.2, 32]} />
|
<ringGeometry args={[1.1, 1.3, 64]} />
|
||||||
<meshBasicMaterial color="#ffffff" side={THREE.DoubleSide} transparent opacity={0.5} />
|
<meshBasicMaterial
|
||||||
|
color={color}
|
||||||
|
side={THREE.DoubleSide}
|
||||||
|
transparent
|
||||||
|
opacity={0.6}
|
||||||
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Turtle ID label */}
|
{/* Turtle ID label */}
|
||||||
<Text
|
<Text
|
||||||
position={[0, 1.5, 0]}
|
position={[0, 1.6, 0]}
|
||||||
fontSize={0.4}
|
fontSize={0.35}
|
||||||
color="white"
|
color="white"
|
||||||
anchorX="center"
|
anchorX="center"
|
||||||
anchorY="middle"
|
anchorY="middle"
|
||||||
|
|||||||
Reference in New Issue
Block a user