Recent Changes - Search:

Blender Technical Director?

pmwiki.org

edit SideBar

BTD /

Lab3

BTD/Modul 3: Übungen

Aufgabe 1: Rigging QC Script

  • Prüfen eines Rigs auf Fehler: unapplied Transforms, fehlende Vertex-Gruppen, Constraint-Loops.
  • Script soll Probleme erkennen und melden.

Aufgabe 2: Automatisiertes Bone-Setup

  • Script zum automatischen Erzeugen eines Grundskeletts.
  • Bones korrekt benennen und hierarchisch organisieren.

Aufgabe 3: Custom Control Generator

  • Kontrollobjekte erzeugen und Constraints anlegen.
  • Bonus: UI-Slider im Properties-Panel implementieren.

Material: Full-Body Motion Capture

Demo: https://btd.kalisz.co/demos/full_body_motion_capture.html

HTML/Javascript-Code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MediaPipe Full Body Debug</title>

<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/pose/pose.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/face_mesh.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js"></script>

<style>
  body { margin:0; overflow:hidden; background:black; }
  video, canvas {
    position:absolute;
    top:0;
    left:0;
  }
</style>
</head>

<body>

<video id="video" width="640" height="480" autoplay muted playsinline></video>
<canvas id="canvas" width="640" height="480"></canvas>

<script>
const video = document.getElementById("video");
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

let faceLandmarks = null;
let poseLandmarks = null;
let handLandmarks = null;

// ---------- Face ----------
const faceMesh = new FaceMesh({
  locateFile: f => `https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${f}`
});
faceMesh.setOptions({
  maxNumFaces: 1,
  refineLandmarks: true
});
faceMesh.onResults(r => {
  faceLandmarks = r.multiFaceLandmarks?.[0] || null;
});

// ---------- Pose ----------
const pose = new Pose({
  locateFile: f => `https://cdn.jsdelivr.net/npm/@mediapipe/pose/${f}`
});
pose.setOptions({
  modelComplexity: 1,
  smoothLandmarks: true
});
pose.onResults(r => {
  poseLandmarks = r.poseLandmarks || null;
});

// ---------- Hands ----------
const hands = new Hands({
  locateFile: f => `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${f}`
});
hands.setOptions({
  maxNumHands: 2,
  modelComplexity: 1
});
hands.onResults(r => {
  handLandmarks = r.multiHandLandmarks || null;
});

// ---------- Draw ----------
function drawLandmarks(points, color, radius) {
  ctx.fillStyle = color;
  points.forEach(p => {
    ctx.beginPath();
    ctx.arc(p.x * canvas.width, p.y * canvas.height, radius, 0, Math.PI * 2);
    ctx.fill();
  });
}

async function onFrame() {
  await faceMesh.send({image: video});
  await pose.send({image: video});
  await hands.send({image: video});

  ctx.clearRect(0,0,canvas.width,canvas.height);

  if (faceLandmarks) drawLandmarks(faceLandmarks, "red", 1.2);
  if (poseLandmarks) drawLandmarks(poseLandmarks, "cyan", 3);
  if (handLandmarks) {
    handLandmarks.forEach(h => drawLandmarks(h, "lime", 2));
  }
}

// ---------- Camera ----------
const camera = new Camera(video, {
  onFrame,
  width: 640,
  height: 480
});
camera.start();
</script>

</body>
</html>

Edit - History - Print - Recent Changes - Search
Page last modified on January 03, 2026, at 05:33 PM UTC