TouchDesigner 손 제어 3D 글리치 큐브 (Claude Code)
Wikiprompt, 무료 프롬프트 백과사전에서
TouchDesigner 손 제어 3D 글리치 큐브 (Claude Code) 클로드 코드 프롬프트로, 실시간 MediaPipe 손 추적에 의해 구동되는 3D 글리치 큐브용 TouchDesigner Python(DAT) 스크립트를 생성하며, 제스처별로 위치, 회전, 스케일, 왜곡 및 색상을 제어합니다.
관련 미디어
프롬프트 내용저장
🌐
# TouchDesigner Python DAT Script - 3D Glitchy Cube with Hand Controls
# Requires: MediaPipe plugin, Python scripting, and a 3D render TOP
import TD
import math
import random
# ============================================================
# TUNABLE PARAMETERS - Adjust these values to fine-tune behavior
# ============================================================
# Movement
MOVE_SPEED = 0.8 # How fast the cube follows hand midpoint
SMOOTHING = 0.15 # Low-pass filter for position (0-1)
# Rotation
ROTATION_SENSITIVITY = 2.0 # Degrees per degree of hand angle change
ROTATION_SMOOTHING = 0.1 # Smoothing for rotation
# Scale
SCALE_MIN = 0.3 # Minimum cube scale
SCALE_MAX = 3.0 # Maximum cube scale
SCALE_SENSITIVITY = 0.5 # Scale sensitivity to hand distance
# Glitch / Noise
NOISE_BASE = 0.05 # Base noise level
NOISE_PINCH_MULT = 2.0 # How much left pinch amplifies noise
NOISE_MAX = 0.8 # Maximum noise level
# Color Cycling
COLOR_CYCLE_SPEED = 0.5 # Speed of color cycling per right pinch
COLOR_PALETTE = [ # Color palette for cycling
(1.0, 0.0, 0.0), # Red
(0.0, 1.0, 0.0), # Green
(0.0, 0.0, 1.0), # Blue
(1.0, 1.0, 0.0), # Yellow
(0.0, 1.0, 1.0), # Cyan
(1.0, 0.0, 1.0), # Magenta
(1.0, 1.0, 1.0), # White
]
# Glitch Flash
FLASH_THRESHOLD = 0.5 # Speed threshold for triggering flash
FLASH_DURATION = 0.3 # Flash duration in seconds
FLASH_INTENSITY = 0.8 # Flash intensity (0-1)
# Freeze / Screenshot
FREEZE_DISTANCE = 0.2 # Hand distance threshold for "fist" detection
FREEZE_DURATION = 1.0 # How long fists must be held to trigger freeze
# ============================================================
# STATE VARIABLES - Do not modify unless you know what you're doing
# ============================================================
# Position
target_pos = [0.0, 0.0, 0.0]
current_pos = [0.0, 0.0, 0.0]
# Rotation
target_rot = [0.0, 0.0]
current_rot = [0.0, 0.0]
# Scale
target_scale = 1.0
current_scale = 1.0
# Glitch
noise_level = NOISE_BASE
target_noise = NOISE_BASE
# Color
color_index = 0
color_cycle_active = False
last_color_change = 0.0
# Flash
flash_active = False
flash_start_time = 0.0
last_hand_speed = 0.0
# Freeze
freeze_start_time = 0.0
freeze_active = False
freeze_triggered = False
# Previous hand positions for speed calculation
prev_hand_pos = None
prev_time = 0.0
# ============================================================
# HELPER FUNCTIONS
# ============================================================
def lerp(a, b, t):
"""Linear interpolation between a and b"""
return a + (b - a) * t
def smooth(current, target, smoothing):
"""Exponential smoothing filter"""
return lerp(current, target, smoothing)
def get_hand_midpoint(hand1, hand2):
"""Calculate midpoint between two hands"""
if hand1 is None or hand2 is None:
return None
return [
(hand1[0] + hand2[0]) / 2.0,
(hand1[1] + hand2[1]) / 2.0,
(hand1[2] + hand2[2]) / 2.0
]
def get_hand_distance(hand1, hand2):
"""Calculate Euclidean distance between two hands"""
if hand1 is None or hand2 is None:
return 0.0
dx = hand1[0] - hand2[0]
dy = hand1[1] - hand2[1]
dz = hand1[2] - hand2[2]
return math.sqrt(dx*dx + dy*dy + dz*dz)
def get_hand_angle(hand1, hand2):
"""Calculate angle between hands for rotation"""
if hand1 is None or hand2 is None:
return [0.0, 0.0]
dx = hand2[0] - hand1[0]
dy = hand2[1] - hand1[1]
dz = hand2[2] - hand1[2]
# X rotation (pitch) - based on vertical angle
rot_x = math.degrees(math.atan2(dy, math.sqrt(dx*dx + dz*dz)))
# Y rotation (yaw) - based on horizontal angle
rot_y = math.degrees(math.atan2(dx, dz))
return [rot_x, rot_y]
def is_pinch(hand):
"""Detect pinch gesture (thumb and index finger close together)"""
if hand is None:
return False
# Assuming hand has landmarks 4 (thumb tip) and 8 (index tip)
thumb = hand[4]
index = hand[8]
distance = math.sqrt(
(thumb[0] - index[0])**2 +
(thumb[1] - index[1])**2 +
(thumb[2] - index[2])**2
)
return distance < 0.05 # Threshold for pinch detection
def is_fist(hand):
"""Detect fist gesture (all fingers curled)"""
if hand is None:
return False
# Check if all fingertips are close to palm center
palm_center = hand[0] # Wrist as approximate palm center
fingertips = [hand[4], hand[8], hand[12], hand[16], hand[20]]
avg_distance = 0.0
for tip in fingertips:
avg_distance += math.sqrt(
(tip[0] - palm_center[0])**2 +
(tip[1] - palm_center[1])**2 +
(tip[2] - palm_center[2])**2
)
avg_distance /= 5.0
return avg_distance < 0.1 # Threshold for fist detection
# ============================================================
# MAIN SCRIPT
# ============================================================
def onFrame():
global target_pos, current_pos, target_rot, current_rot
global target_scale, current_scale, noise_level, target_noise
global color_index, color_cycle_active, last_color_change
global flash_active, flash_start_time, last_hand_speed
global freeze_start_time, freeze_active, freeze_triggered
global prev_hand_pos, prev_time
# Get current time
current_time = TD.time()
# Get hand data from MediaPipe
hand1 = TD.mediapipe.getHand(0) # Left hand
hand2 = TD.mediapipe.getHand(1) # Right hand
# Skip if no hands detected
if hand1 is None and hand2 is None:
return
# ============================================================
# 1. POSITION CONTROL - Midpoint between hands
# ============================================================
midpoint = get_hand_midpoint(hand1, hand2)
if midpoint is not None:
# Map hand coordinates to screen space (adjust as needed)
target_pos[0] = midpoint[0] * 2.0 - 1.0 # X: -1 to 1
target_pos[1] = midpoint[1] * 2.0 - 1.0 # Y: -1 to 1
target_pos[2] = midpoint[2] * 2.0 - 1.0 # Z: -1 to 1
# Smooth position
current_pos[0] = smooth(current_pos[0], target_pos[0], SMOOTHING)
current_pos[1] = smooth(current_pos[1], target_pos[1], SMOOTHING)
current_pos[2] = smooth(current_pos[2], target_pos[2], SMOOTHING)
# ============================================================
# 2. ROTATION CONTROL - Angle between hands
# ============================================================
if hand1 is not None and hand2 is not None:
angle = get_hand_angle(hand1, hand2)
target_rot[0] = angle[0] * ROTATION_SENSITIVITY
target_rot[1] = angle[1] * ROTATION_SENSITIVITY
# Smooth rotation
current_rot[0] = smooth(current_rot[0], target_rot[0], ROTATION_SMOOTHING)
current_rot[1] = smooth(current_rot[1], target_rot[1], ROTATION_SMOOTHING)
# ============================================================
# 3. SCALE CONTROL - Distance between hands
# ============================================================
if hand1 is not None and hand2 is not None:
distance = get_hand_distance(hand1, hand2)
# Map distance to scale range
target_scale = SCALE_MIN + (distance * SCALE_SENSITIVITY)
target_scale = max(SCALE_MIN, min(SCALE_MAX, target_scale))
current_scale = smooth(current_scale, target_scale, SMOOTHING)
# ============================================================
# 4. NOISE CONTROL - Left hand pinch
# ============================================================
if hand1 is not None and is_pinch(hand1):
target_noise = NOISE_BASE * NOISE_PINCH_MULT
else:
target_noise = NOISE_BASE
target_noise = min(NOISE_MAX, target_noise)
noise_level = smooth(noise_level, target_noise, SMOOTHING)
# ============================================================
# 5. COLOR CYCLING - Right hand pinch
# ============================================================
if hand2 is not None and is_pinch(hand2):
if not color_cycle_active:
color_cycle_active = True
color_index = (color_index + 1) % len(COLOR_PALETTE)
last_color_change = current_time
else:
color_cycle_active = False
# ============================================================
# 6. GLITCH FLASH - Fast movement detection
# ============================================================
if hand1 is not None and hand2 is not None:
midpoint_now = get_hand_midpoint(hand1, hand2)
if prev_hand_pos is not None:
dt = current_time - prev_time
if dt > 0:
speed = math.sqrt(
(midpoint_now[0] - prev_hand_pos[0])**2 +
(midpoint_now[1] - prev_hand_pos[1])**2 +
(midpoint_now[2] - prev_hand_pos[2])**2
) / dt
if speed > FLASH_THRESHOLD and not flash_active:
flash_active = True
flash_start_time = current_time
last_hand_speed = speed
prev_hand_pos = midpoint_now
prev_time = current_time
# Flash duration check
if flash_active and (current_time - flash_start_time) > FLASH_DURATION:
flash_active = False
# ============================================================
# 7. FREEZE FRAME - Both fists
# ============================================================
both_fists = (hand1 is not None and hand2 is not None and
is_fist(hand1) and is_fist(hand2))
if both_fists:
if not freeze_active:
freeze_start_time = current_time
freeze_active = True
elif (current_time - freeze_start_time) > FREEZE_DURATION and not freeze_triggered:
# Trigger screenshot
TD.screenshot()
freeze_triggered = True
else:
freeze_active = False
freeze_triggered = False
# ============================================================
# APPLY VALUES TO RENDER TOP
# ============================================================
# Position
TD.op('Transform1').par.tx = current_pos[0] * MOVE_SPEED
TD.op('Transform1').par.ty = current_pos[1] * MOVE_SPEED
TD.op('Transform1').par.tz = current_pos[2] * MOVE_SPEED
# Rotation
TD.op('Transform1').par.rx = current_rot[0]
TD.op('Transform1').par.ry = current_rot[1]
# Scale
TD.op('Transform1').par.sx = current_scale
TD.op('Transform1').par.sy = current_scale
TD.op('Transform1').par.sz = current_scale
# Noise / Glitch
TD.op('Glitch1').par.amount = noise_level
# Color
color = COLOR_PALETTE[color_index]
TD.op('Color1').par.r = color[0]
TD.op('Color1').par.g = color[1]
TD.op('Color1').par.b = color[2]
# Flash effect
if flash_active:
flash_intensity = FLASH_INTENSITY * (1.0 - (current_time - flash_start_time) / FLASH_DURATION)
TD.op('Glitch1').par.amount = noise_level + flash_intensity
TD.op('Color1').par.brightness = 1.0 + flash_intensity
else:
TD.op('Color1').par.brightness = 1.0
# Register the main function
TD.registerCallback(onFrame)
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개