Three. js Source Code Reading Notes (Object3D class)

Source: Internet
Author: User

This is the second reading note of Three. js source code.
Core: Object3D
Object3D seems to be Three. the most important class in the js framework. A considerable number of other classes are inherited from the Object3D class, such as the scenario class, ry class, Camera class, and illumination class. They are all objects in 3D space, so it is called the Object3D class. The Object3D constructor is as follows:
Copy codeThe Code is as follows:
THREE. Object3D = function (){
THREE. Object3DLibrary. push (this );
This. id = THREE. Object3DIdCount ++;
This. name = '';
This. properties = {};
This. parent = undefined;
This. children = [];
This. up = new THREE. Vector3 (0, 1, 0 );
This. position = new THREE. Vector3 ();
This. rotation = new THREE. Vector3 ();
This. eulerOrder = THREE. Object3D. defaultEulerOrder;
This. scale = new THREE. Vector3 (1, 1, 1 );
This. renderDepth = null;
This. rotationAutoUpdate = true;
This. matrix = new THREE. Matrix4 ();
This. matrixWorld = new THREE. Matrix4 ();
This. matrixRotationWorld = new THREE. Matrix4 ();
This. matrixAutoUpdate = true;
This. matrixWorldNeedsUpdate = true;
This. quaternion = new THREE. Quaternion ();
This. useQuaternion = false;
This. boundradgenius = 0.0;
This. boundRadiusScale = 1.0;
This. visible = true;
This. castShadow = false;
This. inclueshadow = false;
This. frustumCulled = true;
This. _ vector = new THREE. Vector3 ();
};

Before introducing a function, you must first introduce several important attributes of this class.
Description of attributes parent and children. Tree is usually required to manage many Object3D objects. For example, a driving car is an Object3D object, and the logic of controlling the driving route of the car is implemented inside the object. Each vertex of the car is in the correct position after being processed by the model matrix; however, the wiper for a car not only moves in the direction of the car, but also its own opposite car is also swinging left and right. The logic of this swing cannot be implemented inside the car. The solution is to set the wiper to the chidren of the car, and the logic of the wiper is only responsible for its swing relative to the car. In this tree structure, a Scene is actually the top Object3D, and its model matrix is the inverse matrix of the view matrix (depending on the camera.

Attributes matrix and matrixWorld are well understood. matrix represents the local model matrix and only the motion of the object. matrixWorld needs to iterate to the Father's Day point in sequence, each iteration is left multiplied by the local model matrix of the parent object until the Scene object -- of course, it is actually the global model matrix of the Left multiplication parent object.

Attributes position, rotation, and scale represent the three transformations of the model matrix, which are described in the Matrix4 class. Rotation and eulerOrder jointly describe a rotation state. quaternion can also describe a rotation state. The specific method to use depends on the Boolean value of useQuation.

We can see that the most important "transformation state" information about the Object3D object is actually stored in two "backups", one is the matrix object, and the other is the position attribute, the two parts should be consistent. If one backup is changed in some way, the other backup should also be updated as appropriate. Some other attributes can be seen from the literal and type, and are not listed separately. Function:
The applyMatrix (matrix) function returns the matrix parameter to this. A transformation is actually performed on the Object3D object on the matrix (this transformation may take several steps, but it is already stored in the matrix parameter ). Note: After the left multiplication is executed on this. matrix, the position and other parameters are updated immediately. Compared with the following Transformation functions, this function is more "advanced", allowing developers to freely specify the transformation matrix, rather than "moving towards the X axis by 5 units ".
Copy codeThe Code is as follows:
ApplyMatrix: function (matrix ){
This. matrix. multiply (matrix, this. matrix );
This. scale. getScaleFromMatrix (this. matrix );
Var mat = new THREE. Matrix4 (). extractRotation (this. matrix );
This. rotation. setEulerFromRotationMatrix (mat, this. eulerOrder );
This. position. getPositionFromMatrix (this. matrix );
},

The function translate (distance, axis) allows the object to forward distance to the direction specified by the axis. The translateX (distance), translateY (distance), and translateZ (distance) functions forward distance to the X, Y, and Z axes. Note that these functions only change the value of the position object without changing the value of matrix.
Copy codeThe Code is as follows:
Translate: function (distance, axis ){
This. matrix. rotateAxis (axis );
This. position. addSelf (axis. multiplyScalar (distance ));
},
TranslateX: function (distance ){
This. translate (distance, this. _ vector. set (1, 0, 0 ));
},

The localToWorld (vector) function converts local coordinates into world coordinates, while the worldToLocal function is the opposite. Note that the local coordinates of the vector here refer to the coordinates before the transformation, that is, the coordinates of the vertices at the default position of the wiper.

The lookAt (eye, center, up) function executes the lookAt function of its matrix attribute object (previously introduced, The matrix4 object also has a lookAt function), which is generally used for camera objects. This function only changes the rotation State. Therefore, after the matrix attribute object is executed, if the rotationAutoUpdate attribute is true, the rotation or quaternion value will be updated. The updated value depends on the attribute useQuation.
The add (object) and remove (object) functions add a child object from the current Object3D object, or delete a child object, it is easy to understand that many Object3D objects in the scenario are managed using trees.

The call back function traverses all future generations of the caller and the caller. The call back parameter is a function that is called by the caller and each descendant object ).
Copy codeThe Code is as follows:
Traverse: function (callback ){
Callback (this );
For (var I = 0, l = this. children. length; I <l; I ++ ){
This. children [I]. traverse (callback );
}
},

