Balder 3D开发系列之--创建自己的primitives

一、About primitives

 

        在Balder中,有很多已经创建好了的基本体,你只要直接调用就可以了,这和3DMax等软件类似,里面也提供了一系列的基本体,给设计者扩展使用。目前,Balder的Geometries命名空间下已经有Box,Cylinder,Ring等等基本体。在之前的文章中,我们已经使用过了其中的Box,也就是那个立方体。当然,如果就这么些基本体,对于越来越复杂的需求,是不够的,因此Balder提供更大的扩展性。那么,该如何实现呢?请往下看...

 

二、How to create your own primitives

 

        想要创建自定义的基本体,其实很简单,基本体,说到底其实就是一个Geometry(几何体)。而在Balder中,每个Geometry拥有一个实现了IGeometryContext  接口的GeometryContext类的属性,通过GeometryContext就可以创建被称为GeometryDetailLevel的东西。那么GeometryDetailLevel又是什么东西呢?它其实就是按照Balder想要进行渲染的细分级别来被渲染的一个对象。在大部分情况下,balder使用full detail level来进行渲染。在Geometry中有一个FullDetailLevel 属性,通过它,我们就可以方便的来产生一个几何体了。

 

三、a demo for creating a primitive

        接下来,通过一个实例,来示范下基本体的创建过程,这里,我们通过创建一个三棱锥来作为例子:

首先,你需要创建一个你自己的基本体类继承自Geometry类

using  Balder.Objects.Geometries;
 
namespace  MeshDemo
{
    
public   class  MyMesh:Geometry
    {
    }
}

这样,你就可以把该对象加到页面中去了,就像这样:

 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网格数据,以创建基本体三棱锥,这里主要由三部分组成:

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函数中调用它们,运行后你会看到这样的结果:

Balder 3D开发系列之--创建自己的primitives_第1张图片

 这样一个基本体就创建好了,当然,如果想要看到实体的话,就还需要完成面的组成函数:

  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,搞定,看看最后效果:

Balder 3D开发系列之--创建自己的primitives_第2张图片

你可能感兴趣的:(Balder 3D开发系列之--创建自己的primitives)