1、About primitiveshtml
在Balder中,有不少已經建立好了的基本體,你只要直接調用就能夠了,這和3DMax等軟件相似,裏面也提供了一系列的基本體,給設計者擴展使用。目前,Balder的Geometries命名空間下已經有Box,Cylinder,Ring等等基本體。在以前的文章中,咱們已經使用過了其中的Box,也就是那個立方體。固然,若是就這麼些基本體,對於愈來愈複雜的需求,是不夠的,所以Balder提供更大的擴展性。那麼,該如何實現呢?請往下看...express
2、How to create your own primitivesvim
想要建立自定義的基本體,其實很簡單,基本體,說到底其實就是一個Geometry(幾何體)。而在Balder中,每一個Geometry擁有一個實現了IGeometryContext 接口的GeometryContext類的屬性,經過GeometryContext就能夠建立被稱爲GeometryDetailLevel的東西。那麼GeometryDetailLevel又是什麼東西呢?它其實就是按照Balder想要進行渲染的細分級別來被渲染的一個對象。在大部分狀況下,balder使用full detail level來進行渲染。在Geometry中有一個FullDetailLevel 屬性,經過它,咱們就能夠方便的來產生一個幾何體了。瀏覽器
3、a demo for creating a primitiveapp
接下來,經過一個實例,來示範下基本體的建立過程,這裏,咱們經過建立一個三棱錐來做爲例子:ide
首先,你須要建立一個你本身的基本體類繼承自Geometry類函數
using
Balder.Objects.Geometries;
namespace
MeshDemo
{
public
class
MyMesh:Geometry
{
}
}
這樣,你就能夠把該對象加到頁面中去了,就像這樣:spa
1
<
UserControl
x:Class
="MeshDemo.MainPage"
2
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
4
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
5
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
6
xmlns:Execution
="clr-namespace:Balder.Execution;assembly=Balder"
7
xmlns:View
="clr-namespace:Balder.View;assembly=Balder"
8
xmlns:Lighting
="clr-namespace:Balder.Lighting;assembly=Balder"
9
xmlns:Local
="clr-namespace:MeshDemo"
10
mc:Ignorable
="d"
11
d:DesignHeight
="300"
d:DesignWidth
="400"
>
12
13
<
Grid
x:Name
="LayoutRoot"
>
14
<
Execution:Game
Width
="640"
Height
="480"
>
15
<
Execution:Game.Camera
>
16
<
View:Camera
Position
="-10,5,-10"
/>
17
</
Execution:Game.Camera
>
18
<
Local:MyMesh
/>
<!--
加進去的基本體對象
-->
19
</
Execution:Game
>
20
</
Grid
>
21
</
UserControl
>
可是,你此時編譯運行它,在瀏覽器中,什麼都看不到。由於,如今在幾何體類中,沒有建立任何的幾何數據,爲了建立這些,你須要實現重載Prepare()方法:設計
1
public
override
void
Prepare(Viewport viewport)
2
{
3
}
4
經過該方法,咱們將加入3D網格數據,以建立基本體三棱錐,這裏主要由三部分組成:code
1.Vertices( 頂點)
2.Lines (線)
3.Face(面)
爲了使得結構更清晰,咱們把它們分別封裝在三函數中:
private void GenerateVertices() //建立頂點
private void GenerateLines() //建立線
private void GenerateFaces() //建立面
接下來,咱們一個個來分別完成,首先是建立頂點的:
1
private
void
GenerateVertices()
2
{
3
var dimensionAsVector
=
new
Vertex(5f, 5f, 5f);
4
var halfDimension
=
new
Vertex(
2.5f
,
2.5f
,
2.5f
);
5
var Top
=
new
Vertex(0f, dimensionAsVector.Y, 0f);
6
var backBottomLeft
=
new
Vertex(
-
(halfDimension.X
/
2
)
*
sqt, 0f, halfDimension.Z
/
2
);
7
var backBottomRight
=
new
Vertex(halfDimension.X
/
2
*
sqt, 0f, halfDimension.Z
/
2
);
8
var frontBottom
=
new
Vertex(0f, 0f,
-
halfDimension.Z);
9
FullDetailLevel.AllocateVertices(
4
);
10
FullDetailLevel.SetVertex(
0
, Top);
11
FullDetailLevel.SetVertex(
1
, backBottomLeft);
12
FullDetailLevel.SetVertex(
2
, backBottomRight);
13
FullDetailLevel.SetVertex(
3
, frontBottom);
14
15
16
}
在balder中的3D點是經過Vertex(x,y,z)對象生成的,其參數表明在所在座標。前面兩行只是實例化了兩個Vertex對象,在後面能夠經過其的X,Y,Z屬性進行初始化三棱錐頂點座標位置。三棱錐一共有4個頂點,因此FullDetailLevel.AllocateVertices(4);分配了4個頂點。其中的sqt是一個常量,爲了控制在空間中的位置,沒必要理會,你能夠本身定義基本體的空間位子。
對於線的函數,與之相似,就不詳細介紹,直接看代碼:
1
private
void
GenerateLines()
2
{
3
FullDetailLevel.AllocateLines(
6
);
4
FullDetailLevel.SetLine(
0
,
new
Line(
0
,
1
));
5
FullDetailLevel.SetLine(
1
,
new
Line(
1
,
3
));
6
FullDetailLevel.SetLine(
2
,
new
Line(
0
,
2
));
7
FullDetailLevel.SetLine(
3
,
new
Line(
3
,
2
));
8
FullDetailLevel.SetLine(
4
,
new
Line(
1
,
2
));
9
FullDetailLevel.SetLine(
5
,
new
Line(
0
,
3
));
10
11
12
}
完成這兩個函數,咱們在 Prepare函數中調用它們,運行後你會看到這樣的結果:
這樣一個基本體就建立好了,固然,若是想要看到實體的話,就還須要完成面的組成函數:
private
void
GenerateFaces()
{
FullDetailLevel.AllocateFaces(
4
);
FullDetailLevel.SetFace(
0
,
new
Face(
3
,
1
,
0
));
FullDetailLevel.SetFace(
1
,
new
Face(
2
,
3
,
0
));
FullDetailLevel.SetFace(
2
,
new
Face(
2
,
0
,
1
));
FullDetailLevel.SetFace(
3
,
new
Face(
3
,
2
,
1
));
}
在建立面的時候須要注意,就是頂點的鏈接順序,每一個面由三個頂點組成的,依次鏈接它們,在balder中鏈接順序是按照順時針方向的(這和Opengl正好相反),並且是你必須在幾何體的外面來觀察它。本身畫個圖形,應該容易理解,弄好後,別忘了加入到Prepare函數,運行,看結果:
你會發現,怎麼是黑的?主要有兩個緣由:一是尚未給場景添加燈光照亮,二是須要法向量。balder中提供了一個 GeometryHelper對象,經過它,就能夠方便的建立法向量:
在建立好頂點和麪後加入: GeometryHelper.CalculateNormals(FullDetailLevel);
而後咱們在修改xaml文件:
1
<
Grid
x:Name
="LayoutRoot"
>
2
<
Execution:Game
Width
="640"
Height
="480"
>
3
<
Execution:Game.Camera
>
4
<
View:Camera
Position
="-10,5,-10"
/>
5
</
Execution:Game.Camera
>
6
<
Lighting:OmniLight
Position
="10,20,-15"
/>
7
<
Local:MyMesh
InteractionEnabled
="True"
Color
="Blue"
/>
8
</
Execution:Game
>
9
</
Grid
>
加入燈光和物體顏色,ok,搞定,看看最後效果: