【C4】 テクニカルケーススタディ

慶應義塾大学大学院 理工学研究科
藤代研究室 研究生 中山 雅紀

中山雅紀

身分 ①
ž 慶應義塾大学大学院 理工学研究科

藤代 一成

ž 藤代研究室 研究生— 球面幾何に基づく情報処理— 球面ディスプレイ
— フォトリアルレンダリング— 立体視映像慶應義塾大学 矢上キャンパス

身分 ②和洋女子大学

ž 和洋女子大学 講師

山本 高美— アパレルＣＡＤž 山本研究室 共同研究者— ３Ｄアパレルデザイン② 人体形状分析アプリケーション① 3D スキャナ

人体 3D モデル

断面輪郭データ前面④ 縫製⑤ スカート着装

スカートパターン③ スカート原型プラグイン

身分 ③
ž 日蓮宗 玉泉山 安国院 副住職— テレビ朝日「ちい散歩」で 故･地井武男 さんも参詣

中山雅紀

中学時代
ž 「フラクタル幾何学」に出会う— 名著『フラクタルとは何か』
ž ＣＧの美しさに魅せられる— 教育用プログラミング言語「LOGO」

高校時代 ①
ž Delphi に出会う
ž 複素系フラクタルに魅せられる

高校時代 ②
ž 「レンダリング」事始め— Z-Buffer法大学時代 ①ž 「ステレオグラム」の描画に成功— 宝島社からオファー

大学時代 ②
ž フラクタルも進化— 画質にこだわり始める中山雅紀

『 孔雀 』
ž 複素系フラクタルへのテクスチャマッピング

『 果てを越える空 』
ž ブラックホールによる時空歪みの可視化
曲線レイトレーシング

『 摂理の明窓 』
ž ２次元陰関数の適応メッシュ分割
ドロネー図

『 sprout of cosmos 』
ž リーマン球面による複素系フラクタルの立体化

『 夢限燈華 』
ž Buddhabrot の探求『 captive julia 』
ž ３Ｄジュリア集合のポリゴン化
ž ３次元陰関数の適応メッシュ分割

『 shelling julia 』
ž ３Ｄプリンタによる具現化

『 FLOSVOLARE 』
ž マンデルブロ集合のスペクトル可視化

中山雅紀

学士研究
ž 『微粒子形状に基づく大気散乱光シミュレーション』— 雪の基本結晶「氷晶」による太陽光散乱現象を再現

修士研究
ž 『関与媒体における複雑な散乱光のレンダリング』— 散乱特性を球面ウェーブレットで情報圧縮

現行研究 ①
ž 球面幾何に基づく情報処理— 曲面生成— モーションデータ処理— 球面データ構造現行研究 ②
ž 球面ディスプレイ

— ２０面体をベース— ㈱五藤光学研究所

現行研究 ③ž ３Ｄアパレルデザイン— 3Ｄスキャナによる人体計測— 和洋女子大学 山本研究室

現行研究 ④
ž 学習/研究に適した レイトレーシング フレームワーク

藤代研究室

研究分野
ž フォトリアリティ
ž ユーザーインタフェース
ž ビジュアライゼーション

藤代研究室金子徳秀
ž 『葉脈パターンを反映した虫食い跡をもつ葉のビジュアルシミュレーション』— 葉の生物学特性に基づいた虫食いシミュレーション

佐野昂洋
ž 『大規模半構造データに対する環境可視化システムの提案』— 内包構造や階層構造を持つデータの閲覧システム

芳賀直樹
ž 『基礎的リズムパターンにおけるグルーヴの可視化』— 音楽におけるグルーブ感の品質解析北見 翔

𝒑𝒑1

𝒏𝒏1

𝒏𝒏2

𝜃𝜃𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟 𝒑𝒑3 𝜃𝜃𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐

𝒑𝒑2

ž 『布における折り目生成のビジュアルシミュレーション』— 繊維の塑性特性

コンタクトž 中山雅紀— サイト ： http://www.luxidea.net— メール ： contact@luxidea.net— facebook： http://www.facebook.com/luxidea— YouTube ： http://www.youtube.com/luxidea— Twitter ： https://twitter.com/luxidea
ž 藤代研究室— サイト ： http://www.fj.ics.keio.ac.jp— メール ： contact@fj.ics.keio.ac.jp○ 藤代一成： fuji@fj.ics.keio.ac.jp○ 中山雅紀： nakayama@fj.ics.keio.ac.jp— facebook： http://www.facebook.com/fujishiro.lab— YouTube ： http://www.youtube.com/fujishirolab

FireMonkey テクニック意義ž 2D/3D GUI フレームワーク
ž マルチプラットフォーム— OS固有APIからの脱却
ž CG と GUI の融合

CG と UI
ž 両者ともツリー構造で表現できる
床

机

コップ

赤リンゴ

TFrom

椅子

皿

人間

青リンゴ

ＣＧにおけるオブジェクトの関係

TGroupBox

TLabelTPanelTViewport3D

TSphereTButtonTCube

ＵＩにおけるコンポーネントの関係

床シーングラフ木材

ž シーン構造を各種ノードの前
40cm

後40cm

机

椅子

上70cm

肌非循環有向グラフ（ＤＡＧ）として表現— オブジェクトノード— 座標変換ノード— マテリアル（質感）ノード

複数の親でインスタンス(コピー)を表現

ガラス

陶器

上40cm

コップ

皿

人間

左10cm

緑

赤右10cmリンゴ

シーングラフ @ FireMonkey
ž ツリー構造

床木材— 複数の親を持たない
ž 座標変換は前40cm

オブジェクトと統合ž マテリアルはツリーに上70cm含まれない

後40cm
陶器机

上40cm

上70cm

コップ

— 下流には椅子

皿

人間

適応されないž インスタンスは専用のノードでガラス

右10cm
リンゴ

赤

左10cm

肌(インスタンス)緑FireMonkey テクニック

種類

Z

ž 反転した右手座標系

X— Ｘ： 親指
左手 座標系

右手 座標系Y— Ｙ： 人差し指

FireMonkey— Ｚ： 中指
Y

Y
Z

X

X
Z

Direct3D

OpenGL基準
ž ローカル座標

ワールド

球体

立方体

— オブジェクト座標
ž グローバル座標

相対— ワールド座標— 絶対座標ローカルローカル

ž 相対座標— TControl3Dが保持

絶対絶対グローバル

FireMonkey テクニック

B
Bl / Bl>
H>
H
X

同次座標系

A座標変換

W

X

Bl Y / Bl W = B Y = B

B

Bl Z / Bl W

BZ

ž 座標変換は行列（４×４）の演算で表現できる— 位置座標
M 11M 12

M 13

M 14AX21

M 22

M 23

M 24YM 31

M 32

M 33

M 34

M 41

M 42

M 43M 44>M

M 11 A X + M 12 A Y + M 13 A Z + M 14

Bl X

H>A H>M A + M A + M A + M H>Bl H
#AZ=

21

X

22Y2324Z

M 31 A X + M 32 A Y + M 33 A Z + M 34

=M 41 A X + M 42 A Y + M 43 A Z + M 44

1YBl Z
Bl W— ベクトル（方向のみ）
M 11M 12M 13M 14AX21

M 22

M 23

M 24YM 31

M 32

M 33

M 34

M 41

M 42M 43

M 44>M

M 11 A X + M 12 A Y + M 13 A Z

Bl X

H>A H>M A + M A + M A H>Bl H#AZ0=21X

22Y23Z

M 31 A X + M 32 A Y + M 33 A Z
M 41 A X + M 42 A Y + M 43 A Z=YBl Z
Bl W

ベクトル仕様ž 行ベクトル： DirectX, FireMonkey
6AX

M 11M 12M 13M 14@M 211#M 31

M 22

M 23

M 24

M 32

M 33

M 34>

AY

AZ

H

M 41 M 42 M 43 M 44
M 12 A X +M 13 A X +M 11 A X +M 22 A Y +M 23 A Y += M 21 A Y +M 31 A Z +M 32 A Z +M 33 A Z +>

M 41

M 42

M 43

M 14 A X +M 24 A Y + = 6Bl X
M 34 A Z +HBl YBl Z

M 44

ž 列ベクトル： OpenGL— 数学では一般的
M 11

M 12

M 13

M 14

21

M 22

M 23

M 24

M 31

M 32

M 33

M 34

M 41

M 42

M 43

M 44>M

M 11 A X + M 12 A Y + M 13 A Z + M 14

AXBl X

H>A H>M A + M A + M A + M H>Bl H
#YAZ
1=21X

22Y23Z24

M 31 A X + M 32 A Y + M 33 A Z + M 34
M 41 A X + M 42 A Y + M 43 A Z + M 44

=Y

Bl Z
Bl W

Bl W

@定義
— 座標系の 基底ベクトル を並べたもの○ ベクトル仕様により 転置 の関係にある
ž 行ベクトル仕様
XX>YXY

