DeveloperFeaturedInnovationJavaScriptLeap MotionProgramming Language

Leap Motion กับ Javascript ในการ Detect Hand หรือมือของเรา

บทเรียน Javascript กับของเล่นใหม่ Leap Motion สำหรับ Detect มือและนิ้วของเราผ่านอุปกรณ์แสกนแล้วทำการ Rigged กระดูกมือเราให้ใช้งานร่วมกับ โปรแกรมได้

ก่อนอื่นที่จะทำอะไรกับบทความนี้ได้นั้น คุณต้องมีเจ้าเครื่อง Leap Motion มาก่อน สามารถสั่งซื้อผ่านอินเทอร์เน็ตได้ ในราคา 79.99$ (http://store-us.leapmotion.com/) ไม่แพงสำหรับการเรียนรู้อะไรใหม่ๆ

Leap Motion 79.99$ เองนะ
Leap Motion 79.99$ เองนะ
ติดตั้งรีวิวแบบบ้านๆ นี่แหละ
ติดตั้งรีวิวแบบบ้านๆ นี่แหละ

ได้ของแล้วก็ทำการติดตั้งซะ

เข้าไปที่หน้าเว็บไซต์
เข้าไปที่หน้าเว็บไซต์

เมื่อได้ของมาแล้วก็ให้ไปดาวน์โหลดตัว Driver และ SDK ซะเลยสำหรับนักพัฒนา

ถ้าติดตั้งแล้วก็เปิดใช้งาน
ถ้าติดตั้งแล้วก็เปิดใช้งาน

ทำการติดตั้งแล้วก็เปิด Virtualize ทดสอบมันซะหน่อย

Virtualize ทดสอบมือเราซะหน่อย
Virtualize ทดสอบมือเราซะหน่อย
ใช้งานได้ 100% โอเคล่ะ
ใช้งานได้ 100% โอเคล่ะ

ทีนี้ก็มาพัฒนาโปรแกรมร่วมกับมันซะหน่อย อันที่จริง มันมีเกมมาให้เยอะแยะเลยนะให้เราเล่น แต่เราจะมองข้ามไป ไปพัฒนากันจริงๆ จังๆ ซึ่งรูปแบบการพัฒนามีให้เลือกอยู่มากมาย ผมจึงเลือกมาแค่ 2 แพลตฟอร์มคือ C# (Unity) กับ Javascript

เรามาเริ่ม Essential Lesson ด้วย Javascript ก่อน ตัว SDK มันก็มีให้แกะแหละครับ แต่การรับรู้ของคนเรามีไม่เท่ากันดังนั้นก็เลย ย่อยมาให้

รูปแบบ Leap Motion ตัวนี้ก็คือการ Detect จับว่ามือเรานั้นเป็นข้างไหน และมีสถานะ กำมือ หรือ แบมืออยู่

เขียน HTML ขึ้นมาก่อนเลยครับ ไฟล์  index.html

<!DOCTYPE html>
<!-- DAYDEV CO., LTD. CASE STUDY-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Leap Motion JS Hand Detect</title>
<!-- SDK-->
<!-- SDK-->
</head>
<body>
<h1>Console</h1>
<div id="main">
  <div id="handData"></div>
  <div style="clear:both;"></div>
</div>
</body>
</html>

ตัว Leap Motion จะมี SDK แบบ Online ให้เราเรียกใช้ครับ แทรก คำสั่งนี้ลงใน <!–SDK–> ได้เลย

<script src="http://js.leapmotion.com/leap-0.6.3.min.js"></script>

ให้เราทำการเขียน ฟังก์ชัน Javascript ขึ้นมาใหม่บน <head> ดังนี้ครับ

// Store frame for motion functions
var previousFrame = null;
var paused = false;
var pauseOnGesture = false;

// Setup Leap loop with frame callback function
var controllerOptions = {enableGestures: true};

เป็นการตรวจสอบการ Detect Gesture ของการเคลื่อนไหวผ่าน Censor ของ Leap Motion ครับ ตามด้วย

Leap.loop(controllerOptions, function(frame) {
  if (paused) {
    return; // Skip this update
  }

  // Display Hand object data
  var handOutput = document.getElementById("handData");
  var handString = "";
  if (frame.hands.length > 0) {
    for (var i = 0; i < frame.hands.length; i++) {
      var hand = frame.hands[i];

      handString += "<div style='width:400px; float:left; padding:5px'>";
      handString += "ID มือ: " + hand.id + "<br />";
      handString += "ข้างที่ใช้: " + hand.type + "<br />";
      handString += "ทิศทาง: " + vectorToString(hand.direction, 2) + "<br />";
      handString += "กำมือ: " + hand.grabStrength + "<br />";

      // IDs of pointables associated with this hand
      if (hand.pointables.length > 0) {
        var fingerIds = [];
        for (var j = 0; j < hand.pointables.length; j++) {
          var pointable = hand.pointables[j];
            fingerIds.push(pointable.id);
        }
        if (fingerIds.length > 0) {
          handString += "ID มือ และ นิ้ว: " + fingerIds.join(", ") + "<br />";
        }
      }

      handString += "</div>";
    }
  }
  else {
    handString += "No hands detect";
  }
  handOutput.innerHTML = handString;
  previousFrame = frame;
  
})

function vectorToString(vector, digits) {
  if (typeof digits === "undefined") {
    digits = 1;
  }
  return "(" + vector[0].toFixed(digits) + ", "
             + vector[1].toFixed(digits) + ", "
             + vector[2].toFixed(digits) + ")";
}

โดย Parameter ที่จำเป็นจะอยู่ส่วนนี้ครับ

var hand = frame.hands[i];

      handString += "<div style='width:400px; float:left; padding:5px'>";
      handString += "ID มือ: " + hand.id + "<br />";
      handString += "ข้างที่ใช้: " + hand.type + "<br />";
      handString += "ทิศทาง: " + vectorToString(hand.direction, 2) + "<br />";
      handString += "กำมือ: " + hand.grabStrength + "<br />";

เราจะมี hand.id ไว้จับว่ามือที่ปรากฏบน censor ณ ขณะนั้นคือมือของใคร เช่น นาย A มี ID คือ 123 แล้วยกอีกมือมาเป็น 124 แต่จู่ๆ มีนาย B เดินมายกอีกข้างสักข้างมันจะนับเป็น 125 ซึ่งจะไม่มีการเรียก Detect แต่เมื่อนาย A ยกมือ 124 ลง มันจะมองว่า ระบบมีมือ 2 ข้างคือ 123 และ 125 นั่นก็คือมือคนละข้างของ A และ B

ตามด้วย hand.type จะมีการ Rigged กระดูกมือเราเสร็จสรรพ และบอกได้เลยว่าเป็นมือ ข้าง ซ้าย หรือ ขวา โดย return ค่าเป็น left, right ครับ

hand.grabStrength เป็นสถานะของการ แบมือ และ กำมือ ถ้าแบมือจะมีค่าเป็น 0 ไปเรื่อย แต่ถ้ามีสถานะกำมือเมื่อไหร มันจะกลายเป็น 1 ไว้เทียบค่าแบบ Parameter ร่วมกับ Boolean ได้

ใส่ code ลงไปเลย จะเห็นว่า ภาพรวมของ code เป็นดังนี้

<!DOCTYPE html>
<!-- DAYDEV CO., LTD. CASE STUDY-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Leap Motion JS Hand Detect</title>
<script src="http://js.leapmotion.com/leap-0.6.3.min.js"></script>
<script>
// Store frame for motion functions
var previousFrame = null;
var paused = false;
var pauseOnGesture = false;

// Setup Leap loop with frame callback function
var controllerOptions = {enableGestures: true};


Leap.loop(controllerOptions, function(frame) {
  if (paused) {
    return; // Skip this update
  }

  // Display Hand object data
  var handOutput = document.getElementById("handData");
  var handString = "";
  if (frame.hands.length > 0) {
    for (var i = 0; i < frame.hands.length; i++) {
      var hand = frame.hands[i];

      handString += "<div style='width:400px; float:left; padding:5px'>";
      handString += "ID มือ: " + hand.id + "<br />";
      handString += "ข้างที่ใช้: " + hand.type + "<br />";
      handString += "ทิศทาง: " + vectorToString(hand.direction, 2) + "<br />";
      handString += "กำมือ: " + hand.grabStrength + "<br />";

      // IDs of pointables associated with this hand
      if (hand.pointables.length > 0) {
        var fingerIds = [];
        for (var j = 0; j < hand.pointables.length; j++) {
          var pointable = hand.pointables[j];
            fingerIds.push(pointable.id);
        }
        if (fingerIds.length > 0) {
          handString += "ID มือ และ นิ้ว: " + fingerIds.join(", ") + "<br />";
        }
      }

      handString += "</div>";
    }
  }
  else {
    handString += "No hands detect";
  }
  handOutput.innerHTML = handString;
  previousFrame = frame;
  
})

function vectorToString(vector, digits) {
  if (typeof digits === "undefined") {
    digits = 1;
  }
  return "(" + vector[0].toFixed(digits) + ", "
             + vector[1].toFixed(digits) + ", "
             + vector[2].toFixed(digits) + ")";
}

</script>
</head>
<body>
<h1>Console</h1>
<div id="main">
  <div id="handData"></div>
  <div style="clear:both;"></div>
</div>
</body>
</html>

มาทดสอบกันหน่อย ผมสร้าง http://localhost/LEAP ขึ้นมาทดสอบ

ถ้าไม่มีมือไป Detect จะไม่มีค่าอะไร
ถ้าไม่มีมือไป Detect จะไม่มีค่าอะไร
เอามือเข้าไปจะมีค่าปรากฏ
เอามือเข้าไปจะมีค่าปรากฏ
ค่าออกมาแล้ว
ค่าออกมาแล้ว

ถ้าเอามือไปวาง 2 มือ มันก็จะปรากฏค่าออกมาเป็น 2 colums ให้เรารู้ว่า มือแต่ละข้างคือมือไหน ตามด้วย ID มือและนิ้ว มือ ID 168 ถ้านิ้วโป้ง 1680, นิ้วชี้ 1681 เป็นต้น

อีกครั้ง
อีกครั้ง

พอดี รีวิวคนเดียวเลย จับหน้าจอแบบ 2 มือไม่ได้แต่เอาเป็นว่ามันแสดงผลได้ครับ

ยังไง ต่อไปคงจะใช้ต่อยอดกับ Unity (C#) กับเกมที่ต้องใช้มือควบคุมครับ ส่วน Leap Motion เหมาะกับงานประเภทไหน ก็คงบอกตรงๆ ว่า เหมาะกับงาน Event พวก Show Case หรือเกมแนว Mo Cap ครับ

 

 

 

 

 

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน