SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ActionScriptによるWebの3Dグラフィックス再入門

ActionScriptによるWebの3Dグラフィックス再入門 (2) - シェーディングでもっと3Dらしく

フラットシェーディングの仕組みと、ActionScriptにおけるパッケージ化


AS3におけるパッケージ

 パッケージという言葉は、Javaプログラマにはなじみ深いかもしれません。意味自体もJavaと同じです。関連性のあるプログラムをひとまとまりに、具体的に言えばフォルダにまとめることをパッケージ化と言います。

 サンプルプログラムのStep 1を開いてみてください。プロジェクトの中は次のようになっています。

パッケージのフォルダ構造
パッケージのフォルダ構造

 今まではsrcフォルダ(FlashDevelop3 Beta5以前ではclassesフォルダ)のすぐ下にActionScriptのファイルがありましたが、今回はcoordzというフォルダが新しくできており、その中にTriangle.as、Vector3.asが入っています。このcoordzをパッケージと言います。このcoordzという名前は、Coordinate Z(座標Z)という意味で付けてみました。何かに似ている響きですが気のせいです。

パッケージ名の付け方
 パッケージの名前には、その製作者や企業が持つドメインが使われることが一般的です。例えばAdobeが公開しているas3corelibというパッケージの場合だと、画像関係のライブラリはcom.adobe.imagesに、ネットワーク関係のライブラリはcom.adobe.netに入っています。その場合のフォルダ構成は、まずcomというフォルダがあり、その中にadobeというフォルダが、さらにその中にimagesやnetというフォルダがあります。
絶対にドメインをパッケージ名に使わなければならないというわけではないので、今回は簡単にcoordzというパッケージ名を使っていますが、もしドメインを持っているような場合、特にオープンソースとして外部に公開するようなプログラムを開発をする場合は、パッケージ名の重複を防ぐためにドメイン名を使うべきでしょう。

 FlashDevelopでデフォルトのプロジェクトを作った場合、srcフォルダに作られたクラスは無名のパッケージに入ります。例えばデフォルトで作られるMainクラスがそれにあたります。srcフォルダの下にフォルダを作っていくと、そこがパッケージになります。フォルダ上で右クリックし、「Add」-「New Folder...」を選べばフォルダが作れます。

パッケージの作成
パッケージの作成

 この中にクラスを作ることになるわけですが、単にフォルダに入れただけではパッケージに入れたことにはなりません。プログラム側でもpackage文を使って明示する必要があります。例えば、Triangle.asのクラス定義はpackage coordz { ... }に囲まれています。

package coordz {
    // ...
    public class Triangle {
        // ...
    }
}

 このように囲むことで、Triangleクラスがcoordzパッケージに入っていることを明示しています。今までのクラスは

package {
    public class Hoge { ... }
}

 というようになっていましたが、これは無名のパッケージに入っていたということです。また、大抵の場合はflash.displayというようにパッケージ名にドットが入っていますが、この場合は「flash.display」というフォルダにクラスが入っているのではなく、「flash」フォルダの中の「display」フォルダの中にクラスが入っています。

 幸い、FlashDevelopの機能を使ってクラスを作れば、自動的にパッケージが指定されます。パッケージ内のクラスを作るときには、作りたいパッケージの上で右クリックし、[Add]-[New Class...]を選べばクラスが作れます。

クラスの作成
クラスの作成

 パッケージの作り方、またパッケージ内のクラスの作り方は以上です。次はパッケージを使う側について説明します。

 ActionScriptのプログラムを見ていると、上のほうにimport flash.display.Sprite;などといった行がいくつもあるのが目立ちます。これがパッケージを使うのに必要なimport文です。import flash.display.Sprite;の場合は、flash.displayパッケージ内のSpriteクラスを使うことを表しています。

 import文が必要になるのは、そのクラスが属しているパッケージ以外のクラスを使う必要がある場合です。例えばMainクラスの場合は無名のパッケージに属しているので、何らかのパッケージに属しているクラスを使う場合は常にimport文が必要になります。以下は実際にMain.asに書かれているimport文です。