XZ

0X

YY

YZ

0ZX

ZY

ZZ

0PX

PY

PZ

1Z

H

YX

ZX

PX

YY

ZY

PY

XZ

YZ

ZZ

PZ

000

1>X YX

親：基準P

ž 列ベクトル仕様
XXY

H

合成変換

自分：子親

— 座標変換は逐次的に合成可能

ž 行ベクトル仕様> 子 H>変換前 H> 親 H >変換後 H
基準#変換

ž 列ベクトル仕様

相対#基準=変換

変換相対変換> 親 H>変換前 H> 子 H >変換後 H
基準

変換#相対変換#基準変換=相対変換

基本 ①
ž 平行移動1>00001 0 0 TX

100Y00100 0 1 TZTXTYTZ

10 0 0H >0 1 0 T H

行ベクトル仕様ž 拡大/縮小：スケーリング— ベクトル仕様に依存しない

1列ベクトル仕様

0>0 S00Y0000SZ

00001SXH

基本 ②
ž 回転
○ ベクトル仕様の違いによって回転方向が変わる— Ｘ軸>10 cosi010>
H0 cosi- sin i 000+ sin i

00 + sin i

cosi

00 - sin i

cosi

0010010000Hcosi>
H000 - sin i

0100cosi

0+ sin i0cosi

0010001>+ sin i- sin i0 0cosi

cosi

0 0001 0001000 1000 10 + sin i

cosi
>
0— Ｙ軸

10- sin i000cosi— Ｚ軸00H >- sin i

行ベクトル仕様H+ sin i0 0cosi

0 0H

列ベクトル仕様0M # M - 1 = M - 1 # M = I ( 単位行列)

逆行列

h- 1BhM A# M B # M = M A M # M A# M B ] M A
^h -1
^h- 1
###MBMMMAMA MB = MB
B # M A ]Až 行列の逆数に相当：除算が可能- 1Bワールド

ž 逆方向の座標変換は逆行列

球体
立方体— 球体座標系
M W" S立方体— 立方体座標系

球体

M W" C— 相対変換行列○ 行ベクトル仕様

順順

M S" C = M W " C M W- 1" S
○ 列ベクトル仕様
M S" C = M W- 1" S M W " C

逆逆ワールド演算関数
ž FMX.Types3D— function CreateTranslateMatrix3D :TMatrix3D— function CreateScaleMatrix3D :TMatrix3D— function CreateRotationMatrix3D :TMatrix3D○ 任意のベクトルを軸とした回転行列— function InvertMatrix :TMatrix3D○ 逆行列— function Matrix3DMultiply :TMatrix3D○ 行列の積— function Vector3DTransform :TVector3D○ ベクトル×行列

FireMonkey テクニック

クラス
TCameraTCube
TDummyTPlaneTControl3D

TLightTDisk
TStrokeCube
TMesh

TFmxObject

TShape3D

TCustomMesh
TSphereTColorMaterialSource
TCylinder
TMaterialSource

TTextureMaterialSource
TRoundCube
TLightMaterialSource
TCone

FMX.Types3D ①
ž TControl3D = class( TFmxObject, IControl )— property LocalMatrix :TMatrix3D○ 相対変換行列— property AbsoluteMatrix :TMatrix3D○ 絶対変換行列— property AutoCapture :Boolean○ マウスポインタが図形外へ出てもイベントを発生させる○ TControl3D. Capture / ReleaseCapture をコール
— TViewport3D は デフォルトで True

— property Context :TContext3D○ 描画エンジン

TControl3D.LocalMatrix
ž 読取専用プロパティだが クラスヘルパ で改造可能
interface
typeHControl3D = class Helper for TControl3D
protected
function GetLocalMatrix :TMatrix3D;
procedure SetLocalMatrix( const LocalMatrix_:TMatrix3D ); virtual;publicproperty LocalMatrix :TMatrix3D read GetLocalMatrix write SetLocalMatrix;
end;
implementation

直接 FLocalMatrix は指定できない

function HControl3D.GetLocalMatrix :TMatrix3D;
begin
Result := FLocalMatrix
end;
procedure HControl3D.SetLocalMatrix( const LocalMatrix_:TMatrix3D );begin
FLocalMatrix := LocalMatrix_; RecalcAbsolute; Repaintend;

絶対変換行列を再計算

FireMonkey テクニック

法線

ポリゴンモデル連続面面

ž 三角ポリゴンの集合面

面— ＧＰＵ は 三角形ポリゴンしか描けない座標

不連続面

ž 構成要素— 面：Face○ 頂点を右回りに参照— 頂点：Vertex○ 位置座標○ 法線

0,1

0,00,00.5,0— 面の垂直ベクトル○ テクスチャ座標

0,1

1,0

1,1
1,1

1,0

FMX.Types3D ②
ž TShape3D = class( TControl3D )— property MaterialSource :TMaterialSource○ マテリアルコンポーネントへの参照

ž TCustomMesh = class( TShape3D )— property Data :TMeshData○ ポリゴンデータを保持する— function DoRayCastIntersect :Boolean○ ボリゴンと光線（ray）との交点を求める— Data.RayCastIntersect をコール

FMX.Types3D ③
ž レイ交差判定— function RayCastPlaneIntersect :Boolean;○ 対 平面— function RayCastSphereIntersect :Integer;○ 対 球体— function RayCastEllipsoidIntersect :Integer;○ 対 楕円体— function RayCastCuboidIntersect :Integer;○ 対 直方体— function RayCastTriangleIntersect :Boolean;○ 対 三角ポリゴン(一枚)FMX.Types3D ④
ž TMeshData = class( TPersistent )— function RayCastIntersect :Boolean;○ ポリゴン群とのレイ交差判定— 総当たりで RayCastTriangleIntersect をコール
- ポリゴン数が多いと処理が重い： 空間分割最適化の検討— property VertexBuffer :TVertexBuffer○ 頂点のリスト— 位置座標— 法線ベクトル— テクスチャ座標— property IndexBuffer :TIndexBuffer○ ポリゴンのリスト

FMX.Types3D ⑤
ž TVertexBuffer = class( TPersistent )— property Length :Integer○ 頂点数— property Vertices[ AIndex:Integer ] :TPoint3D○ 頂点の位置座標— property Normals[ AIndex:Integer ] :TPoint3D○ 頂点の法線ベクトル— property TexCoord0[ AIndex:Integer ] :TPointF○ 頂点のテクスチャ座標

FMX.Types3D ⑥
ž TIndexBuffer = class( TPersistent )— property Length ：Integer○ 面数×３ ：ポリゴン○ 線数×２ ：ワイヤーフレーム○ 点数×１ ：ポイントクラウド— property Indices[ AIndex:Integer ] :Integer○ Ｎ番目ポリゴン— Indices[ 3×N＋0 ] = 頂点①のインデックス番号— Indices[ 3×N＋1 ] = 頂点②のインデックス番号— Indices[ 3×N＋2 ] = 頂点③のインデックス番号

描画エンジンž TCustomMesh
procedure TCustomMesh.Render;
begin
Context.SetMatrix( Matrix3DMultiply( CreateScaleMatrix3D( Vector3D( Width, Height, Depth ) ),AbsoluteMatrix ) );Context.DrawTriangles( FData.VertexBuffer, FData.IndexBuffer,TMaterialSource.ValidMaterial( FMaterialSource ), AbsoluteOpacity );end;ž TContext3D = class abstract( TInterfacedPersistent, IFreeNotification )— procedure DoDrawTriangles○ 面群の描画— procedure DoDrawLines○ 線群の描画

例：TStrokeCube— procedure DoDrawPoints○ 点群の描画

モデル構築不連続面面

ž TCustomMesh面

面

with Data dobegin
with VertexBuffer dobegin
Length := 7{頂点数};
Vertices [ 0 ] := TPoint3D.Create( *, *, * ){位置座標};
Normals [ 0 ] := TPoint3D.Create( *, *, * ){法線ベクトル};
TexCoord0[ 0 ] := TPointF.Create( *, * ){テクスチャ座標};〜Vertices [ 6 ] := TPoint3D.Create( *, *, * );;Normals [ 6 ] := TPoint3D.Create( *, *, * );TexCoord0[ 6 ] := TPointF.Create( *, * );end;with IndexBuffer do
begin
Length := 3{頂点数/ポリゴン} * 3{ポリゴン数};
Indices[ 3*0+0 ] := 6;
Indices[ 3*0+1 ] := 1;
Indices[ 3*0+2 ] := 0;
Indices[ 3*1+0 ] := 6;
Indices[ 3*1+1 ] := 5;
Indices[ 3*1+2 ] := 1;
Indices[ 3*2+0 ] := 4;
Indices[ 3*2+1 ] := 3;
Indices[ 3*2+2 ] := 2;
end;
end;

(0)

分
解

(5)

(6)

(4)

<1>
<0>

<2>
(1)

(2)
(3)