The getChildByName (name, recursive) function returns a string by querying the object that matches the property name in the caller's subelement (recursive is false) or descendant element (recursive is true.

The getDescendants (array) function pushes all descendant objects of the caller to the array.
The updateMatrix () and updateMatrixWorld (force) functions update the matrix and matrixWorld based on the position, rotation, quaternion, and scale parameters. UpdateMatrixWorld also updates the matrixWorld of all descendant elements. If the force value is true or the value of the caller's matrixWorldNeedsUpdate is true. In the applyMatrix (matrix) function, attributes such as position and rotation are updated immediately after the matrix value is changed, but in the function translate (distance, axis) after changing the position and other variables (or directly changing the position and other attributes), the matrix value is not updated immediately. In this case, you should manually call updateMatrix (). These details are worth noting. You may think that you should add event listening. Once a value changes, all others will be updated immediately. However, I think this may be due to the following considerations: when appropriate, updating will lead to higher efficiency-for example, the rotation value may be changed frequently, but it will only be updated before the matrix attribute is used.
Copy codeThe Code is as follows:
UpdateMatrix: function (){
This. matrix. setPosition (this. position );
If (this. useQuaternion === false ){
This. matrix. setrotationfromeeting (this. rotation, this. eulerOrder );
} Else {
This. matrix. setRotationFromQuaternion (this. quaternion );
}
If (this. scale. x! = 1 | this. scale. y! = 1 | this. scale. z! = 1 ){
This. matrix. scale (this. scale );
This. boundRadiusScale = Math. max (this. scale. x, Math. max (this. scale. y, this. scale. z ));
}
This. matrixWorldNeedsUpdate = true;
},
UpdateMatrixWorld: function (force ){
If (this. matrixAutoUpdate = true) this. updateMatrix ();
If (this. matrixWorldNeedsUpdate = true | force = true ){
If (this. parent === undefined ){
This. matrixWorld. copy (this. matrix );
} Else {
This. matrixWorld. multiply (this. parent. matrixWorld, this. matrix );
}
This. matrixWorldNeedsUpdate = false;
Force = true;
}
For (var I = 0, l = this. children. length; I <l; I ++ ){
This. children [I]. updateMatrixWorld (force );
}
},

The deallocate function manually releases the space occupied by the caller. This is done when this object is no longer needed.
Core: Projectors
The code for managing the projection matrix class is too complicated. I guess it will involve operations in the render class and wait until appropriate.
Core: UV
This constructor generates a material coordinate class, that is, the coordinates on the material, which usually correspond to the vertex. After raster, each pixel has a material coordinate, then "color" is taken from the material to realize the texture.
Copy codeThe Code is as follows:
THREE. UV = function (u, v ){
This. u = u | 0;
This. v = v | 0;
};

