搜尋此網誌

2011年8月3日 星期三

簡述Prime Sense API

Prime Sense API → NITE:
1、Prime Sense 以「OpenNI」為基礎建立「NITE」,再以「NITE」提供3D Gesture及其他應用。
2、NITE提供「hand tracking」、「user detector」、「depth detector」、「3d gestures detector」
2、Prime Sense Camera同於Kinet所使用的Camera,雖同以「OpenNI」為基礎,卻各自擁有不同的SDK。
3、NITE內的演算法以處理「hand tracking」為重點(人體骨架的使用仍需交給OpenNI處理)。
4、不同於Kinet,NITE的使用者需要做特定動作啟動程式(Initial Pose)。
5、NITE的「初始化手勢」有兩種,分別為「Wave」及「Click」。


API要角:
1、Detector及其Callbacks:
各種Detector,如 Wave Detector專門負責偵測使用者是否做了「Wave」,當使用者有需求時,將「WaveDetecotr」加入程式,再以callback取得wave偵測。NITE提供的 Detector包括「Wave」、「Circle」、「Swipe」、「Steady」、「Push」。
2、Session Manager:
相當於「總管」、「掌門」、「開關」的角色,決定偵測及偵測內容之執行。
3、Selectable Slider及其Callbacks:
相當方便的應用元件,包括「SelectableSlider1D」及「SelectableSlider2D」,能對Camera所偵測畫面做區域分割。
4、Flow Router   :
若一次只想偵測一種手勢時,請使用此元件。
5、Broadcaster   :
為「Flow Router」的進階,將想要偵測的手勢加入Broadcaster,即可同時偵測多項手勢。

NITE執行概念:

Step1:宣告「 Session Manager」元件
Step2:宣告欲使用的「Detector」及其「callbacks」
Step3:宣告「Flow Router」或「Broadcast」
Step4:將Detector加入「Flow Router」或「Broadcast」
Step5:將「Flow Router」或「Broadcast」加入「Session Manager」
Step6:宣告一Thread,以無限迴圈的方式執行 Session Manager內容,取得Camera內容並更新偵測內容。

以上,即可運用Prime Sense Camera配合程式碼完成3D操作的動作!

2011年7月31日 星期日

Gesture + Skeleton :最近的玩具 - Kung Fu Live & 其他

突然想起來...偉德說:「玩過的玩具該多做點紀錄」~XD

好玩有趣的其中之一:
Game : Kung Fu live參考影片(ref:http://www.kungfulivegame.com/videos/)


這個遊戲需要用Prime Sense 3D Camera來玩。事實上網路上已有非常多的相關影片,這裡貼的是他們自己的廣告影片(真該給他們一個讚)
KungFu Live是從PS3移至PC的Skelecton Game,雖然只有短短10關,但遊戲內容很有創意。目前為止,讓人最為印象深刻的Skeleton Game就屬它了!!

後續若有閒,再慢慢補上:

1、Prime Sense相關應用技術

  (1)、Prime Sense API & 使用前請先搖一搖
  (2)、如何讓Prime Sense 3D Camera正常動起來

2、最近生出來的 「Gesture TV」

  (1)、Q:關於未來電視的搖控器,你覺得會長什麼樣子?

3、3D Max 入門
  
  (1)、創造自己的的3D世界,簡單~(3D Max是比「最近」再更早以前習得的額外技能)

4、Virtools 進階

  (1)、此軟體的臺灣代理商叫「愛迪斯科技」,簡單好用...雖然不太流行><"
  (2)、除了「移植性爛到3個標準差之外」的缺點,建立3D互動的世界工具中,它真的很讚

5、3D Max + Virtools = 3D Games

  (1)、一個人就能創造自己的3D遊戲!!
  (2)、若想玩的更深入,那就把Prime Sense也加進來


有空寫完這些嗎?~XD 看工作時有沒有其他多餘時間........

2010年5月7日 星期五

WPF : Translate & Rotate

以Grid來舉例,在Grid.RenderTransform時,先做「TranslateTransform」或是先做「RotateTransform」是有差別的:

確實以(0,0)點做Rotate,意即先Rotate再做Translate:

<Grid.RenderTransform>
 <TransformGroup>
  <RotateTransform CenterX="0" CenterY="0" Angle="0"
  x:Name="Crash_MidFront_Rotate"/>
  <TranslateTransform X="560" Y="300"/>
 </TransformGroup>
</Grid.RenderTransform>


反之,將Translate放在Rotate之前,會先做Translate,再以(0,0)點做Rotate

2010年4月14日 星期三

Silverlight : Point Animation of Storyboard

運用Path元件中 LineSegment來製造3D的假像,以下紀錄對於LineSegment中 Point動畫的設定:


<Storyboard x:Name="BoxSide_LeftSide_Back" Duration="0:0:1" >
 <PointAnimation x:Name="PointMove_Left_TL"
  Storyboard.TargetName="BoxSide_LeftSide_TL"
  Storyboard.TargetProperty="(LineSegment.StartPoint)"
  From="0,0" To="0,0"/>
 <PointAnimation x:Name="PointMove_Left_TR"
  Storyboard.TargetName="BoxSide_LeftSide_TR"
  Storyboard.TargetProperty="(LineSegment.Point)"
  From="0,0" To="0,0"/>

 <PointAnimation x:Name="PointMove_Left_BL"
  Storyboard.TargetName="BoxSide_LeftSide_BL"
  Storyboard.TargetProperty="(LineSegment.Point)"
  From="0,0" To="0,0"/>
 <PointAnimation x:Name="PointMove_Left_BR"
  Storyboard.TargetName="BoxSide_LeftSide_BR"
  Storyboard.TargetProperty="(LineSegment.Point)"
  From="0,0" To="0,0"/>
</Storyboard>

其中一個Path元件的內容如下:

<Path  x:Name="BoxSide_BackSide" Stroke="Gold">
 <Path.RenderTransform>
  <TranslateTransform X="200" Y="0"/>
 </Path.RenderTransform>
 <Path.Fill>
  <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
   <GradientStop Color="#FF770000" Offset="0.0"/>
   <GradientStop Color="Black" Offset="1.0"/>
  </LinearGradientBrush>
 </Path.Fill>
 <Path.Data>
  <PathGeometry >
   <PathFigure StartPoint="90,100" IsClosed="True"   
    x:Name="BoxSide_BackSide_TL">
    <LineSegment Point="310,100" x:Name="BoxSide_BackSide_TR"/>
    <LineSegment Point="300,150" x:Name="BoxSide_BackSide_BR"/>
    <LineSegment Point="100,150" x:Name="BoxSide_BackSide_BL"/>
   </PathFigure>
  </PathGeometry>
 </Path.Data>
</Path>



假若Target直接指定Path元件,則TargetProperty設定值為:

Storyboard.TargetProperty=
 "(Path.Data).(PathGeometry.Figures)[0].
 (PathFigure.Segments)[0].(LineSegment.Point)"

可做到的效果(按下box前端及右端做上下拖拽):Box

2010年3月18日 星期四

C#:Dynamic Array

適用於 .NET 2.0 以上

無法確定陣列長度,要動態存取Grid陣列時:

List<Grid> dynamicGrid = new List<Grid>();

加入物件:

Grid myGrid = new Grid();
dynamicGrid.Add(myGrid)

取得物件,假設想要取得第一萬兩千三百四十五個Grid:

Grid tmpGrid = dynamicGrid[12345];


參考頁:http://forums.asp.net/p/1188478/2036031.aspx#2036031

2010年3月3日 星期三

3D Gesture:蠻有感覺的3D Gesture

參考頁:http://web.media.mit.edu/~mhirsch/bidi/
研究3D Gesture者可以參考一下,其內容為一種融合觸控及3D Gesture的LCD,其中他們同時提供paper,說明使用LCD同時達成「capture」及「display」。

Bidi Screen於YouTube的影片

2010年3月1日 星期一

Silverlight、C#:Unicode轉換

在C#中可使用以下程式碼對字串轉換為Unicode或將Unicode轉換為字元:

Encode

using System.Text;

private string StringToUnicode(string srcText)
{
  string dst = "";
  char[] src = srcText.ToCharArray();
  for (int i = 0; i < src.Length; i++)
  {
   byte[] bytes = Encoding.Unicode.GetBytes(src[i].ToString());
   string str = @"\u" + bytes[1].ToString("X2") + bytes[0].ToString("X2");
   dst += str;
  }
  return dst;
}

Decode

using System.Globalization;

private string UnicodeToString(string srcText)
{
string dst = "";
string src = srcText;
int len = srcText.Length / 6;

for (int i = 0; i <= len - 1; i++)
{
  string str = "";
  str = src.Substring(0, 6).Substring(2);
  src = src.Substring(6);
  byte[] bytes = new byte[2];
  bytes[1] =  
   byte.Parse(int.Parse
    (str.Substring(0,2),NumberStyles.HexNumber).ToString());
  bytes[0] = byte.Parse(int.Parse
    (str.Substring(2,  2),NumberStyles.HexNumber).ToString());
  dst += Encoding.Unicode.GetString(bytes);
  }
  return dst;
}


但上述程式碼中,Decode的部份在Slilverlight會出現「... is inaccessable due to its protection level」的錯誤,請改為以下內容,程式即可正常編譯:
Decode at Silverlight

string UnicodeToString(string srcText)
{
 string dst = "";
 string src = srcText;
 int len = srcText.Length / 6;

 for (int i = 0; i <= len - 1; i++)
 {
  string str = "";
  str = src.Substring(0, 6).Substring(2);
  src = src.Substring(6);
  byte[] bytes = new byte[2];
  bytes[1] = byte.Parse(int.Parse(str.Substring(0, 2),
   NumberStyles.HexNumber).ToString());
  bytes[0] = byte.Parse(int.Parse(str.Substring(2, 2),
   NumberStyles.HexNumber).ToString());

  Encoding enc = Encoding.GetEncoding("utf-16");
  dst += enc.GetString(bytes, 0, bytes.Length);

 }
  return dst;
}