core的部分大致看完了,看一点独立而又轻松的东西吧,Geometries感觉符合这个要求。


geometry中是个相对扁平的结构,第一个 BoxGeometry 好好看一下,应该能够了解基本的组织方式吧。

BoxGeometry

对于general的geometry的继承,生成具体的某一类型的geometry,包括用户友好的geometry和更高性能的buffergeometry。

这这这,才注意到, BoxBufferGeometryBoxGeometry 两个class,里边都只有constructor,一看就是从function class改过来的hhh。

BoxBufferGeometry

首先有参数的设定:

  1. this.parameters = {
  2. width: ...,
  3. ...
  4. }

还有geometry所具有的buffers:

  1. var indices = [];
  2. var vertices = [];
  3. var normals = [];
  4. var uvs = [];

用来临时存放生成的数据,最终通过 setIndex 或者 setAttribute 放进去

大致的结构就是生成对应的数据,然后存到buffer中

那么接下来的代码,全部都是关于生成数据了,而再box中,也就是六个面,用 buildPlane 函数来生成。

buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz

BuildPlane

这个函数还是很设计的还是很巧妙的,通过对三个坐标的轮换,以及u,v方向的不同设定,做到了一个函数设置六个面的vertices位置,法线,index,uv坐标等等。
具体细节就不细看了,按照代码推演即可。
uv的部分,自己自始至终都不了解,可能最后要统一回顾。

BoxGeometry

用户友好的geometry倒简单,直接使用Geometry中的 fromBufferGeometry 搞定,对于面中重复的点,进行融合。

这里就有个问题,上述的buildPlane显然是创造了很多个重复的vertices,那么再绘制的时候,效率不会受影响么?难道在绘制geometry的时候,three做了相关的优化?可能在renderer中有体现吧,TODO

CircleGeometry

准确的说是,正多边形:
image.png
关于uv的设置:

vertices.push( 0, 0, 0 );
uvs.push( 0.5, 0.5 );

vertices.push( vertex.x, vertex.y, vertex.z );
uv.x = ( vertices[ i ] / radius + 1 ) / 2;
uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;

可以看出,uv的设置是circle的包围正方形,左下为(0,0),右上(1,1),中心为(0.5,0.5),也算是把uv的对应关系理清楚了。

剩下的应该没什么值得关注的地方了。

CylinderGeometry

怎么说,也都是数学运算了,好像没什么特别需要深究的地方。
剩下的,有特殊的再单独说,不然就略去。

ParametricGeometry

不是很懂,先放下

ShapeGeometry

根据2D shape生成geometry,emmm,跟ExtrudeBufferGeometry一样,也是接受一个shape,这个util中的shape之后详细看下吧。
TODO:shape的内容

TextGeometry

这一部分主要来源于three维护的font相关的系统,这里只是调用了:

var shapes = font.generateShapes( text, parameters.size );

便生成了shape,所以再TextGeometry中反而比较简单,就直接设置一些参数就好了,然后调用ExtrudeBufferGeometry,根据形状直接挤出3D字体。
关于Three的Text系统之后还要看看。

WireframeGeometry

一个Helper,用来展示Geometry的线框形式
接收一个geometry,然后提取其中的边的信息,整理成2个点一组的点的数组和边的数组,具体内部有好多处理不同geometry以及index的逻辑