<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Codelogy</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/" />
   <link rel="self" type="application/atom+xml" href="http://www.codelogy.org/atom.xml" />
   <id>tag:www.codelogy.org,2010://28</id>
   <updated>2010-02-07T07:14:37Z</updated>
   
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.33-ja</generator>

<entry>
   <title>32ビット環境で64ビット整数を扱う (乗法編)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2010/02/3264_3.html" />
   <id>tag:www.codelogy.org,2010://28.14317</id>
   
   <published>2010-02-07T07:12:26Z</published>
   <updated>2010-02-07T07:14:37Z</updated>
   
   <summary>   これまでの記事では、32ビット環境における64ビットの加法および減法につい...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="caption">
  これまでの記事では、32ビット環境における64ビットの<entry@16>加法</entry>および<entry@50>減法</entry>について解説しました。
  いよいよ、ヤマ場である乗法、すなわち「掛け算」のやり方について解説しましょう。
</div>
<div style="margin: 1em 0;">
  <a href="http://www.codelogy.org/quillpen/?entry=53">&gt;&gt; 続きを読む...</a>
</div>]]>
      
   </content>
</entry>
<entry>
   <title>Array クラスを作る (size フィールド編)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/12/_java.html" />
   <id>tag:www.codelogy.org,2009://28.13858</id>
   
   <published>2009-12-04T14:00:00Z</published>
   <updated>2009-12-04T14:50:39Z</updated>
   
   <summary>   Java では、配列の要素数をフィールド length を通じて参照するこ...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  Java では、配列の要素数をフィールド <code>length</code> を通じて参照することができます。
</p>
<table class="code">
<tr>
  <td><pre><em class="cmt">//合計の取得</em>
<em class="kwd">int</em> sum(<em class="kwd">int</em>[] anData){

    <em class="kwd">int</em> nSum =<em class="lit">0</em>;

    <em class="kwd">int</em> i;
    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;anData.length; ++i){
        nSum +=anData[i];
    } <em class="cmt">//i</em>

    <em class="kwd">return</em> nSum;
}</pre></td>
  </tr>
</table>
<p>
  この <code>length</code> は (おそらく) <b>final</b> <b>int</b>、即ち、変更不能な <b>public</b> フィールドとして定義されており、これに対する代入操作を行おうとすると、コンパイルエラーとなります。
  ところで、この仕組みは Java が「配列のサイズは変更できない」という仕様を有するが故に可能なものであるということに読者諸兄はお気づきでしょうか。
  もし配列のサイズが初期化後に変更可能であるとすれば、<code>length</code> を <b>final</b> 修飾することはできません。
  そうなると、<code>length</code> に対する代入操作を禁止する手立てはなくなってしまうのです。
</p>
<p>
  一方、C++ ならば、値の変更が可能かつ、外部からの変更が不能なメンバ変数 (を模したインターフェイス) を定義することが可能です。
  このエントリでは、このテクニックを使い、これまでのエントリで作成してきた Array クラステンプレート (<entry@30>参照</entry>) に要素数読み取り専用のメンバ変数 <b>size</b> を定義します。
</p>  
<div style="margin: 1em 0;">
  <a href="http://www.codelogy.org/quillpen/?entry=52">&gt; 続きを読む...</a>
</div>
]]>
      
   </content>
</entry>
<entry>
   <title>ビット演算の基礎</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/11/post_18.html" />
   <id>tag:www.codelogy.org,2009://28.13798</id>
   
   <published>2009-11-15T12:00:00Z</published>
   <updated>2009-11-16T00:07:54Z</updated>
   
   <summary>   ビット演算を使用すると、1つの整数型データをビット単位で区切って、複数の用...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="caption">
  ビット演算を使用すると、1つの整数型データをビット単位で区切って、複数の用途に割り当てることができます。 例えば、符号なし整数 (<b>unsigned</b> <b>int</b>) のデータ長さが32ビットの環境であれば、一つの変数で32個の真理値 (<b>bool</b>: <b>true</b>/<b>false</b> に相当) を格納することができます。 また、これらの真理値を複数個まとめて参照・操作することも可能です。 <br />
  <br />
  しかし最近のプログラミング環境では、潤沢なメモリやライブラリの普及などにより、ビット演算を利用するような場面は、以前と比べて少なくなっています。
  そのため、ある程度長くプログラミングを学んでいるにも関わらず、ビット演算が使えない、あるいはその概念自体を知らないという人も見かけるようになりました。 <br />
  <br />
  というわけで、今回はビット演算の基本中の基本である、ビット値の参照・操作の方法とその手順について解説します。
   ちなみに、当エントリの説明では図のスペース節約のため、8ビット符号なし整数 (<b>BYTE</b>: <b>unsigned</b> <b>char</b>) を操作の対象としていますので、実際に使用する場合は適当なデータ長に置き換えて考えてください。 
</div>
<div style="margin: 1em 0;">
  <a href="http://www.codelogy.org/quillpen/?entry=55">&gt;&gt; 続きを読む...</a>
</div>]]>
      
   </content>
</entry>
<entry>
   <title>参照の配列は何故作れないか</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/07/post_17.html" />
   <id>tag:www.codelogy.org,2009://28.13254</id>
   
   <published>2009-07-10T06:00:00Z</published>
   <updated>2009-07-11T02:12:59Z</updated>
   
   <summary>   さて問題です。次のコードの実行結果はどうなるでしょうか？   #inclu...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  さて問題です。次のコードの実行結果はどうなるでしょうか？
</p>
<table class="code">
<tr>
  <td><pre><em class="kwd">#include</em> <em class="lit">&lt;iostream&gt;</em>

<em class="kwd">using namespace</em> std;

<em class="kwd">int</em> main(){
  <em class="kwd">int</em> a = <em class="lit">1</em>, b = <em class="lit">2</em>, c = <em class="lit">3</em>;
  <em class="kwd">int</em> &amp;n[<em class="lit">3</em>] = {a, b, c};

  <em class="kwd">for</em>(<em class="kwd">int</em> i = <em class="lit">0</em>; i < <em class="lit">3</em>; ++i)
    cout &lt;&lt; n[i] &lt;&lt; <em class="lit">' '</em> ;
  cout &lt;&lt; endl;

  <em class="kwd">return</em> <em class="lit">0</em>;
}</pre></td>
  </tr>
</table>
<p>
  見出しを見た皆様のお察しの通り、正解は、「そもそもコンパイルされない」です。
</p>
<table class="code">
<tr>
  <td class="result">