import coordz.Triangle;
import coordz.Vector3;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.ui.Keyboard;

 coordzパッケージ内のクラスをはじめとして、いくつかのパッケージのクラスを使っていますよというimport文が書かれています。

 通常、これらの文を直接書くことはありません。クラスを使ったときにFlashDevelopが勝手に追加してくれます。ただしクラスの定数、例えばKeyboard.LEFTなどだけを使う場合には、Keyboardクラスに関するimport文が勝手に追加されません。そのような場合は、自分で書くか、一度new Keyboardと書いてimport文を生成した後、newしたところを消すなどしてください。ちなみに一度生成されたimport文が勝手に消えることはありません。

 また、TriangleクラスではVector3クラスを使っていますが、こちらはimport文がありません。理由は、両方のクラスが同じパッケージに入っているからです。同じパッケージ内のクラスを使うのであれば、import文は不要です。

Triangleクラスを使った4面体の表現

 ここからはプログラムの中身の話です。4面体のデータは、Mainクラスのプライベート変数として次のように書いています。

// 頂点データ
private var vertices:Array = [
    new Vector3( 0,  1,  0), // 頂点A
    new Vector3(-1, -1,  1), // 頂点B
    new Vector3( 1, -1,  1), // 頂点C
    new Vector3( 0, -1, -1)  // 頂点D
];

// 4面体
private var tetrahedral:Array = [
    new Triangle(vertices[0], vertices[1], vertices[2]),
    new Triangle(vertices[0], vertices[2], vertices[3]),
    new Triangle(vertices[0], vertices[3], vertices[1]),
    new Triangle(vertices[3], vertices[2], vertices[1])
];

 まず4面体の頂点座標をすべてverticesに入れてしまいます。これらの頂点座標を使った三角形4つからなる配列が、4面体を表すtetrahedralです。参考のために、先ほどの頂点座標を再度載せておきます。

4面体の頂点座標
4面体の頂点座標

 では、Triangleクラスについて詳しく説明します。

 Triangleクラスには、三角形の頂点座標を表すVector3型の変数v0v1v2があります。これらは三角形の表から見て反時計回りに並んでいるものとします。線を引くだけであれば表も裏も関係ないのでどちら回りでも関係ありませんが、後で法線の概念が出てくるときに重要になることなので、反時計回りと決めておきます。それぞれの頂点座標はコンストラクタで指定しています。

 Triangleクラスのメソッドには、三角形を描くrender、回転させるrotateXrotateYrotateZ、平行移動させるtranslateがあります。例えば、renderメソッドは次のようになっています。

Triangle.as
public function render(graphics:Graphics):void {
    graphics.lineStyle(5, 0x0088FF);
    
    // v0 -> v1 -> v2 -> v0の順に三角形を描く
    var point:Point = v0.project();
    graphics.moveTo(point.x, point.y);
    point = v1.project();
    graphics.lineTo(point.x, point.y);
    point = v2.project();
    graphics.lineTo(point.x, point.y);
    point = v0.project();
    graphics.lineTo(point.x, point.y);
}

 前回は頂点が配列に入っていたのでfor文を使った書き方でしたが、今回は配列ではなくv0v1v2が頂点の座標なので、そこを1つずつたどって線を引いています。3次元空間上の頂点であるv0を2次元平面に投影する処理は、Vector3クラスのprojectメソッドで行っています。ここの内容は前回と大差ありません。

 rotateXなどの回転メソッドや、移動させるtranslateメソッドについても、実際の計算はVector3クラスが行っています。これらのメソッドは、引数に与えた角度や移動量だけ回転、移動させた座標値を返します。

実行結果

 Step 1のプログラムを実行すると、最初に頂点座標を説明するときに使った画像が出てきます。

Step 1の結果
Step 1の結果

 実際に実行して回してみたりすれば、3Dらしさを感じられると思いますが、問題もあります。今はまだ4面体なので線の数も少ないですが、形が複雑になってくると線が大量に引かれて分かりにくくなることが想像できます。もう少し見やすくするために、次のステップでは面を塗りつぶす処理を加えます。

次のページ
Step 2 - シェーディング

この記事は参考になりましたか?

ActionScriptによるWebの3Dグラフィックス再入門連載記事一覧
この記事の著者

rch850/りちゃ(リチャ)

気になった技術をいろいろとつまみ食いしてます。覚えた技術をうまく組み合わせて面白いものができたらいいなと思います。twitter: @rch850

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2235 2008/09/05 11:02

おすすめ

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー