WPFで3Dモーフィング
WFPの壁を破ろうシリーズ第5段?
3Dモーフィングは、複数の3Dジオメトリ間で頂点を補間して中間のジオメトリを表示して、3Dジオメトリ間の遷移を表現するテクニックです。リアルタイム シェーダを使えば、GPU内のジオメトリをハードウェアでモーフィングできますが、WPFでは頂点単位の処理はできないので、例の如くCPUで処理します。ただし頂点の数とそのトポロジは同じでなければなりません。
まず同じ頂点数の球(mySpere)と円柱(myCylinder)のGrometryModel3Dを用意して、一方をシーンに配置します。
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D Geometry="{StaticResource mySphere}" >
<GeometryModel3D.Material>
<DiffuseMaterial Brush="{StaticResource myEarth}" />
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
補間パラメータはスライダで設定するように、コールバックを定義します。コールバックの中で2つの頂点を補間し、新しいModelVisual3Dを生成してシーンに追加します。
private void SliderMoved(object sender, RoutedEventArgs e)
{
Slider s = (Slider)sender;
myScene.Children.Clear();
MeshGeometry3D myMesh = GetMorphedMesh(s.Value);
GeometryModel3D myGeom = new GeometryModel3D();
myGeom.Geometry = myMesh;
myGeom.Material = new DiffuseMaterial(myEarth);
ModelVisual3D myModel = new ModelVisual3D();
myModel.Content = myGeom;
myScene.Children.Add(myModel);
}
internal MeshGeometry3D GetMorphedMesh(double w)
{
MeshGeometry3D m = new MeshGeometry3D();
m.TextureCoordinates = myCylinder.TextureCoordinates;
m.TriangleIndices = myCylinder.TriangleIndices;
for (int i = 0; i < myCylinder.Positions.Count; i++)
{
Point3D p0 = myCylinder.Positions[i];
Point3D p1 = mySphere.Positions[i];
Point3D p = new Point3D( w * p0.X + (1.0 - w) * p1.X,
w * p0.Y + (1.0 - w) * p1.Y,
w * p0.Z + (1.0 - w) * p1.Z) ;
m.Positions.Add(p);
Vector3D n0 = myCylinder.Normals[i];
Vector3D n1 = mySphere.Normals[i];
Vector3D n = w * n0 + (1.0 - w) * n1;
m.Normals.Add(n);
}
return m;
}
Comments
- Anonymous
October 11, 2007
PingBack from http://www.artofbam.com/wordpress/?p=7663