HTML5巨乳の作り方

あんまり新しいこともやってないんだけど、一応HTML5巨乳の作り方メモ。

主だった部分はこちら。

http://html5kyonyu.appspot.com/js/html5_kyonyu.js

基本的な流れは次のような感じです。

  1. カメラから映像を読み取ってcanvasに表示(getUserMedia)
  2. canvasの内容から顔の位置と大きさを求めて、胸の位置と大きさを決定(ccv.js + face.js)
  3. 胸部のテクスチャに使用するため、胸の位置に当たる画像を切り取って別のcanvasに表示
  4. 画面を構成(three.js)
    1. 背景としてカメラから取得した画像全体を使用
    2. 平面上に胸の位置と大きさを元に半球を二つ配置
      • 平面のテクスチャとしてカメラの映像を取り込んだcanvasを使用
      • 半球のテクスチャとして胸部を切り取ったcanvasを使用

順にコードを見ていくと

カメラから映像を読み取ってcanvasに表示

    video = document.getElementById('video');
    navigator.webkitGetUserMedia(
      {video:true},
      function(stream) {video.src = window.webkitURL.createObjectURL(stream)}, 
      function(error) {console.log(error)}
    );
    // ... snip ...
    bgContext.drawImage(video, 0, 0);

まぁ普通に。

canvasの内容から顔の位置と大きさを求めて、胸の位置と大きさを決定

  function detectFace() {
    var detectedComp;
    var comp = ccv.detect({
      //canvas:ccv.grayscale(bgCanvas),
      canvas:bgCanvas,
      cascade:cascade,
      interval:5,
      min_neighbors:1
    });
    for (var i = 0; i < comp.length; i++) {
      if (VIDEO_WIDTH / 5 < comp[i].width) {
        detectedComp = comp[i];
        break;
      }
    }
    return detectedComp;
  }
  // ...snip...
    if (isDetectingFace) detected = detectFace() || detected;
    if (detected) {
      var boobSize = detected.width * 0.9;
      var center = new THREE.Vector3(detected.x, detected.y + detected.height * 2.2, 0);

顔検出も普通にccv.detectするだけ。ただ検出された顔があまりに小さい場合は無視。で、胸の位置は検出された顔の位置とサイズから適当に求めると。

胸部のテクスチャに使用するため、胸の位置に当たる画像を切り取って別のcanvasに表示

      var top = center.y - boobSize / 2.0;
      var lLeft = center.x - boobSize / 2.0;
      var rLeft = center.x + boobSize / 2.0;
      var boobWidth = boobSize;
      var boobHeight = VIDEO_HEIGHT <= top + boobSize ?  VIDEO_HEIGHT - top - 2 : boobSize;

      leftContext.drawImage(bgCanvas, lLeft, top, boobWidth, boobHeight, 0, 0, 100, 100);
      rightContext.drawImage(bgCanvas, rLeft, top, boobSize, boobHeight, 0, 0, 100, 100);

先ほど求めた胸の位置を元にbgCanvasから切り取って(left|right)Canvasに設定するだけです。

画面を構成

特に目新しい部分もないので、半球を表示してテクスチャを設定するとこだけ

  function initBoob(size, center, textureCanvas) {
    var geometry = new THREE.SphereGeometry(size, 8, 8, 0, Math.PI);
    var texture = new THREE.Texture(textureCanvas);
    texture.needsUpdate = true;
    var material = new THREE.MeshLambertMaterial({map:texture});
    var mesh = new THREE.Mesh(geometry, material);
    mesh.position = center;
    scene.add(mesh);
    return mesh;
  }

半球はTHREE.jsがデフォルトで用意してるジオメトリにはないと勘違いしてたんですが、SphereGeometryは球体だけじゃなくて第4,5引数を使うと半球も作れるんですね。楽できてよかった。

ということで、Enjoy your own 巨乳!