code.cpp: In function `int main()':<br />
code.cpp:7: error: declaration of `n' as array of references<br />
code.cpp:10: error: `n' undeclared (first use this function)<br />
code.cpp:10: error: (Each undeclared identifier is reported only once for each function it appears in.)</td>
  </tr>
</table>
<p>
  このように、C++では参照の配列を作成することは出来ません。<br />
  しかし、一体何故でしょうか？
  参照の配列によって簡潔に記述できるような処理に出くわすこともままありますし、参照の配列を作ることが原理的に不可能であるとは到底思えません。
  それなのに、何故禁止されているのでしょう？
</p>
<div style="margin: 1em 0;">
  <a href="http://www.codelogy.org/quillpen/?entry=54">&gt;&gt; 続きを読む...</a>
</div>]]>
      
   </content>
</entry>
<entry>
   <title>32ビット環境で64ビット整数を扱う (減法編)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/04/3264_2.html" />
   <id>tag:www.codelogy.org,2009://28.12906</id>
   
   <published>2009-04-21T02:20:00Z</published>
   <updated>2009-04-21T02:08:14Z</updated>
   
   <summary>   32ビット環境で64ビット整数を扱う (加法編) の続き。   今回は、加...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  <a href="http://www.codelogy.org/quillpen/?entry=16">32ビット環境で64ビット整数を扱う (加法編)</a> の続き。<br />
  今回は、加法のコードに少し手を加えて、減法を行う関数を作成します。
</p>
<div style="margin: 1em 0;">
  <a href="http://www.codelogy.org/quillpen/?entry=50">&gt; 続きを読む...</a>
</div>]]>
      
   </content>
</entry>
<entry>
   <title>カウンタ付き参照</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/03/post_16.html" />
   <id>tag:www.codelogy.org,2009://28.12676</id>
   
   <published>2009-03-11T08:58:23Z</published>
   <updated>2009-03-11T09:00:36Z</updated>
   
   <summary>   C++ では、new を用いてオブジェクト (メモリ領域) を確保したなら...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  C++ では、<b>new</b> を用いてオブジェクト (メモリ領域) を確保したならば、これを <b>delete</b> でを明示的に解放してやらなければなりません。
  この「借りたもの (メモリ) は自分で返す」という硬派なスタイルは非常に C++ らしく、またパフォーマンスの面でも優れるため、個人的にはとても気に入っています。
</p>
<p>
  その一方で、このスタイルには<a href="http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF">メモリリーク</a>や二重解放によるアクセス違反, ダングリング・ポインタの発生とった問題があり、致命的なバグの原因となりがちであることも事実です。
  また、プログラムの性質上、オブジェクトが利用されなくなるタイミングが予測しづらく、明示的な解放を記述することが原理的に困難であるような状況というものも存在します。
</p>
<p>
  C/C++ 以外の殆どの言語は<a href="http://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%99%E3%83%BC%E3%82%B8%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3">ガーベジ・コレクション</a>を言語仕様として採用することでこうした問題を回避しています。
  特に、ガーベジ・コレクション手法の一つである<a href="http://ja.wikipedia.org/wiki/%E5%8F%82%E7%85%A7%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88">参照カウント</a>は、その動作原理が非常に単純であり、またそれ故に (一般的な状況下における) パフォーマンスにおいて他の手法よりも優れています。
  そこで、この参照カウントの仕組みを C++ でも利用できないかと考え、<b>Reference</b> というクラステンプレートを作ってみました:
</p>
<ul>
<li><a href="http://www.nowhere.co.jp/~narita/library/narita/doc/ConstReference/">汎用ライブラリ: ConstReference</a></li>
<li><a href="http://www.nowhere.co.jp/~narita/library/narita/doc/Reference/">汎用ライブラリ: Reference</a></li>
</ul>
<p>
  ソースコードは上記リンク先のページからダウンロードすることができます。
</p>
<p>
  今回はこの <b>Reference</b> クラステンプレートの使い方について簡単に説明します。
</p>
<p>
  <a href="http://www.codelogy.org/quillpen/?entry=47">&gt;&gt; 続きを読む...</a>
</p>]]>
      
   </content>
</entry>
<entry>
   <title>C++ スタイルのキャスト</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/02/c_2.html" />
   <id>tag:www.codelogy.org,2009://28.12584</id>
   
   <published>2009-02-17T09:20:46Z</published>
   <updated>2009-02-17T09:23:06Z</updated>
   
   <summary>   C言語では、キャスト (型変換) を以下のような形式で行います。   ( ...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  C言語では、キャスト (型変換) を以下のような形式で行います。
</p>
<table class="code">
<tr>
  <td><pre>( <i>type</i> ) <i>expression</i></pre></td>
  </tr>
</table>
<p>
  この記法では、どのような種類のキャストが行われるのかを明示したり、不正・危険なキャストに対してチェックを行うことができないという問題があります。<br/>
  そこで、C++ では <b>static_cast</b>, <b>dynamic_cast</b>, <b>const_cast</b>, <b>reinterpret_cast</b> の 4つのキャスト演算子が導入されました。
  今回は、これらのキャストの使い方について解説していこうと思います。
</p>
<p>
  <a href="http://www.codelogy.org/quillpen/?entry=46">&gt;&gt; 続きを読む....</a>
</p>]]>
      
   </content>
</entry>
<entry>
   <title>Ruby でローカルスコープを作る</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2009/02/ruby_1.html" />
   <id>tag:www.codelogy.org,2009://28.12509</id>
   
   <published>2009-02-08T14:10:21Z</published>
   <updated>2009-02-08T14:49:15Z</updated>
   
   <summary>   必要に迫られて、ローカルスコープを作り出す関数を作ってみました。 ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Ruby" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  必要に迫られて、ローカルスコープを作り出す関数を作ってみました。
</p>
]]>
      <![CDATA[<h3 class="section">背景</h3>
<p>
  私が CGI を作る時には、基本的に Ruby で実装し、html の出力の際には eRuby を使っています。
  小さいページを作るときはあまり問題にならないのですが、結構な規模のページを作ろうと思うと、テンプレートが長大になってしまいます。
  さらに、いくつかのページでは重複する部分 (ヘッダやフッタ) が存在し、すべてのテンプレートにそれを記述しておくのは冗長で、変更が面倒になります。
</p>
<p>
  そこで、テンプレートを複数に分割し、別のテンプレートを埋め込めるように、以下のような関数を定義して使用しています。
</p>
<table class="code"><tr><td><pre>
<span style="color: #a020f0;">def</span> <span style="color: #0000ff;">include_template</span>(filename, binding)
  <span style="color: #b22222;"># </span><span style="color: #b22222;">再帰的に include_template を呼ばれると, ERB でバッファが競合するので, それを
</span>  <span style="color: #b22222;"># </span><span style="color: #b22222;">避けるためにサフィックスに一意な番号を付ける.
</span>  <span style="color: #b8860b;">@erb_buffer_count</span> = 0   <span style="color: #a020f0;">unless</span> <span style="color: #b8860b;">@erb_buffer_count</span>

  buffer_name = <span style="color: #bc8f8f;">'_erbout_'</span> + <span style="color: #b8860b;">@erb_buffer_count</span>.to_s

  <span style="color: #b8860b;">@erb_buffer_count</span> += 1

  erb = <span style="color: #228b22;">ERB</span>::new(<span style="color: #228b22;">IO</span>.read(filename), <span style="color: #b8860b;">nil</span>, <span style="color: #bc8f8f;">'%'</span>, buffer_name)
  erb.filename = filename
  res = erb.result(binding)

  <span style="color: #b8860b;">@erb_buffer_count</span> -= 1

  <span style="color: #a020f0;">return</span> res
<span style="color: #a020f0;">end</span> <span style="color: #b22222;"># </span><span style="color: #b22222;">def include_template
</span></pre></td></tr></table>

<p>
  例えば、以下のように使います。
</p>
<table class="code"><tr><td><pre>
&lt;<span style="color: #0000ff;">html</span>&gt;
  &lt;<span style="color: #0000ff;">head</span>&gt;
    &lt;<span style="color: #0000ff;">title</span>&gt;<span style="font-weight: bold; text-decoration: underline;">test</span>&lt;/<span style="color: #0000ff;">title</span>&gt;
  &lt;/<span style="color: #0000ff;">head</span>&gt;
  &lt;<span style="color: #0000ff;">body</span>&gt;
    &lt;%= include_temmplate('header.rhtml', binding) %&gt;
    &lt;<span style="color: #0000ff;">div</span> <span style="color: #b8860b;">id</span>=<span style="color: #bc8f8f;">"main"</span>&gt;
      Hello, world!
    &lt;/<span style="color: #0000ff;">div</span>&gt;
    &lt;%= include_temmplate('footer.rhtml', binding) %&gt;
  &lt;/<span style="color: #0000ff;">body</span>&gt;
&lt;/<span style="color: #0000ff;">html</span>&gt;
</pre></td></tr></table>

<h3 class="section">スコープが分けられない</h3>
<p>
  これで、テンプレートが分割でき、開発効率も改善されたのですが、テンプレートを分割していった過程で新たな問題が出てきました。
  それは、それぞれのテンプレート間で自由に変数を使っていたために、予期せぬ内に変数が変更されていることがある、という問題でした。
</p>
<p>
  普通、このような問題はスコープを分けることで減らすことができるのですが、eRuby のテンプレートでは、うまく分けられません。
 というのも、現在の Ruby では、あるスコープ内で完全にローカルな変数を確実に作る方法は関数定義、クラス定義、モジュール定義のいずれかしかないにも関わらず、eRuby では、間にテンプレートを含む関数、クラス、モジュールを定義することができないからです。
  例えば、以下のようなテンプレートはエラーが起きて動きません。
</p>
<table class="code"><tr><td><pre>
%   <span style="color: #a020f0;">def</span> hello(name)
Hello, &lt;%= name %&gt;!
%   <span style="color: #a020f0;">end</span>

&lt;%= hello(<span style="color: #bc8f8f;">'world'</span>) %&gt;
</pre></td></tr></table>
<p>
  なぜなら、上のテンプレートは以下のように展開され、hello 関数からは出力バッファである _erbout が視えないからです。
</p>
<table class="code"><tr><td><pre>
_erbout = <span style="color: #bc8f8f;">''</span>;
<span style="color: #a020f0;">def</span> hello(name)
  _erbout.concat <span style="color: #bc8f8f;">"Hello, "</span>;
  _erbout.concat(( name ).to_s);
  _erbout.concat <span style="color: #bc8f8f;">"!\n"</span>;
<span style="color: #a020f0;">end</span>
_erbout.concat <span style="color: #bc8f8f;">"\n"</span>;
_erbout.concat(( hello(<span style="color: #bc8f8f;">'world'</span>) ).to_s);
_erbout.concat <span style="color: #bc8f8f;">"\n"</span>;
_erbout
</pre></td></tr></table>
<p>
  ここで、Proc や begin 〜 end でブロックを作るという方法を考えられるかもしれませんが、そもそもこれらは常に完全なローカル変数を作り出すことはできません。
  ローカル変数を作り出せるのは、そのブロックの外のスコープに同名のローカル変数が定義されていない場合だけなのです。
  それ以外では、外側のスコープの変数にアクセスしているとみなされます。
</p>
<table class="code"><tr><td><pre>
a = 1
b = 2
p [a, b] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 2]
</span><span style="color: #a020f0;">begin</span>
  b = 3
  p [a, b] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 3]
</span><span style="color: #a020f0;">end</span>
p [a, b] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 3]
</span></pre></td><td><pre>
a = 1
b = 2
p [a, b] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 2]
</span><span style="color: #228b22;">Proc</span>.new{|b|
  b = 3
  p [a, b] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 3]
</span>}.call(b)
p [a, b] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 3]
</span></pre></td><tr></table>
<p>
  ちなみに、このような問題は結構前から指摘され、そのうち対策案が実装されるようです。
  参考: <a href="http://rainyday.blog.so-net.ne.jp/2007-02-13">Ruby に let/local/my がない（らしい）ことについて　[Ruby] - Rainy Day Codings</a>
</p>
<h3 class="section">解決</h3>
<p>
  しかし、いつ実装されるのかよく分からないので、自分でローカルスコープを定義する関数を作ってみました。
</p>
<table class="code"><tr><td><pre>
<span style="color: #a020f0;">def</span> <span style="color: #0000ff;">local_vars</span>(vars, binding)
  vars.each{|sym|
    eval(<span style="color: #bc8f8f;">&lt;&lt;EOS</span>, binding)<span style="color: #bc8f8f;">
_local_var_stack_ = []  unless _local_var_stack_
_local_var_stack_.push(defined?(</span><span style="color: #b8860b;">#{sym}</span><span style="color: #bc8f8f;">) ? </span><span style="color: #b8860b;">#{sym}</span><span style="color: #bc8f8f;"> : nil)
EOS</span>
  }
  <span style="color: #a020f0;">yield</span>()
  vars.reverse.each{|sym|
    eval(<span style="color: #bc8f8f;">"</span><span style="color: #b8860b;">#{sym}</span><span style="color: #bc8f8f;"> = _local_var_stack_.pop"</span>, binding)
  }
<span style="color: #a020f0;">end</span> <span style="color: #b22222;"># </span><span style="color: #b22222;">def local_vars
</span></pre></td></tr></table>
<p>
  個人的に eval は好きではないのですが、ローカルスコープを作るためなら仕方ないということで、諦めました。
  それはさておき、これにて以下のようにローカルスコープを作ることができるようになりました。
</p>
<table class="code"><tr><td><pre>
a = 1
b = 2
c = 3
p [a, b, c] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 2, 3]
</span>local_vars([<span style="color: #5f9ea0;">:b</span>], binding){
  b = 4
  p [a, b, c] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 4, 3]
</span>  local_vars([<span style="color: #5f9ea0;">:c</span>], binding){
    c = 5
    p [a, b, c] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 4, 5]
</span>  }
  p [a, b, c] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 4, 3]
</span>}
p [a, b, c] <span style="color: #b22222;"># </span><span style="color: #b22222;">=&gt; [1, 2, 3]
</span></pre></td></tr></table>
<div class="author">
  担当: 齋藤 (eval があれば何でもできる)
</div>
]]>
   </content>
</entry>
<entry>
   <title>リニューアル計画中</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/12/post_15.html" />
   <id>tag:www.codelogy.org,2008://28.11406</id>
   
   <published>2008-12-19T04:52:40Z</published>
   <updated>2008-12-19T07:07:38Z</updated>
   
   <summary>   現在、サイトリニューアルを計画中です。   このURL (http://w...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  現在、サイトリニューアルを計画中です。<br />
  このURL (http://www.codelogy.org/) はこのまま使用する予定ですが、一足先に見たい、という方は<a href="http://www.codelogy.org/quillpen/">こちら</a>へどうぞ。
</p>]]>
      
   </content>
</entry>
<entry>
   <title>エスケープは出力時に</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/11/post_14.html" />
   <id>tag:www.codelogy.org,2006://28.11274</id>
   
   <published>2008-11-08T15:00:00Z</published>
   <updated>2008-11-14T05:26:24Z</updated>
   
   <summary>   CGIプログラムは、HTMLを出力とすることが多い (というか殆ど) ため...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="section">
  CGIプログラムは、HTMLを出力とすることが多い (というか殆ど) ため、入力データに対して HTML エスケープを施すものが多く見られます。
  <table class="code">
  <tr>
    <td class="caption">入力部</td>
    </tr>
  <tr>
    <td><pre>
cgi    =CGI::new()
title  =CGI::escapeHTML(cgi.params[<em class="str">'title'</em>])
artist =CGI::escapeHTML(cgi.params[<em class="str">'artist'</em>])
asin   =CGI::escapeHTML(cgi.params[<em class="str">'asin'</em>])
</pre></td>
    </tr>
  <tr>
    <td class="caption">出力部 (<a href="http://ja.wikipedia.org/wiki/ERuby">eRuby</a>)</td>
    </tr>
  <tr>
    <td><pre>
&lt;<em class="kwd">table</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;タイトル&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;<em class="erb">&lt;%=title%&gt;</em>&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;アーティスト&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;<em class="erb">&lt;%=artist%&gt;</em>&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;購入&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;&lt;<em class="kwd">a</em> <em class="usr">href</em>=<em class="str">"http://www.amazon.co.jp/dp/<em class="erb">&lt;%=asin%&gt;</em>"</em>&gt;Amazon.co.jp&lt;<em class="kwd">a</em>&gt;&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
&lt;/<em class="kwd">table</em>&gt;</pre></td>
    </tr>
  <tr>
    <td class="caption">実行結果 (HTML出力)</td>
    </tr>
  <tr>
    <td class="result">
<pre>&lt;<em class="kwd">table</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;タイトル&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;American McGee's &amp;quot;ALICE&amp;quot; (Original Music Score)&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;アーティスト&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;Chris Vrenna&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;購入&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;&lt;<em class="kwd">a</em> <em class="usr">href</em>=<em class="str">"http://www.amazon.co.jp/dp/B00005OB0J"</em>&gt;Amazon.co.jp&lt;<em class="kwd">a</em>&gt;&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
&lt;/<em class="kwd">table</em>&gt;</pre></td>
     </tr>
  </table>
  <p>
    HTMLのタグや属性の記述に使用される <code>&lt;</code>, <code>&gt;</code>, <code>&amp;</code>, <code>&quot;</code> といった特殊文字をエスケープすることで、<a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0">クロスサイトスクリプティング</a>などの不正な出力を防止しているわけです。
    このような、入力時にエスケープ処理を施す手法は多くの書籍・サイトなどで紹介され、実際に公開されている Web アプリケーションにおいても広く用いられています。
    しかしながら、この手法には大きな問題点があります。
  </p>
</div>
]]>
      <![CDATA[<h3 class="section">データベースに格納する場合</h3>
<div class="section">
  <p>
    例えば、このCGIプログラムが、入力値をHTMLとして出力するだけでなく、データベースに格納するような仕様になっている場合、どんなことが起こるでしょう？
    (下のコード例では PostgreSQL に、Ruby::DBI を使用して格納)
  </p>
  <table class="code">
  <tr>
    <td>
<pre>dbh.do(
  <em class="str">'INSERT INTO album(title, artist, asin) VALUES (?, ?, ?');'</em>,
  title, artist, asin)</pre></td>
    </tr>
  </table>
  <p>
    この操作によって生成されるSQLコマンドは、以下に示す文字列となります。(SQL では、文字列定数はシングルクォート <code>'</code> で囲む。文字列定数にシングルクォートが含まれる場合は、これを二つ重ねることでエスケープする。)
  </p>
  <table class="code">
  <tr>
    <td>INSERT INTO album(title, artist, asin) VALUES (<em class="str">'American McGee''s &amp;quot;ALICE&amp;quot; (Original Music Score)'</em>, <em class="str">'Chris Vrenna'</em>, <em class="str">'B00005OB0J'</em>)</td>
    </tr>
  </table>
  <p>
    SQL では、文字列定数中でダブルクォート <code>"</code> をエスケープする必要はありませんが、入力時にHTMLに合わせてこれをエスケープしてしまったため、データベースには、アルバムのタイトルとして、
  </p>
  <table class="code">
  <tr>
    <td>American McGee's &amp;quot;ALICE&amp;quot; (Original Music Score)</td>
    </tr>
  </table>
  <p>
    という値が記録されてしまうこととなります。
  </p>
</div>

<h3 class="section">出力時エスケープ</h3>
<div class="section">
  <p>
    エスケープを出力時に行うようにすれば、出力形式に応じて適切なエスケープ手法を選択することができるようになります。
  </p>
  <table class="code">
  <tr>
    <td class="caption">入力部</td>
    </tr>
  <tr>
    <td><pre>
cgi    =CGI::new()
title  =cgi.params[<em class="str">title</em>]
artist =cgi.params[<em class="str">artist</em>]
asin   =cgi.params[<em class="str">asin</em>]
</pre></td>
    </tr>
  <tr>
    <td class="caption">出力部 (<a href="http://ja.wikipedia.org/wiki/ERuby">eRuby</a>)</td>
    </tr>
  <tr>
    <td><pre>
&lt;<em class="kwd">table</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;タイトル&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;<em class="erb">&lt;%=CGI::escapeHTML(title)%&gt;</em>&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;アーティスト&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;<em class="erb">&lt;%=CGI::escapeHTML(artist)%&gt;</em>&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
  &lt;<em class="kwd">tr</em>&gt;
    &lt;<em class="kwd">th</em>&gt;購入&lt;/<em class="kwd">th</em>&gt;
    &lt;<em class="kwd">td</em>&gt;&lt;<em class="kwd">a</em> <em class="usr">href</em>=<em class="str">"http://www.amazon.co.jp/dp/<em class="erb">&lt;%=CGI::escapeHTML(asin)%&gt;</em>"</em>&gt;Amazon.co.jp&lt;<em class="kwd">a</em>&gt;&lt;/<em class="kwd">td</em>&gt;
  &lt;/<em class="kwd">tr</em>&gt;
&lt;/<em class="kwd">table</em>&gt;</pre></td>
    </tr>
  </table>
  <p>
    このようにすれば、先の例のように、入力値をSQLに埋め込む場合でも、余計なエスケープをかけずに、正しい値をデータベースに保存することができるようになります。
  </p>
</div>


<h3 class="section">まとめ</h3>
<div class="section">
  <p>
    「出力の形式」が指定されなければ、「入力値をどのようにエスケープすべきか」という問いは無意味です。
    このことを理解せずに、入力に対して一律にHTMLエスケープを施してしまうと、HTML 以外の形式 (SQL, CSV等) での出力に不具合をきたしかねません。<br />
    しかしながら、先に述べたように、この手法は「サニタイズ (sanitize)」として多くの書籍・サイトで紹介されているため、すでに広く認知され、普及・採用されてしまっています。
    この「サニタイズ」が多くの人に受け入れられている理由として、以下のことが考えられるでしょう。
  </p>
  <ul>
  <li>HTML以外の出力を考慮していない。</li>
  <li>「入力時」にまとめてエスケープ処理を施すことで、チェックの手間が減り、コードの複雑さが低減されると誤解している。</li>
  <li>何も考えずに、書籍などの解説を鵜呑みにしている。</li>
  </ul>
  <p>
    いずれにせよ、「入力時のエスケープ処理」は本質的に正しくない手法であり、バグや脆弱性の原因となるので、これを採用することは避けるべきです。
  </p>
</div>

<h3 class="section">関連記事: 「サニタイズ言うな」キャンペーン</h3>
<div class="section">
  <p>
    また、「サニタイズ」という呼称を与えることで、これが本質的に正しい対策だと勘違いされたり、異なる手法を同じ「サニタイズ」という名前で呼ぶことで議論に齟齬を生じるケースが多いので、「サニタイズ」という言葉そのものを使うな、という意見もあります。
  </p>
  <ul>
  <li><a href="http://takagi-hiromitsu.jp/diary/20051227.html#p02">高木浩光＠自宅の日記 - 「サニタイズ言うなキャンペーン」とは何か</a></li>
  <li><a href="http://takagi-hiromitsu.jp/diary/20051231.html#p02">高木浩光＠自宅の日記 - 要約版：「サニタイズ言うなキャンペーン」とは </a></li>
  <li><a href="http://takagi-hiromitsu.jp/diary/20060115.html">高木浩光＠自宅の日記 - 続・「サニタイズ言うなキャンペーン」とは </a></li>
  </ul>
</div>
<div class="signature">
  担当: 成田 (配列全体にエスケープをかける機能など必要ない)
</div>]]>
   </content>
</entry>
<entry>
   <title>FBXファイルを読み込む(スキン情報の取得) </title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/09/fbx_1.html" />
   <id>tag:www.codelogy.org,2000://28.11106</id>
   
   <published>2008-09-26T15:00:00Z</published>
   <updated>2008-09-29T13:11:09Z</updated>
   
   <summary> 松浦さんから依頼を受けて、Autodesk Maya 等の .fbx 形式から...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="3D" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="section" style="margin-bottom: 1em;">
松浦さんから依頼を受けて、Autodesk Maya 等の .fbx 形式からMicrosoft DirectX の .x 形式に変換するスクリプトを書きました。<br />
FBX形式の仕様は膨大で、予想していたよりもずっと大掛かりな作業となってしまいました。<br />
これからFBX SDKを扱う人の助けになることを祈って、解説記事を書くことにします。<br />
</div>]]>
      <![CDATA[<div class="section" style="margin-bottom: 1em;">
今回の作業に当たって、<a href="http://marupeke296.com/">○×つくろーどっとコム</a>さんの<a href="http://marupeke296.com/FBX_main.html">FBX修得編</a>を参考にさせていただきました。<br />
こちらは大変丁寧な記事ですので、FBX SDKを始める人はまずこちらを読むのがいいでしょう。<br />
また、.x 形式については<a href="http://sora.cc.nagoya-u.ac.jp/t4369/fortran/index.htm">Windows Fortran入門</a>さんの<a href="http://sora.cc.nagoya-u.ac.jp/t4369/fortran/DirectX/Xfile.htm">Ｘファイルの形式</a>に詳しい解説があります。<br />
<br />
この記事では、まだ<a href="http://marupeke296.com/FBX_main.html">FBX修得編</a>でも解説されていないスキン情報の取得と、その DirectX 形式への変換について説明します。<br />

私は3Dについては門外漢なので、もし不正確な表現がありましたらご指摘ください。修正させていただきます。
</div>

<h3 class="section">1. スキン情報オブジェクトを取り出す</h3>

<div class="section" style="margin-bottom: 1em;">
FBXでは、スキン情報は <code>KFbxDeformer</code> クラスの子クラスである<code>KFbxSkin</code> クラスによって管理されます。<br />
<code>KFbxDeformer</code> オブジェクトは <code>KFbxMesh</code> オブジェクトから次のようにして取り出すことが出来ます。<br />
</div>

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の呼び出し</td></tr>
<tr><td><pre>
KFbxMesh *pMesh;

:  <em class="cmt">// set appropriate value to pMesh</em>

<em class="cmt">// get number of deformer</em>
<em class="kwd">int</em> DeformerCount = pMesh-&gt;GetDeformerCount();
<em class="kwd">for</em>(<em class="kwd">int</em> i = <em class="lit">0</em> ; i &lt; DeformerCount; ++i){

    <em class="cmt">// output each deformer</em>
    PrintSkinweight(pMesh-&gt;GetDeformer(i));
}

</pre></td></tr>
</table>
<div class="section" style="margin-bottom: 1em;">
1つのメッシュに対して複数の Deformer が定義されていることがあります。<br />
よって、 <code>GetDeformerCount()</code> メソッドによって Deformer の個数を取得し、 GetDeformer(i) で i 番目の Deformer を取得します。<br />
<br />
forループの中の <code>PrintSkinWeight()</code> 関数の中で、実際の出力処理を行います。<br />
それでは、この関数の実装を説明しましょう。<br />
</div>

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(1/7)</td></tr>
<tr><td><pre>
<em class="kwd">void</em> PrintSkinweight(KFbxDeformer *pDeformer){
    <em class="cmt">// open file to output</em>
    FILE *fp = fopen(<em class="lit">"output.x"</em>,<em class="lit">"w"</em>);

    <em class="cmt">// Is deformer type eSKIN?</em>
    <em class="kwd">if</em>(pDeformer-&gt;GetDeformerType() != KFbxDeformer::eSKIN){
        fprintf(stderr, <em class="lit">"Error : Deformer type is not skin.\n"</em>);
        <em class="kwd">return</em>;  <em class="cmt">// abort</em>
    }

    KFbxSkin *pSkin = <em class="kwd">static_cast</em>&lt;KFbxSkin *&gt;(pDeformer);


</pre></td></tr>
</table>

<div class="section" style="margin-bottom: 1em;">
<code>KFbxDeformer</code> オブジェクトは、以下の4種類の DeformerType のうちどれか1つを持っています。<br />

<ul>
<li>UNIDENTIFIED</li>
<li>eSKIN</li>
<li>eVERTEX_CACHE</li>
<li>eDEFORMER_COUNT</li>
</ul>

.x 形式の SkinWeight と同様の情報を持っているのは DeformerType が eSKIN であるオブジェクトで、これは <code>KFbxSkin</code> クラスにキャストすることが出来ます。<br />
これで <code>KFbxSkin</code> オブジェクトを取り出すことが出来ました。<br />
</div>


<h3 class="section">2. クラスタと3つのリンクモード</h3>

<div class="section" style="margin-bottom: 1em;">
1つの <code>KFbxSkin</code> オブジェクトは、複数のクラスタから構成されます。<br />
このクラスタひとつひとつが、 .x 形式のひとつの SkinWeight 情報に相当します。<br />
つまり、クラスタはボーンの同義語のようです。<br />
<br />
次のようにして、クラスタ情報を読み込みます。<br />
</div>

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(2/7)</td></tr>
<tr><td><pre>
    
    <em class="cmt">// get number of cluster</em>
    <em class="kwd">int</em> ClusterCount = pSkin-&gt;GetClusterCount();

    <em class="kwd">for</em>(<em class="kwd">int</em> i = <em class="lit">0</em>; i &lt; ClusterCount; ++i){
        <em class="cmt">// get a cluster</em>
        KFbxCluster *pCluster = pSkin-&gt;GetCluster(i);

        <em class="cmt">// <s>set link mode to eTOTAL1</s></em>
        <em class="cmt">// <s>pCluster-&gt;SetLinkMode(KFbxCluster::eTOTAL1);</s></em>
        <em class="cmt">// Sorry, let me discuss only clusters where link mode is eTOTAL1</em>
        <em class="kwd">if</em>(pCluster-&gt;GetLinkMode() != KFbxCluter::eTOTAL1){
                <em class="kwd">continue</em>;
        }

</pre></td></tr>
</table>

<div class="section" style="margin-bottom: 1em;">
先ほど見た <code>GetDeformerCount()</code> や <code>GetDeformer()</code> と同様にして、<br />
クラスタの総数とそれぞれのクラスタを取得することが出来ます。<br />
<br />
各クラスタには、次の3種類のリンクモードのうちどれか1つが設定されています。<br />

<ul>
<li>eNORMALIZE</li>
<li>eADDITIVE</li>
<li>eTOTAL1</li>
</ul>

<s><font size="-1">
本来ならばこの3種類のリンクモードに応じて3つの出力コードを書くべきなのですが、<br />
これらの（特に <code>eADDITIVE</code> の）データ構造を理解してコードを書くのは非常に難しく大変な作業です。<br />
あまり褒められた手段ではありませんが、ここでは <code>SetLinkMode()</code> メソッドを使ってリンクモードを <code>eTOTAL1</code> に設定し、<br />
<code>eTOTAL1</code> 用のコードだけを書くことにします。<br />
<code>eTOTAL1</code> を選んだのは、これが最も .x 形式に近いデータ構造だからです。<br />
</font></s>
訂正：<br />
SetLinkMode() メソッドはリンクモードのフラグを書き換えるだけで、実際のデータ構造には影響を与えないようです。したがって、やはり3種類のリンクモードに合わせて3つのコードを書かなければなりません。<br />
ちなみに、このことについてもリファレンスに十分な記述はありません。<br />
</div>


<h3 class="section">3. 影響を受ける頂点情報の取得</h3>

<div class="section" style="margin-bottom: 1em;">
ここからは、実際にスキン情報を出力する部分に入ります。<br />
<br />
まずは、 <code>GetName()</code> メソッドでクラスタの名前を取得します。<br />

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(3/7)</td></tr>
<tr><td><pre>
        fprintf(fp, <em class="lit">"SkinWeights {\n"</em>);
        fprintf(fp, <em class="lit">"\"%s\";\n"</em>, pCluster-&gt;GetName());
</pre></td></tr>
</table>

次に、 <code>GetControlPointIndicesCount()</code> メソッド（長いですね）で、このクラスタによって移動する頂点の数を取得します。<br />

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(4/7)</td></tr>
<tr><td><pre>
        <em class="cmt">// get number of control point affected by this bone</em>
        <em class="kwd">int</em> ControlPointIndicesCount = pCluster-&gt;GetControlPointIndicesCount();

        <em class="cmt">// output number of control point</em>
        fprintf(fp, <em class="lit">"%d;\n"</em>, ControlPointIndicesCount);
</pre></td></tr>
</table>

実際に移動する頂点のインデックスの配列は、 <code>GetControlPointIndices()</code>によって取得できます。<br />
このメソッドは int * 型を返します。<br />

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(5/7)</td></tr>
<tr><td><pre>
        <em class="kwd">for</em>(<em class="kwd">int</em> j = <em class="lit">0</em>; j &lt; ControlPointIndicesCount; ++j){
            fprintf(fp, <em class="lit">"%d%c\n"</em>,

                    <em class="cmt">// get index of j-th control point that is deformed</em>
                    (pCluster-&gt;GetControlPointIndices())[j],

                    <em class="cmt">// a comma is needed between two consecutive indices,</em>
                    <em class="cmt">// a semicolon is needed after the last index.</em>
                    (j+<em class="lit">1</em>==ControlPointIndicesCount ? <em class="lit">';'</em> : <em class="lit">','</em>));
        }
</pre></td></tr>
</table>

そして、各頂点がボーンから受ける影響の重みの配列は、<code>GetControlPointWeights()</code> メソッドによって取得できます。<br />
こちらは double * 型を返します。<br />

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(6/7)</td></tr>
<tr><td><pre>
        <em class="kwd">for</em>(<em class="kwd">int</em> j = <em class="lit">0</em>; j &lt; ControlPointIndicesCount; ++j){
            fprintf(fp, <em class="lit">"%.6lf%c\n"</em>,
                    (pCluster-&gt;GetControlPointWeights())[j],
                    (j+<em class="lit">1</em>==ControlPointIndicesCount ? <em class="lit">';'</em> : <em class="lit">','</em>));
        }
</pre></td></tr>
</table>

簡単のために省略しましたが、実際には移動する頂点数が 0 だった場合も考慮して実装する必要があります。<br />
</div>


<h3 class="section">3. トランスフォーム行列の取得</h3>

<div class="section" style="margin-bottom: 1em;">
最後に、メッシュの頂点をボーンの空間へと変換する行列を取得します。<br />
この変換を行う行列は、以下の3種類があります。<br />

<ul>
<li>TransformMatrix</li>
<li>TransformLinkMatrix</li>
<li>TransformAssociateModelMatrix</li>
</ul>

まず、 <code>TransformAssociateModelMatrix</code> は無視してかまいません。<br />
これはリンクモードが <code>eADDITIVE</code> のときだけ必要になるからです。<br />
（先ほどリンクモードを <code>eTOTAL1</code> に設定したことを思い出してください。）<br />
<br />
残る2つの行列なのですが、どちらを使えばいいのかはよく分かりません。<br />
とりあえず、 <code>TransformMatrix</code> を使うことにします。<br />

<table class="code">
<tr><td class="caption">PrintSkinweight() 関数の実装(7/7)</td></tr>
<tr><td><pre>
        KFbxXMatrix Matrix, TransformMatrix, TransformLinkMatrix;

        <em class="cmt">// get transform matrix and transform link matrix</em>
        pCluster-&gt;GetTransformMatrix(TransformMatrix);
        pCluster-&gt;GetTransformLinkMatrix(TransformLinkMatrix);

        <em class="cmt">// THESE ARE SUBJECT TO RETHINK</em>
        Matrix = TransformMatrix;
        <em class="cmt">// Matrix = TransformLinkMatrix;</em>
        <em class="cmt">// Matrix = TransformLinkMatrix * TransformMatrix;</em>
        <em class="cmt">// Matrix = TransformMatrix * TransformLinkMatrix;</em>

        <em class="cmt">// output all elements of the matrix</em>
        <em class="kwd">for</em>(<em class="kwd">int</em> y = <em class="lit">0</em>; y &lt; <em class="lit">4</em>; ++y)
            <em class="kwd">for</em>(<em class="kwd">int</em> x = <em class="lit">0</em>; x &lt; <em class="lit">4</em>; ++x)
                fprintf(fp, <em class="lit">"%.6lf%s"</em>, Matrix.Get(y, x), ((x==<em class="lit">3</em> &amp;&amp; y==<em class="lit">3</em>) ? <em class="lit">";;"</em> : <em class="lit">","</em>));
        fprintf(fp, <em class="lit">"\n}\n\n"</em>);

    } <em class="cmt">// end of for(int i = 0; i &lt; ControlPointIndicesCount; ++i){</em>

    return;

} <em class="cmt">// end of function</em>
</pre></td></tr>
</table>

FBX SDKでは、行列は <code>KFbxXMatrix</code> クラスによって管理されます。<br />
<code>Get()</code> メソッドによって要素へのアクセスを行います。<br />
<br />
<br />
これで .x 形式での出力が完了しました。<br />
ここまでお付き合い下さいましてありがとうございます。<br />
</div>


<h2 class="section">FBX SDKの問題点</h2>

<div class="section" style="margin-bottom: 1em;">
FBX SDK は最近バージョンアップがあり、大幅な機能の強化が施されました。<br />
しかし、ユーティリティに関しては十分でも、ユーザビリティに関してはお世辞にも満足とは言えません。<br />
<br />
まず、この記事で触れた部分の中で私が不満を持った点を挙げます。<br />
</div>

<h3 class="section">1. <code>KFbxSkin</code> が見付けにくい</h3>

<div class="section" style="margin-bottom: 1em;">
<code>KFbxSkin</code> オブジェクトは、 <code>KFbxDeformer</code> オブジェクトをキャストして得られると説明しました。<br />
しかしリファレンスでは、この2つのクラスの関連性についてほとんど表記されていません。(*<a href="http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_deformer.html">KFbxDeformer</a>, <a href="http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_skin.html">KFbxSkin</a>)<br />
クラス図によって継承関係は示されていますが、文章による説明は全くありません。<br />
これは、リファレンスをトップダウンに見ながらスキン情報を探すユーザにとって大きな障害です。<br />
もしスキン情報を見つけたいと思ったなら、 <code>KFbxDeformer</code> クラスの解説の中で<br />
ただ一度しか触れられていない <code>KFbxSkin</code> という単語を見つけ、<br />
それがスキン情報だという洞察を発揮した上で（もしボーンという単語だけを<br />
探していたなら、この単語は見つけられないでしょう）クリックする必要があります。<br />
<br />
始めに言ったように私は門外漢ですので、まず <code>KFbxDeformer</code> クラスを見付け、<br />
検索フォームに思いつく限りの単語を打ち込んで <code>KFbxSkin</code> クラスを見付け、<br />
これらのクラスの説明を何度か見比べてやっと理解しました。<br />
</div>

<h3 class="section">2. どちらの行列を使うべきか</h3>

<div class="section" style="margin-bottom: 1em;">
頂点をトランスフォームする行列の解説について、恥ずかしながら<br />
どちらを使えばいいのかよく分からないと逃げてしまいました。<br />
この点について、リファレンスの該当箇所を見てみましょう。<br />

<blockquote cite="http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_cluster.html">
<ul>
<li>Transform refers to the global initial position of the node containing the link</li>
<li>TransformLink refers to global initial position of the link node</li>
</ul>
<div class="cite"><a href="http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_cluster.html">http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_cluster.html</a></div>
</blockquote>

これでは、お世辞にも分かりやすいとは言えません。<br />
2つのモノの違いを説明するのに、なぜ全く同じ単語を使うのでしょうか？<br />
</div>

<h3 class="section">何が問題か</h3>

<div class="section" style="margin-bottom: 1em;">
これらの問題は、「ドキュメントが不十分である」と言い換えられます。<br />
十分な量の説明を与えていれば、私は情報を求めてリファレンスを何度もめくったり、<br />
不正確なコードを書くことも無かったのです。<br />
<br />
「十分な知識があればこのドキュメントからでもすぐに情報を<br />
見付けられるのだから、ドキュメントが悪いのではない。<br />
不勉強なお前が悪いのだ」という反論もあるかもしれません。<br />
確かに私が悪いのですが、しかしそれは「ドキュメントをより充実させなくても良い」<br />
という理由にはなりえません。<br />
なぜなら、FBX SDKは多くの人に使われることを目的としている（はずだ）からです。<br />
<br />
もしより詳細なドキュメントのあるSDKが使えるならば、たとえ機能が劣っていても<br />
私はそちらを使います。そちらのほうが効率的に製作できるからです。<br />
「ドキュメントは貧弱だがウチのSDKの方が高性能だ。だから必死に勉強して<br />
ウチのSDKを使え」と言われても、耳を貸すつもりはありません。<br />
<br />
もしAutodesk社がFBX SDKを多くの人に使ってもらいたいと思っているのなら、<br />
詳細なドキュメントを書く以外に採るべき手段はありません。<br />
</div>

<div class="section" style="margin-bottom: 1em;">
担当：（後半は成田さんの霊が乗り移った）田山
</div>
]]>
   </content>
</entry>
<entry>
   <title>モーションキャプチャデータの使い方（計画編）</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/09/post_13.html" />
   <id>tag:www.codelogy.org,2008://28.11102</id>
   
   <published>2008-09-26T02:20:12Z</published>
   <updated>2008-09-26T08:37:23Z</updated>
   
   <summary> 前回予定していましたFBX形式からメッシュやマテリアル情報を抜き出す方法ですが...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
前回予定していましたFBX形式からメッシュやマテリアル情報を抜き出す方法ですが、FBXSDKのドキュメントがあまりにも、以下略であるため、断念しました。<br>
簡単に理由をあげますと、クラスの説明がたったの英語5単語であったり、関数名がGetなのに説明がSetだったりとすさまじいものがあります。<br>
ですので今回はFBXはおいておき、モーションキャプチャデータであるBVHファイルの利用方法を考えてみたいと思います。<br>
これに対応できるMax,Mayaプラグインを近日に書きたいと思っています。<br>
既に合成を終えたわけではありませんので、間違っている部分があるかもしれません。<br>
その部分は合成が終了しだいプラグインのソースコードと一緒に公開したいと思います。<br>
</p>]]>
      <![CDATA[<p>
まずはモーションキャプチャデータの入手を行います。<br>
幸い<a href ="http://mocapdata.com/">mocapdata.com</a>さんでフリーのデータが配られていますのでこちらのDrinkモーションを使用しました。<br>
データ形式はモーションビルダーから出力される形式であるBVH形式を利用します。<br>
なぜならテキスト形式で最も構造が理解しやすいためです。<br>
<br>
それでは早速drink.bvhをエディタなどで開いてみます。<br>
<br>
</p>
<h3 class = "section">階層構造の理解</h3>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
HIERARCHY
ROOT Hips
{
  OFFSET -20.7799 39.8705 -6.41841
  CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
  JOINT LeftHip
  {
    OFFSET 3.43 -2.81208e-014 -2.13163e-014
    CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
    JOINT LeftKnee
    {
      OFFSET 0 -18.47 2.13163e-014
      CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
      JOINT LeftAnkle
      {
        OFFSET -1.06581e-014 -17.95 1.33227e-015
        CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
        End Site
        {
          OFFSET 0 -3.12 0
        }
      }
    }
  }
　...（略）
</pre>
</td>
</tr>
</table>
<p>
上から順に見ていきます。<br>
<ul>
<li>HIERARCHY<br>
スケルトンの階層構造定義の開始。</li>
<li>ROOT<br>
基点となる特殊なノード。</li>
<li>OFFSET<br>
ノードのオフセット成分。<br>
ルートノードの場合はワールド座標から、それ以外の場合は親ノードから間接ノードへのオフセット成分。<br>
モデリングソフトから抽出した基点位置を合わせるために使用。</li>
<li>CHANNELS<br>
間接自由度。<br>
X, Y, Zの位置座標、Z, X, Yの回転自由度の順に定義されています。
（今回は）<br>
もちろん、どれか1つだけの場合もあります。<br>
この指定によりトランスフォーム行列を計算することができます。<br>
<li>End<br>
階層構造末端ノード。<br>
OFFSETのみ要素を持つのですが、何に利用するのか調査中です。<br>
（Siteというノード名で普通のノードであるのか、それとも別用途であるのか）</li>
</ul>
<br>
上記を繰り返すことによって<br>
階層構造が定義されています。<br>
全ての定義が終了すると、次に座標を記録した部分があらわれます。<br>
</p>
<h3 class = "section">モーション記録情報の理解</h3>
<p>
それでは、モーション記録部を見てみましょう。

<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
MOTION
Frames:	751
Frame Time:	0.0333333
17.8378 39.6935 -4.63393 0.802098 0.0108709 -0.297077 3.43 ...（略）
</pre>
</td>
</tr>
</table>
<p>
<ul>
<li>MOTION<br>
モーション情報の記録開始部分です。</li>
<li>Frames<br>
記録されたフレーム数です<br>
今回の場合は751フレームあるようです。</li>
<li>Frame Time<br>
1フレーム更新するための時間。<br>
今回ですと0.03ですので33fpsになります。<br>
ゲーム製作の視点からですと60fpsが主流ですので、こちらはカクカクするのではないか、と思われるかもしれませんが、３Dの専門の方に聞いたところ30fpsが標準だそうですので特にモーションの隙間を補間したりする必要はなさそうです。<br>
ちなみに他のデータもダウンロードしてみましたが、ほぼ30fpsでしたので、この部分はそのまま使用することにしました。</li>
<li>タグは無し<br>
次に大量の座標、回転角が記されています。<br>
こちらは先ほどCHANNELで定義されていた順序どおりに座標、角度が記されています。<br>
ですので今回は、X, Y, Z座標、続いてZ, X, Yの回転角の順に記録されています。<br>
1行に記録されている情報は1フレームの動作に対応しています。<br>
ですので、必要なフレームからのみ抜き出す（最初のT字ポーズをはずす）といったことも可能です。</li>
</ul>
<br>
本来ですと、ここでFBXから抜き出したデータを利用して合成まで実証しようと用意していたのですが、FBXSDKから出てくる致命的エラーの前に断念してしまいました。（申し訳ありません）<br>
ですので、明日から早速Max、Mayaプラグインを開発し、合成方法を公開したいと思います。<br>
<br>
担当：松浦（FBXこわい。。。）<br>
<br>
</p>




]]>
   </content>
</entry>
<entry>
   <title>32ビット環境で64ビット整数を扱う (加法編)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/09/3264.html" />
   <id>tag:www.codelogy.org,2008://28.11027</id>
   
   <published>2008-09-04T10:00:00Z</published>
   <updated>2008-09-11T05:32:00Z</updated>
   
   <summary>   通常用いられる整数型 (32ビット符号付き) は -2,147,483,6...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="section">
  通常用いられる整数型 (32ビット符号付き) は -2,147,483,648 ～ 2,147,483,647 の範囲の値を表現することができます。<br />
  殆どのアプリケーションにおいては、この制限が問題になることはまずありません。<br />
  しかし、この範囲を超える値を扱う必要のあるアプリケーションも存在します。<br />
  <br />
  そこで考え付くのが、32ビット環境で64ビット整数を扱うための仕組みを作ることですが、実際にやってみると意外なほどに手間が掛ってしまいます。<br />
  この記事では、四則演算・10進出力などのプログラムを組むときの手順や考え方について解説していきます。
</div>

<h3 class="section">64ビット整数の表現</h3>
<div class="section">
  まず、64ビット整数を表現するための構造体を定義します。<br />
  <b>DWORD</b> (<b>unsigned</b> <b>long</b>) 

組み込みの整数型は最大で32ビットまでなので、これを 2つ組み合わせて64ビット整数を表現します。
  <table class="code">
  <tr>
    <td>
      <pre><em class="kwd">#ifndef</em> __QWORD_H__
<em class="kwd">#define</em> __QWORD_H__

<em class="cmt">//32ビット整数</em>
<em class="kwd">typedef</em> <em class="kwd">unsigned</em> <em class="kwd">long</em> <em class="usr">DWORD</em>;

<em class="cmt">//64ビット整数</em>
<em class="kwd">typedef</em> <em class="kwd">struct</em> {
    <em class="usr">DWORD</em> dwLow;  <em class="cmt">//下位32ビット</em>
    <em class="usr">DWORD</em> dwHigh; <em class="cmt">//上位32ビット</em>
} QWORD;

<em class="kwd">#undef</em> <em class="cmt">//__QWORD_H__</em>
<em class="cmt">//[EOF]</em></pre></td>
    </tr>
  </table>
  メンバ <b>dwHigh</b> の最上位ビットは符号ビットとして利用しますが、この段階では特に気にする必要はないでしょう。
</div>
]]>
      <![CDATA[<h3 class="section">32ビット値の加算と繰り上がり</h3>
<div class="section">
 2つの <b>QWORD</b> 値の和を直接計算することはできないので、これらのオブジェクトのメンバ <b>dwLow</b>, <b>dwHigh</b> を個別に足し合わせ、その結果を組み合わせてこれを求めることにしましょう。
  演算結果の下位32ビットは <b>dwLow</b> の和に等しいので、これは簡単に求められます。
  一方、演算結果の上位32ビットの値を求めるには、<b>dwHigh</b> の和に下位32ビットの加算からの「繰り上がり (carry)」を加える必要があります。<br />
<br />
  しかし、<b>DWORD</b> (32ビット) 値を単純に <code>+</code> 演算子を用いて加算したのでは、この繰り上がりの値を得ることができません。
  そこで、<b>DWORD</b> の加算を、繰り上がりの計算まで含めて行うこのとのできる関数 <b>add32</b> を以下のように定義します。
  <table class="code" style="float: left;">
  <tr>
    <td>
      <pre><em class="cmt"><em class="kwd">#define</em> <em class="usr">NULL</em> <em class="lit">0</em>

//略記用マクロ</em>
<em class="kwd">#define</em> LOWORD(dw) (<em class="lit">0xFFFFUL</em> &amp; dw)
<em class="kwd">#define</em> HIWORD(dw) (<em class="lit">0xFFFFUL</em> &amp; (dw &gt;&gt; <em class="lit">16</em>);

<em class="cmt">//32ビット整数の加算</em>
<em class="usr">DWORD</em> add32(<em class="usr">DWORD</em> dw1, <em class="usr">DWORD</em> dw2, <em class="usr">DWORD</em>* lpdwCarry =<em class="usr">NULL</em>){

    <em class="usr">DWORD</em> dwTmp1 =LOWORD(dw1) + LOWORD(dw2);
    <em class="usr">DWORD</em> dwTmp2 =HIWORD(dw1) + HIWORD(dw2) + HIWORD(dwTmp1);

    <em class="usr">DWORD</em> dwSum   =LOWORD(dwTmp1) | (dwTmp2 &lt;&lt; <em class="lit">16</em>))
    <em class="usr">DWORD</em> dwCarry =HIWORD(dwTmp2);

    <em class="cmt">//繰り上がりの格納</em>
    <em class="kwd">if</em> (lpdwCarry) *lpdwCarry =dwCarry;

    <em class="kwd">return</em> dwSum;
}</pre></td>
    </tr>
  </table>
  <div class="figure">
    【図1: 関数 <b>add32</b> の動作】<br />
    <img src="http://www.codelogy.org/archives/images/2008/09/04/0.png" alt="" /><span style="clear: left;" />
  </div>
  この関数は、繰り上がりの値を得るために、<b>DWORD</b> を上位16, 下位16ビットに分けて加算を行います。(図1)<br />
  和は戻り値として返され、繰り上がりの値は <code>lpdwCarry</code> で指定された変数に格納されます。
</div>


<h3 class="section">64ビット値の加算</h3>
<div class="section">
  前節で作成した関数 <b>add32</b> を使用して、<b>QWORD</b> (32ビット) の加算を行う関数<b>add</b> を以下のように定義します。
 <table class="code">
  <tr>
    <td>
      <pre>
<em class="cmt">//64ビット整数の加算</em>
<em class="usr">QWORD</em> add(<em class="usr">QWORD</em> qw1, <em class="usr">QWORD</em> qw2){

    <em class="usr">DWORD</em> dwCarry;

    QWORD qwSum;
    qwSum.dwLow  =add32(qw1.dwLow, qw2.dwLow, &amp;dwCarry);
    qwSum.dwHigh =add32(add32(qw1.dwHigh, qw2.dwHigh), dwCarry);

    <em class="kwd">return</em> dwSum;
}</pre></td>
    </tr>
  </table>
  下位32ビット (<b>dwLow</b>) の加算で生じた繰り上がりを <code>dwCarry</code> に格納し、これを上位32ビット (<b>dwHigh</b>) の和に加えたものを、演算結果 <code>dwSum</code> の上位32ビットとしています。
  <table class="code">
  <tr>
    <td>
      <pre><em class="kwd">#include</em> <em class="str">&lt;stdio.h&gt;</em>

<em class="kwd">int</em> main(){

    QWORD qw1;
    qw1.dwLow  =<em class="lit">0xFFFFFFFF</em>;
    qw1.dwHigh  =<em class="lit">0x00000007</em>;

    QWORD qw2;
    qw2.dwLow  =<em class="lit">0xB</em>;
    qw2.dwHigh =<em class="lit">0x8</em>;

    QWORD qwSum =add(qw1, qw2);

    printf(<em class="str">"qwSum.dwLow  =&gt; %08X\n"</em>, qwSum.dwLow);
    printf(<em class="str">"qwSum.dwHigh =&gt; %08X\n"</em>, qwSum.dwHigh);

    <em class="kwd">return</em> <em class="lit">0</em>;
}</pre></td>
    </tr>
  <tr>
    <td class="result"><pre>qwSum.dwLow  =&gt; 0000000A
qwSum.dwHigh =&gt; 00000010</pre></td>
    </tr>
  </table>
  きちんと加算が行われていることを確認して頂けたでしょうか？<br />
  次の記事では、減法を行う方法について解説する予定です。
</div>
<h3 class="section">追記</h3>
<div class="section">
  <s>暇人プロ学生</s>篤志家の nsdt さんが読みやすい図を作ってくれたよ！<br />
  　 ﾊ_ﾊ<br />
  ('(ﾟ∀ﾟ∩　ありがと！<br />
  　ヽ　　〈<br />
  　　ヽヽ_)<br />
<br />
  <img src="http://www.codelogy.org/archives/images/2008/09/04/0ex.png" alt="" />
</div>
<div class="signature">
  担当: 成田 (図を描くのが大変)
</div>
]]>
   </content>
</entry>
<entry>
   <title>連結リストを作る (1)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/09/post_12.html" />
   <id>tag:www.codelogy.org,2006://28.11014</id>
   
   <published>2008-09-01T06:00:00Z</published>
   <updated>2008-09-26T16:02:46Z</updated>
   
   <summary>   C/C++ の配列は、そのサイズをコンパイル時に決定する必要があります。 ...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="section" style="margin-bottom: 1em;">
  C/C++ の配列は、そのサイズをコンパイル時に決定する必要があります。<br />
  そのため、サイズが動的に変化するデータの格納が少々面倒だったりします。<br />
  <br />
  そこでよく用いられるのが、<a href="http://ja.wikipedia.org/wiki/%E9%80%A3%E7%B5%90%E3%83%AA%E3%82%B9%E3%83%88">連結リスト</a>と呼ばれるデータ構造です。
  殆どの環境ではライブラリとして提供されていますが、勉強もかねて自分で実装してみましょう。
</div>


<h3 class="section">設計</h3>
<div class="section" style="margin-bottom: 1em;">
  コードを書き始めるまえに、簡単な設計を行いましょう。<br />
  この段階では詳細には立ち入らず、データの構造をおおまかに決定すれば十分です。(図 1)<br />
  <div class="figure">
    <img src="http://www.codelogy.org/archives/images/2008/09/01/0.png" alt="" style="margin-bottom: 4px;"/><br />
    【図1: 連結リストの構造】
  </div>
  リストを構成するノード (node) はそれぞれ、自分の前後に位置するノードのアドレスをメンバ変数 <code>m_lpPrev</code>, <code>m_lpNext</code> に保持します。
  （始端ノードの <code>m_lpPrev</code> および、終端ノードの <code>m_lpNext</code> は<b>NULL</b>とする)。<br />
  <br />
  リストの本体 (list) は、始端および終端ノードのアドレスを <code>m_lpHead</code>, <code>m_lpTail</code> として保持します (リストが空の場合は、<code>m_lpHead</code>, <code>m_lpTail</code> は共に<b>NULL</b>とする)。<br />
  <br />
  だいたいの構造が決まったら、いよいよ実装を始めます。
</div>
]]>
      <![CDATA[					<h3 class="section">ノードの定義</h3>
<div class="section" style="margin-bottom: 1em;">
  まずは、リストのデータを保持するノード (<b>ListNode</b> クラステンプレート) を定義します。
  <table class="code">

  <tr>
    <td class="caption">ListNode.h</td>
    </tr>
  <tr><td><pre><em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//</em>
<em class="cmt">//  ListNode.h</em>
<em class="cmt">//</em>

<em class="kwd">#ifndef</em> __LISTNODE_H__
<em class="kwd">#define</em> __LISTNODE_H__

<em class="kwd">#include</em> <em class="str">&lt;assert.h&gt;</em>

<em class="kwd">#ifndef</em> <em class="usr">NULL</em>
<em class="kwd">#define</em> <em class="usr">NULL</em> <em class="lit">0</em>

<em class="kwd">#endif</em>

<em class="cmt">//略記用マクロ</em>
<em class="kwd">#define</em> LPCNODE   <em class="kwd">const</em> ListNode&lt;T&gt;*
<em class="kwd">#define</em> LPNODE    ListNode&lt;T&gt;*

<em class="kwd">#define</em> _TEMPLATE <em class="kwd">template</em> &lt;<em class="kwd">typename</em> T&gt;

<em class="cmt">//プロトタイプ宣言</em>
_TEMPLATE <em class="kwd">class</em> List;

<em class="cmt">//リストノード</em>

_TEMPLATE <em class="kwd">class</em> ListNode {
    <em class="kwd">friend</em> <em class="kwd">class</em> List&lt;T&gt;;
<em class="kwd">public</em>:

    T   value; <em class="cmt">//ノード値</em>

    <em class="cmt">//construction</em>

    ListNode(LPNODE lpPrev, LPNODE lpNext, <em class="kwd">const</em> T&amp; value);

    <em class="cmt">//member access (getting)</em>
    LPNODE  Prev();
    LPCNODE Prev() <em class="kwd">const</em>;
    LPNODE  Next();
    LPCNODE Next() <em class="kwd">const</em>;

<em class="kwd">protected</em>:

    LPNODE  m_lpPrev; <em class="cmt">//前ノードのアドレス</em>

    LPNODE  m_lpNext; <em class="cmt">//次ノードのアドレス</em>

};

<em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//construction</em>

<span id="t20080901-impl1" style="display: none;"><em class="cmt">//コンストラクタ</em>
_TEMPLATE ListNode&lt;T&gt;::ListNode(LPNODE lpPrev, LPNODE lpNext, <em class="kwd">const</em> T&amp; value)
: m_lpPrev(lpPrev), m_lpNext(lpNext), value(value) {
}</span><span id="t20080901-impl1s"><a href="javascript: showImplement(1);">▼実装部を表示</a></span>


<em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//member access (getting)</em>

<span id="t20080901-impl2" style="display: none;"><em class="cmt">//前ノードアドレス</em>
_TEMPLATE LPNODE ListNode&lt;T&gt;::Prev() {
    <em class="kwd">return</em> m_lpPrev;
}

<em class="cmt">//前ノードアドレス (const)</em>

_TEMPLATE LPCNODE ListNode&lt;T&gt;::Prev() <em class="kwd">const</em> {
    <em class="kwd">return</em> m_lpPrev;
}

<em class="cmt">//次ノードアドレス</em>
_TEMPLATE LPNODE ListNode&lt;T&gt;::Next() {
    <em class="kwd">return</em> m_lpNext;
}


<em class="cmt">//次ノードアドレス (const)</em>
_TEMPLATE LPCNODE ListNode&lt;T&gt;::Next() <em class="kwd">const</em> {
    <em class="kwd">return</em> m_lpNext;
}</span><span id="t20080901-impl2s"><a href="javascript: showImplement(2);">▼実装部を表示</a></span>


<em class="cmt">//略記用マクロ解除</em>

<em class="kwd">#undef</em> LPCNODE
<em class="kwd">#undef</em> LPNODE
<em class="kwd">#undef</em> _TEMPLATE

<em class="kwd">#endif</em> <em class="cmt">//__LISTNODE_H__</em>
<em class="cmt">//[EOF]</em></pre></td>
    </tr>

  </table>
  <code>m_lpPrev</code>, <code>m_lpNext</code> はユーザに勝手に書き換えられては困るので、<b>protected</b> とし、アクセス用のメンバ関数 <b>Prev</b>, <b>Next</b> を作っておきます。
</div>


<h3 class="section">リストの定義</h3>
<div class="section" style="margin-bottom: 1em;">
  次に、この連結されたノード列を管理するためのクラス <b>List</b> を作成します。<br />
  実際にはここで記述されるもの以外の機能も必要ですが、今回は次節のサンプルコードの動作に最低限必要なものだけを実装します。
  <table class="code">
  <tr>
    <td class="caption">List.h</td>

    </tr>
  <tr><td><pre><em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//</em>
<em class="cmt">//  List.h</em>
<em class="cmt">//</em>

<em class="kwd">#ifndef</em> __LIST_H__
<em class="kwd">#define</em> __LIST_H__


<em class="kwd">#include</em> <em class="str">"ListNode.h"</em>


<em class="cmt">//略記用マクロ</em>
<em class="kwd">#define</em> LPCNODE   <em class="kwd">const</em> ListNode&lt;T&gt;*
<em class="kwd">#define</em> LPNODE    ListNode&lt;T&gt;*

<em class="kwd">#define</em> _TEMPLATE <em class="kwd">template</em> &lt;<em class="kwd">typename</em> T&gt;


_TEMPLATE <em class="kwd">class</em> List {
<em class="kwd">public</em>:

    <em class="kwd">const</em> <em class="kwd">int</em>&amp; size;

    <em class="cmt">//construction</em>

    List();
    List(<em class="kwd">const</em> List&lt;T&gt;&amp;);

    <em class="cmt">//destruction</em>
    <em class="kwd">virtual</em> ~List();

    <em class="cmt">//operator</em>
    List&lt;T&gt;&amp; <em class="kwd">operator</em> = (<em class="kwd">const</em> List&lt;T&gt;&amp;);
    T&amp;       <em class="kwd">operator</em> [] (<em class="kwd">int</em> nIndex) ;
    <em class="kwd">const</em> T&amp; <em class="kwd">operator</em> [] (<em class="kwd">int</em> nIndex) <em class="kwd">const</em>;

    <em class="cmt">//operation</em>

    LPNODE  Append(<em class="kwd">const</em> T&amp;);


<em class="kwd">protected</em>:

    LPNODE  m_lpHead; <em class="cmt">//始端ノードのアドレス</em>
    LPNODE  m_lpTail; <em class="cmt">//終端ノードのアドレス</em>
    <em class="kwd">int</em>     m_nSize;  <em class="cmt">//要素数</em>

    <em class="cmt">//operation</em>
    LPNODE  GetLPNode(<em class="kwd">int</em> nIndex);
    LPCNODE GetLPNode(<em class="kwd">int</em> nIndex) <em class="kwd">const</em>;

<em class="kwd">private</em>:

    <em class="cmt">//destruction</em>

    <em class="kwd">void</em>    Destroy();

};


<em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//construction</em>

<span id="t20080901-impl3" style="display: none;"><em class="cmt">//コンストラクタ</em>
_TEMPLATE List&lt;T&gt;::List()
: m_lpHead(<em class="usr">NULL</em>), m_lpTail(<em class="usr">NULL</em>), m_nSize(<em class="lit">0</em>), size(m_nSize) {
}


<em class="cmt">//コンストラクタ</em>
_TEMPLATE List&lt;T&gt;::List(<em class="kwd">const</em> List&lt;T&gt;&amp; l)
: size(m_nSize) {

    <em class="kwd">if</em> (l.m_nSize){

        LPCNODE p     =l.m_lpHead;
        <em class="kwd">int</em>     nSize =l.m_nSize;

        LPNODE lpHead =<em class="kwd">new</em> ListNode&lt;T&gt;(NULL, NULL, p-&gt;value);
        LPNODE lpTail =lpHead;

        <em class="kwd">while</em> (p =p-&gt;m_lpNext){
            lpTail =lpTail-&gt;m_lpNext =<em class="kwd">new</em> ListNode&lt;T&gt;(lpTail, <em class="usr">NULL</em>, p-&gt;value);
        }

        m_lpHead =lpHead;
        m_lpTail =lpTail;
        m_nSize  =nSize;
    }
    <em class="kwd">else</em> {
        m_lpHead =<em class="usr">NULL</em>;
        m_lpTail =<em class="usr">NULL</em>;
        m_nSize  =<em class="lit">0</em>;
    }
}</span><span id="t20080901-impl3s"><a href="javascript: showImplement(3);">▼実装部を表示</a></span>


<em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//destruction</em>

<span id="t20080901-impl4" style="display: none;"><em class="cmt">//デストラクタ</em>
_TEMPLATE List&lt;T&gt;::~List(){
    Destroy();
}

<em class="cmt">//オブジェクトの破棄 [for internal use]</em>
_TEMPLATE <em class="kwd">void</em> List&lt;T&gt;::Destroy(){

    LPNODE p =m_lpHead;
    <em class="kwd">while</em> (p){

        LPNODE q =p->m_lpNext;

        <em class="kwd">delete</em> p;

        p =q;
    }

    <em class="kwd">return</em>;
}</span><span id="t20080901-impl4s"><a href="javascript: showImplement(4);">▼実装部を表示</a></span>


<em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//operator</em>

<span id="t20080901-impl5" style="display: none;"><em class="cmt">//代入</em>
_TEMPLATE List&lt;T&gt;&amp; List&lt;T&gt;::<em class="kwd">operator</em> = (<em class="kwd">const</em> List&lt;T&gt;&amp; l){

    <em class="kwd">if</em> (l.m_nSize){

        LPCNODE p     =l.m_lpHead;
        <em class="kwd">int</em>     nSize =l.m_nSize;

        LPNODE lpHead =<em class="kwd">new</em> ListNode&lt;T&gt;(<em class="usr">NULL</em>, <em class="usr">NULL</em>, p->value);
        LPNODE lpTail =lpHead;

        <em class="kwd">while</em> (p =p->m_lpNext){
            lpTail =lpTail->m_lpNext =<em class="kwd">new</em> ListNode&lt;T&gt;(lpTail, <em class="usr">NULL</em>, p->value);
        }

        Destroy();

        m_lpHead =lpHead;
        m_lpTail =lpTail;
        m_nSize  =nSize;
    }
    <em class="kwd">else</em> {

        Destroy();

        m_lpHead =<em class="usr">NULL</em>;
        m_lpTail =<em class="usr">NULL</em>;
        m_nSize  =<em class="lit">0</em>;
    }

    <em class="kwd">return</em> *<em class="kwd">this</em>;
}


<em class="cmt">//要素参照</em>
_TEMPLATE <em class="kwd">inline</em> T&amp; List&lt;T&gt;::<em class="kwd">operator</em> [] (<em class="kwd">int</em> nIndex){
    assert(<em class="lit">0</em> &lt;= nIndex &amp;&amp; nIndex &lt; m_nSize);
    <em class="kwd">return</em> GetLPNode(nIndex)->value;
}


<em class="cmt">////要素参照 (const)</em>
_TEMPLATE <em class="kwd">inline</em> <em class="kwd">const</em> T&amp; List&lt;T&gt;::<em class="kwd">operator</em> [] (<em class="kwd">int</em> nIndex) <em class="kwd">const</em> {
    assert(<em class="lit">0</em> &lt;= nIndex &amp;&amp; nIndex &lt; m_nSize);
    <em class="kwd">return</em> GetLPNode(nIndex)->value;
}</span><span id="t20080901-impl5s"><a href="javascript: showImplement(5);">▼実装部を表示</a></span>


<em class="cmt">////////////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">//operation</em>

<span id="t20080901-impl6" style="display: none;"><em class="cmt">//要素の追加</em>
_TEMPLATE LPNODE List&lt;T&gt;::Append(<em class="kwd">const</em> T&amp; value){

    LPNODE lpNode;

    <em class="kwd">if</em> (m_lpTail){

        lpNode =<em class="kwd">new</em> Node(m_lpTail, <em class="usr">NULL</em>, value);

        m_lpTail =m_lpTail->m_lpNext =lpNode;
        ++m_nSize;
    }
    <em class="kwd">else</em> {

        lpNode =<em class="kwd">new</em> Node(<em class="usr">NULL</em>, <em class="usr">NULL</em>, value);

        m_lpHead =lpNode;
        m_lpTail =lpNode;
        m_nSize  =<em class="lit">1</em>;
    }

    <em class="kwd">return</em> lpNode;
}


<em class="cmt">//ノードアドレスの取得 [for internal use]</em>
_TEMPLATE LPNODE List&lt;T&gt;::GetLPNode(<em class="kwd">int</em> nIndex){
    assert(<em class="lit">0</em> &lt;= nIndex &amp;&amp; nIndex &lt; m_nSize);

    LPNODE p =m_lpHead;

    <em class="kwd">int</em> i;
    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;nIndex; ++i) p =p->m_lpNext;

    <em class="kwd">return</em> p;
}


<em class="cmt">//ノードアドレスの取得 (const) [for internal use]</em>
_TEMPLATE LPCNODE List&lt;T&gt;::GetLPNode(<em class="kwd">int</em> nIndex) <em class="kwd">const</em> {
    assert(<em class="lit">0</em> &lt;= nIndex &amp;&amp; nIndex &lt; m_nSize);

    LPCNODE p =m_lpHead;

    <em class="kwd">int</em> i;
    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;nIndex; ++i) p =p->m_lpNext;

    <em class="kwd">return</em> p;
}</span><span id="t20080901-impl6s"><a href="javascript: showImplement(6);">▼実装部を表示</a></span>


<em class="cmt">//略記用マクロ解除</em>
<em class="kwd">#undef</em> LPNODE
<em class="kwd">#undef</em> _TEMPLATE

<em class="kwd">#endif</em> <em class="cmt">//__LIST_H__</em>
<em class="cmt">//[EOF]</em></pre></td>
    </tr>

  </table>
</div>


<h3 class="section">使ってみる</h3>
<div class="section" style="margin-bottom: 1em;">
  このリストを利用した簡単なプログラムを作成し、動作テストを行います。
  <table class="code">
  <tr>
    <td><pre>
<em class="kwd">#include</em> <em class="str">&lt;stdio.h&gt;</em>

<em class="kwd">#include</em> <em class="str">"List.h"</em>

<em class="kwd">int</em> main(){

    List&lt;<em class="kwd">char</em>&gt; list;

    <em class="cmt">//読み込み</em>

    <em class="kwd">for</em> (;;){

        <em class="kwd">int</em> n =getc(stdin);
        <em class="kwd">if</em> (n == EOF) <em class="kwd">break</em>;

        list.Append(<em class="kwd">static_cast</em>&lt;<em class="kwd">char</em>&gt;(n));
    }

    <em class="cmt">//出力</em>

    <em class="kwd">int</em> i;
    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;list.size; ++i){
        putc(list[i], stdout);
    } <em class="cmt">//i</em>

    <em class="kwd">return</em> <em class="lit">0</em>;
}</pre></td>

    </tr>
<tr>
  <td class="result">
    <em class="inp">Truth is always bitter to those who fear it.<b>[LF]</b></em><br />
    <em class="inp"><b>[EOF]</b></em><br />
    Truth is always bitter to those who fear it.</td>
  </table>

  このとおり、任意長の長さのデータをメモリ上に読み込むことができます。<br />
  <br />
  次回は、要素の挿入・削除といった動作のためのメンバ関数の作成を行います。<br />
  <br />
  担当: 成田
</div>
<script type="text/javascript">
<!--
//実装部の表示
function showImplement(num){

  var e1 =document.getElementById("t20080901-impl" + num);
  var e2 =document.getElementById("t20080901-impl" + num + "s");

  e1.style.display ="inline";
  e2.style.display ="none";

  return;
}

//-->
</script>
]]>
   </content>
</entry>
<entry>
   <title>3Dモデルファイルの独自形式制作（１回目）</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/08/3d.html" />
   <id>tag:www.codelogy.org,2008://28.10908</id>
   
   <published>2008-08-01T03:03:33Z</published>
   <updated>2008-08-01T07:21:17Z</updated>
   
   <summary> 3D系プログラムをしていると、どうしてもついて回るのが読み込みモデリングファイ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
3D系プログラムをしていると、どうしてもついて回るのが読み込みモデリングファイルの形式です。<br>
私は普段DirectXを使っていますので、標準形式のXFileを使えばよいではないかということになりそうですが、XFileの方言はひどいものがある上に上位にあたるXNAではXFileをサポートしないといったことになっており散々です。<br>
よくデザイナーさんが使うmaya, 3ds max, LightWave3Dなどのソフトがありますが、それぞれのエクスポーターで出力するXFileも方言があり、Root Frameにアニメーション情報を含んだり、含まなかったり、メッシュの名前をつけたりつけなかったりと様々です。<br>
（他にもアニメーションの名前をつけたりつけなかったりするものまで・・・）<br>
当然標準のビューアのみで対応できるはずもなく、マテリアル色がおかしくなったり、アニメーションが壊れたり、描画すらされなかったりといった結果になります。<br>
<br>
それぞれのソフトに対応したエクスポーターを書いてもよいのですが、現在進行中プロジェクトではmaya, max, light waveすべてからのデータが送られてくるため、３つもエクスポータを書くのはさすがに無理です。<br>
ですので、これらの問題を埋めるためにAutodesk社が標準とするFBXというファイル形式から必要な情報を抜き出し独自形式にコンバートしたいと思います。<br>
<br>
今回はお仕事用としてのメモも兼ねますので、すぐに次の情報をアップしたいと思います。今回はFBXのパース、バージョンが上がったSDKの使い方がメインです。<br>
</p>]]>
      <![CDATA[<p>
FBXにはAutodesk社が提供しているFBX SDKなるものがあり簡単にパース、エクスポートできる・・・はずなのですが、標準でメモリリークをしたり、デバイスハンドラを作成するだけのプログラムでwarningが300以上出たりと黒い話が絶えません。(200611)<br>
そしてこのたび2009.1という（恐らく2009年1月バージョン）未来バージョンらしきものにバージョンアップされましたので使用してみることにしました。<br>
</p>

<h3 class = "section">ビルド前設定</h3>
とりあえず昔作ったパーサをビルドしようとすると、全く動きません。何やらビルド前オプションやインクルードディレクトリにも変更があったようですので設定を行います。<br>
以下VisualStudio 2005の設定です。<br>

<ul>
<li>追加のインクルードファイルパスに\Autodesk\FBX\FbxSdk\2009.1\include; \Autodesk\FBX\FbxSdk\2009.1\include\kbaselib;を設定</li>
<li>ライブラリファイルパスに\Autodesk\FBX\FbxSdk\2009.1\libを設定</li>
<li>追加の依存ファイルにfbxsdk_md2005d.libを設定</li>
<li>プリプロセッサ定義 : WIN32;_DEBUG;_CONSOLEK_PLUGIN;K_FBXSDK;K_NODLL;_CRT_SECURE_NO_DEPRECATE</li>
</ul>

なぜライブラリ内ですらインクルードファイルパスが相対で書かれてないのかとか、コマンド引数を指定しないとデバイスハンドラ作成メソッドすら使えないのかとか、色々言いたいことはありあますが、とりあえず設定はこれで大丈夫です。<br>
また、今回からUnicode文字セットが使えるようになりました。<br>
日本語ディレクトリ名が存在すると読み込めないのは相変わらずのようです。<br>
また、日本語ディレクトリが存在してファイルが読み込めなかった場合、ファイルが存在しないエラーではなく、サポートしていないファイル形式エラーを返してくるので注意が必要です<br><br>

<h3 class = "section">何はともあれインポート（読み込み）</h3>
<p>
バージョンアップにより各種オブジェクト生成関数名、ファイルフォーマット定義マクロ、オブジェクト作成方法など色々変更されましたので旧バージョンのままだとやはり使えません。<br>
<br>
以前のバージョンでは全体の管理クラスであるKFbxSdkManagerオブジェクトの作成にKFbxSdkManager::CreateKFbxSdkManagerメソッドを使用していましたが今回からメソッド名が変わりました。<br>
まずこのオブジェクト生成と同時にインポートしてくる情報を受け取るためのKFbxSceneオブジェクトを生成します。<br>
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
KFbxSdkManager *pSdkManager = NULL; 
KFbxScene      *pScene = NULL;

pSdkManager = KFbxSdkManager::Create();
pScene = KFbxScene::Create(pSdkManager, <em class="str">""</em>);
</pre>
</td>
</tr>
</table>
<p>
続いてインポータオブジェクトを生成します。<br>
ここではファイルフォーマットの設定を行いますが、ここも旧バージョンとは違い直接ASCII文字やバイナリコードであることを示すためのマクロがKFbxImporterからなくなっています。<br>
またKFbxStreamOptionsFbxReaderというインポート用オプションが追加され、以前はKFbxImporterで設定していた読み込むべきデータをこちらで設定することになります。<br>
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">// インポータ作成</em>
KFbxImporter* pImporter = KFbxImporter::Create(pSdkManager, <em class="str">""</em>);

<em class="cmt">// インポートする情報を設定するオプション</em>
KFbxStreamOptionsFbxReader* lImportOptions=KFbxStreamOptionsFbxReader::Create(pSdkManager, <em class="str">""</em>);

<em class="cmt">// ファイルフォーマットをファイルから取得</em>
<em class="kwd">if</em>(!pSdkManager-&gt;GetIOPluginRegistry()-&gt;DetectFileFormat(file, iFileFormat)) {
    <em class="cmt">// ファイルフォーマット取得に失敗した場合</em>
    iFileFormat = pSdkManager-&gt;GetIOPluginRegistry()-&gt;GetNativeReaderFormat();
}

<em class="cmt">// インポータにファイルフォーマットを設定</em>
pImporter-&gt;SetFileFormat(iFileFormat);

<em class="cmt">// インポータ初期化</em>
<em class="kwd">const</em> <em class="kwd">bool</em> bImportStatus = pImporter-&gt;Initialize(file);

<em class="cmt">// ファイルバージョンを取得</em>
pImporter-&gt;GetFileVersion(iFileMajor, iFileMinor, iFileRevision);

<em class="kwd">if</em>(!bImportStatus) {  <em class="cmt">// インポータ初期化失敗の場合エラーを表示</em>
    puts(<em class="str">"FBXImporterの初期化に失敗しました\n"</em>);
    printf(<em class="str">"エラー内容: %s\n\n"</em>, pImporter-&gt;GetLastErrorString());

    <em class="kwd">if</em>(pImporter-&gt;GetLastErrorID() == KFbxIO::eFILE_VERSION_NOT_SUPPORTED_YET || 
        pImporter-&gt;GetLastErrorID() == KFbxIO::eFILE_VERSION_NOT_SUPPORTED_ANYMORE) 
    {
        puts(<em class="str">"FBX SDK 2009.1がサポートしていないバージョンのファイルです\n"</em>);
    }
}
</pre>
</td>
</tr>
</table>

<p>
いよいよデータ取得に入ります。<br>
今回はノードをたどり必要情報を抜き出すところまではやりませんのでオプションを設定し、シーンオブジェクトに必要情報をロードするだけです。<br>
</p>

<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">// インポートする情報を設定</em>
<em class="cmt">// とりあえずパースしたいので全てtrueで必要情報は全部読み込みます</em>
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_MATERIAL, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_TEXTURE, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_LINK, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_SHAPE, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_GOBO, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_ANIMATION, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_GLOBAL_SETTINGS, <em class="kwd">true</em>);

bStatus = pImporter->Import(pScene, lImportOptions);
</pre>
</td>
</tr>
</table>

<p>
これでシーンオブジェクトの中に必要情報が格納されました。<br>
最後に後片付けを行います
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
lImportOptions->Destroy();
lImportOptions = NULL;
pImporter->Destroy();
pSdkManager->Destroy();
pSdkManager = NULL;
</pre>
</td>
</tr>
</table>
<p>
次回はシーンオブジェクトから必要情報を抜き出作業になります。<br>
また今回作成したファイルはこちらです。<br>
<a href="http://www.codelogy.org/FBXImporter.cpp">ファイルをダウンロード</a><br>
<br>
担当：松浦（３Ｄ標準形式ｷﾃｸﾚｰ！）
</p>]]>
   </content>
</entry>

</feed>