The material coordinate class is a simplified vector2 class, except for the attribute names.
Core: Ray Core: Rectangle Core: Spline
Rays, with the origin, direction, and distance truncation points. It should be used in the light source. Rectangular and curve types are relatively simple and not so "core". Let's take a look later.
Core: Geometry
Geometry is also a very important class that represents a geometric shape composed of vertices and surfaces.
Copy codeThe Code is as follows:
THREE. Geometry = function (){
THREE. GeometryLibrary. push (this );
This. id = THREE. GeometryIdCount ++;
This. name = '';
This. vertices = [];
This. colors = [];
This. normals = [];
This. faces = [];
This. faceUvs = [[];
This. faceVertexUvs = [[];
This. morphTargets = [];
This. morphColors = [];
This. morphNormals = [];
This. skinWeights = [];
This. skinIndices = [];
This. lineDistances = [];
This. boundingBox = null;
This. boundingSphere = null;
This. hasTangents = false;
This. dynamic = true;
This. verticesNeedUpdate = false;
This. elementsNeedUpdate = false;
This. uvsNeedUpdate = false;
This. normalsNeedUpdate = false;
This. tangentsNeedUpdate = false;
This. colorsNeedUpdate = false;
This. lineDistancesNeedUpdate = false;
This. buffersNeedUpdate = false;
};

The following two groups of attributes are the most important:
Attribute vertics is an array. Each element is a vector3 object that represents a vertex coordinate. The colors and normals attributes represent the color values and discovery vectors corresponding to the vertex. They are used only in rare cases. In most cases, the color of the vertex and what is defined in the "surface"-if the six sides of the cube have different colors, each vertex actually has different faces.

Attribute faces is an array where each element is a face4 or face3 object. As mentioned earlier, face3 only stores the vertex index value, the index value can be used to obtain the coordinate value of the vertex in the array vertices.

Function:
The applyMatrix (matrix) function updates the coordinates of all vertices in the geometry and the normal vectors on the surface. What we do is to use the transformation matrix to perform spatial transformation on the geometry shape. NormalMatrix is the inverse matrix of the 3×3 matrix in the upper left corner of the matrix parameter. This matrix is used to rotate the vector (normal rather than vertex coordinates ).
Copy codeThe Code is as follows:
ApplyMatrix: function (matrix ){
Var normalMatrix = new THREE. Matrix3 ();
NormalMatrix. getInverse (matrix). transpose ();
For (var I = 0, il = this. vertices. length; I <il; I ++ ){
Var vertex = this. vertices [I];
Matrix. multiplyVector3 (vertex );
}
For (var I = 0, il = this. faces. length; I <il; I ++ ){
Var face = this. faces [I];
NormalMatrix. multiplyVector3 (face. normal). normalize ();
For (var j = 0, jl = face. vertexNormals. length; j <jl; j ++ ){
NormalMatrix. multiplyVector3 (face. vertexNormals [j]). normalize ();
}
Matrix. multiplyVector3 (face. centroid );
}
},

The ComputeCentroid () function calculates the center of gravity of each surface in the ry (not the center of gravity of the ry itself ). It seems better to put this function on the prototype of the face class, but because the face class cannot obtain the coordinates of the points (unless the reference of the Point Coordinate array is passed as a parameter to the constructor, in this case, the cost is high.) instead of the index value, we have to define it on the ry class prototype. The following functions are similar (in fact, there are almost no member functions in the face class ).

The computeFaceNormals () and computeVertexNormals (areaWeight) functions calculate the normal vector. The former affects the normal attributes of each element in the face array and only one face; vertexNormal attribute of each element in the latter face array. There are three face3 objects and four face4 objects, but note that, A vertex shared by multiple surfaces has only one normal vector and is affected by multiple surfaces at the same time. For example, if the center is at the origin and the three groups of surfaces are perpendicular to the axis cubes, the vertices in the First quadrant and the normal vectors are normalized (, 1. Although it looks incredible, the normal of the plane's vertices is not perpendicular to the plane, but this method of specifying the normal has a good effect when simulating a surface using the plane.

The createMorphNormal function creates a normal for each morph. Morph should be used to display the deformation effect of a fixed continuous animation.
The mergeVertics function removes vertices with the same coordinate values and updates the vertex index value in the face object.
Core: Quaternian
The four-dimensional number rotation class expresses a rotation Transformation in another way. Compared with rotation, it can avoid the deadlock problem of universal joints.
Copy codeThe Code is as follows:
THREE. Quaternion = function (x, y, z, w ){
This. x = x | 0;
This. y = y | 0;
This. z = z | 0;
This. w = (w! = Undefined )? W: 1;
};

Without talking about functions, Quaternian is a simple vector4 object.
The setfrome (v, order) function sets a four-dimensional number rotation through an Euler's rotation.
The setFromAxis (axis, angle) function sets the four-dimensional number rotation by rotating around any axis.
The setFromRotationMatrix (matrix) function sets four-dimensional rotation through the rotation matrix.
Some functions that are the same as vector4 are not listed here.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.