This is the third article of Three.js source reading notes. The previous two articles are mainly about the core objects, these core objects mainly revolve around the vector Vector3 object and the matrix Matrix4 object, focusing on the position and change of the single vertex in the space. This article will mainly discuss how objects in Three.js are organized: How to combine vertices, surfaces, and materials into a specific object.
Object::mesh
The constructor constructs an object in a space. The reason is called "grid" because, in fact, the volume of objects are basically modeled as "grid".
Copy Code code as follows:
THREE. Mesh = function (geometry, material) {
THREE. Object3d.call (this);
This.geometry = geometry;
this.material = (material!== undefined)? Material:new THREE. Meshbasicmaterial ({color:Math.random () * 0xffffff, wireframe:true});
* * Some other content unrelated to this section.
}
In fact, the mesh class has only two properties, representing the geometry object of the geometric form and the material object representing the material. The Geometry object has been introduced in the previous blog post, and some of the derived classes will be introduced in this posting (through the construction of these derived classes to get a clearer idea of how the mesh objects work); Matrial objects and their derived classes will also be introduced in this note. The two properties of the mesh object are closely related to each other, and in the face array in the geometry object, each face object's materialindex is used to match the material Property object. The Vertexuvs array of face objects is used to sequentially match the values of each vertex on the array. It is noteworthy that the mesh can only have a material object (I do not know the intention of this design), if you need to use more than one material, the material should be initialized in Materialindex order in the geometry itself materials properties.
Geometry::cubegeometry
The constructor creates a cube object.
Copy Code code as follows:
THREE. Cubegeometry = function (width, height, depth, widthsegments, heightsegments, depthsegments) {
THREE. Geometry.call (this);
var scope = this;
This.width = width;
This.height = height;
this.depth = depth;
var width_half = THIS.WIDTH/2;
var height_half = THIS.HEIGHT/2;
var depth_half = THIS.DEPTH/2;
/* Omitted * *
Buildplane (' z ', ' y ',-1,-1, This.depth, This.height, width_half, 0); Px
/* Omitted * *
function Buildplane (U, V, Udir, vdir, width, height, depth, materialindex) {
/* Omitted * *
}
This.computecentroids ();
This.mergevertices ();
};
The most important thing a constructor does is in Buildplane. The most important thing about this function is the action on scope (the code block above, scope is this), including: calling Scope.vertices.push (vector) to add vertices to geometry objects; calling Scope.faces.push ( Face) adds the surface to the geometry object and calls the Scope.facevertexuvs[i].push (UV) method to add the material coordinates corresponding to the vertex to the Geometry object. Most of the code is about the logic of building cubes, which are easy to understand and can easily be extended to other types of geometry objects.
The parameters of the constructor include length, width, height, and three-direction segments. The so-called segmentation, that is, if the widthseqments and so on three parameters are set to 2, then each face will be represented as a 2x2=4, the entire cube is composed of 24 surfaces, just like the grid.
Copy Code code as follows:
function Buildplane (U, V, Udir, vdir, width, height, depth, materialindex) {
var W, IX, IY,
GridX = Scope.widthsegments,
GridY = Scope.heightsegments,
Width_half = WIDTH/2,
Height_half = HEIGHT/2,
offset = scope.vertices.length;
if (U = = ' X ' && v = = ' y ') | | (U = = ' Y ' && v = = ' x ')) {w = ' z ';}
else if ((U = = ' X ' && v = = ' Z ') | | (U = = ' Z ' && v = = ' x ')) {w = ' y '; gridY = scope.depthsegments;} else if ((U = = ' Z ' && v = = ' y ') | | (U = = ' Y ' && v = = ' Z ')) {w = ' x '; gridX = scope.depthsegments;}
var gridX1 = GridX + 1,
gridY1 = GridY + 1,
Segment_width = Width/gridx,
Segment_height = Height/gridy,
normal = new THREE. Vector3 ();
normal[W] = depth > 0? 1:-1;
for (iy = 0; iy < gridY1; iy + +) {
for (ix = 0; IX < gridX1 IX + +) {
var vector = new THREE. Vector3 ();
vector[U] = (IX * segment_width-width_half) * UDIR;
vector[v] = (iy * segment_height-height_half) * VDIR;
vector[W] = depth;
Scope.vertices.push (vector);
}
}
for (iy = 0; iy < GridY; iy++) {
for (ix = 0; ix < GridX; ix++) {
var a = IX + gridX1 * IY;
var B = ix + gridX1 * (iy + 1);
var C = (ix + 1) + gridX1 * (iy + 1);
var d = (ix + 1) + gridX1 * IY;
var face = new THREE. Face4 (A + offset, B + offset, C + offset, D + offset);
Face.normal.copy (normal);
Face.vertexNormals.push (Normal.clone (), Normal.clone (), Normal.clone (), Normal.clone ());
Face.materialindex = Materialindex;
Scope.faces.push (face);
scope.facevertexuvs[0].push ([
New THREE. UV (Ix/gridx, 1-iy/gridy),
New THREE. UV (IX/GRIDX, 1-(iy + 1)/GridY),
New THREE. UV ((ix + 1)/GridX, 1-(iy + 1)/GridY),
New THREE. UV ((ix + 1)/GridX, 1-iy/gridy)
] );
}
}
}
In addition to a clone () method that most objects have, Cubegeometry has no other method, and the other Xxxgeometry objects are probably the same. There is no way to explain that the object is responsible for organizing and storing data, and how to use that data to generate three-dimensional scenes and animations is defined in another object.
Geometry::cylindergeometry
As the name suggests, the constructor creates a cylinder (or round table) object.
Copy Code code as follows:
THREE. Cylindergeometry = function (Radiustop, radiusbottom, height, radiussegments, heightsegments, openended) {
/* Slightly *
}
With the foundation of the Cubegeometry constructor, we should be able to implement cylindergeometry, we only need to pay attention to the meaning of the parameters of the constructor. Radiustop and Radiusbottom represent the radii at the top and bottom, and the height represents the heights. Radiussegments defines the number of circles that need to be divided (the larger the number, the more rounded the cylinder), the heightsegments defines how many copies the entire height needs to be divided, and openended specifies whether the top and bottom surfaces are generated.
There are two points to note in the source code: The local origin of the model is the midpoint of the central axis, rather than the center of gravity and the like, that is, the height of the upper circle (Y-axis value) is HEIGHT/2, the next round is-HEIGHT/2, this point to the cylinder is not different, but for the upper and lower radii of different round table body is a difference The top surface and the ground of the model are FACE3 type surface, and the Face4 type surface is used on the side.
Geometry::spheregeometry
The constructor creates a sphere.
Copy Code code as follows:
THREE. Spheregeometry = function (radius, widthsegments, heightsegments, Phistart, Philength, Thetastart, thetalength) {
/* Slightly *
}
Meaning of each parameter: radius Specifies the radius, widthsegments represents the number of "longitude" bands, and Heightsegments represents the number of "latitude" bands. The following four parameters are optional, representing the starting value of the longitude and the starting value of the latitude. Familiar with polar coordinates, it is common to use the Greek letter φ (PHI) to denote the latitude angle (longitude) and to use θ (theta) to denote the warp-circle angle (latitude). The default values for these four numbers are 0,2π,0,π, which, by changing their values, can create a defective sphere (but the edges must be neat).
The source code, in addition to the Arctic and Antarctic Polar Circle area is used face3 type of surface, other parts are used Face4-type surface. The local origin is the center of the sphere.
Geometry::P lanegeometry
The constructor creates a plane.
Copy Code code as follows:
THREE. Planegeometry = function (width, height, widthsegments, heightsegments) {
/* Slightly *
}
Meaning of each parameter: width, height, width segment, height segment. Presumably the reader should be familiar with the way the grid is structured.
The source code to get some other information: The plane is structured in the X-y plane, the origin is the rectangular center point.
Geometry::extrudegeometry
The object is now a method of constructing a general geometry, but usually we are storing the modeled object in a file of some format and loading it through the loader, so there seems to be little chance of using the function directly. And this function seems to be semi-finished, a lot of the set of brain heap in the options object, I did not study carefully.
material::material
The material object is a prototype object for all other kinds of material.
Copy Code code as follows:
THREE. Material = function () {
THREE. Materiallibrary.push (this);
This.id = THREE. Materialidcount + +;
THIS.name = ';
This.side = THREE. frontside;
this.opacity = 1;
This.transparent = false;
this.blending = THREE. normalblending;
THIS.BLENDSRC = THREE. Srcalphafactor;
THIS.BLENDDST = THREE. Oneminussrcalphafactor;
This.blendequation = THREE. Addequation;
This.depthtest = true;
This.depthwrite = true;
This.polygonoffset = false;
This.polygonoffsetfactor = 0;
this.polygonoffsetunits = 0;
this.alphatest = 0;
This.overdraw = false; Boolean for fixing antialiasing gaps in Canvasrenderer
This.visible = true;
This.needsupdate = true;
};
Let's look at some of the more important attributes:
Attribute opacity to a value of 0-1 intervals, indicating transparency. Property transparent Specifies whether to use transparency, and only when the value is true does it mix with (transparency is rendering pixels, the rendered pixel values are computed after rendering and the values are mixed).
Property blending,blendsrc,blenddst,blendequation Specifies how the blending mode and mixed-source src and mixed pixel-valued DST weights are specified. By default (such as the default value assigned in the constructor), the new image value is equal to: the new value xalpha+ the old value x (1-alpha).
I was wondering why there is no most important object in the material class that represents the properties of the texture picture. Later I understand, in fact, the material and texture are still different, can only say that some material texture, but there is no texture of material. The material affects the rendering effect of the whole body, such as: "The rendering of a line to 5px wide, the two ends of the square, opaque red" This description can be considered material, and does not involve any texture.
Like many geometry objects, there is no other way to material objects except for the generic Clone (), Dellocate (), and Setvalues () methods. Here are two of the most basic material objects.
material::linebasicmaterial
This constructor creates the material that is used to render the line shape.
Copy Code code as follows:
THREE. linebasicmaterial = function (parameters) {
THREE. Material.call (this);
This.color = new THREE. Color (0XFFFFFF);
This.linewidth = 1;
This.linecap = ' round ';
This.linejoin = ' round ';
This.vertexcolors = false;
This.fog = true;
This.setvalues (parameters);
};
Properties color and LineWidth, as the name suggests, are the color of the line and the width of the line (the line is not wide and the width is used to render it).
Properties LineCap and LineJoin Specify the style of line endpoints and connection points.
Property fog Specifies whether the material is affected by fog.
material::meshbasicmaterial
This constructor creates the material used to render the mesh surface.
Copy Code code as follows:
THREE. meshbasicmaterial = function (parameters) {
THREE. Material.call (this);
This.color = new THREE. Color (0XFFFFFF); Emissive
This.map = null;
This.lightmap = null;
This.specularmap = null;
This.envmap = null;
This.combine = THREE. Multiplyoperation;
this.reflectivity = 1;
This.refractionratio = 0.98;
This.fog = true;
this.shading = THREE. smoothshading;
This.wireframe = false;
This.wireframelinewidth = 1;
This.wireframelinecap = ' round ';
This.wireframelinejoin = ' round ';
This.vertexcolors = THREE. Nocolors;
This.skinning = false;
This.morphtargets = false;
This.setvalues (parameters);
};
Here are the most important texture attributes, including map,lightmap and specularmap, which are texture types of objects.
Property wireframe Specifies whether the boundary line of the surface is rendered, and if rendered, a number of subsequent properties that begin with wireframe indicate how the rendering boundary will be rendered.
texture::texture
This constructor is used to create a texture object.
Copy Code code as follows:
THREE. Texture = function (image, mapping, wraps, WRAPT, Magfilter, Minfilter, format, type, anisotropy) {
THREE. Texturelibrary.push (this);
This.id = THREE. Textureidcount + +;
THIS.name = ';
This.image = image;
this.mapping = mapping!== undefined? Mapping:new THREE. Uvmapping ();
This.wraps = wraps!== undefined? Wraps:three. clamptoedgewrapping;
this.wrapt = wrapt!== undefined? Wrapt:three. clamptoedgewrapping;
This.magfilter = Magfilter!== undefined? Magfilter:three. Linearfilter;
This.minfilter = Minfilter!== undefined? Minfilter:three. Linearmipmaplinearfilter;
this.anisotropy = anisotropy!== undefined? Anisotropy:1;
This.format = format!== undefined? Format:three. Rgbaformat;
This.type = Type!== undefined? Type:three. Unsignedbytetype;
This.offset = new THREE. Vector2 (0, 0);
This.repeat = new THREE. Vector2 (1, 1);
This.generatemipmaps = true;
This.premultiplyalpha = false;
This.flipy = true;
This.needsupdate = false;
This.onupdate = null;
};
The most important attribute is image, which is a JavaScript image type object. The first parameter passed in is the object, and how to create the object is said later.
The objects that follow are optional, and if the defaults are populated by default, they are often populated with default values.
Properties Magfileter and Minfileter Specify how textures are filtered when zoomed in and out: The nearest point, the bilinear interpolation, and so on.
To generate a texture from the URL, you need to call Three.ImageUtils.loadTexture (paras), which returns a texture type object. The THREE.IMAGELOADER.LOAD (paras) function is called inside the function, and the Three.texture () constructor is called inside of the function to generate a texture.