Threejs Animation interactive logic and effects

Source: Internet
Author: User
Tags asin

The work needs, studied the Threejs simple logic animation interactive method. Wrote a small example, share, pretty ugly.

The first step

It is, of course, initializing the Threejs rendering scene.

var // Camera var scene; // Scene var renderer; // WebGL Renderer var controls; //  var raycaster; // three. The Raycaster object launches a beam of light from the screen's point of view, returning a ray of array var composer through the object  ; // post-effect synthesizer to add glow effects to the scene's selected object

Step Two

Create a simple example model in Threejs Editor, "Export Scene", exporting. and import the sample program. Eliminates the hassle of modeling yourself in the sample program, but because the sample program loads local JSON, you can set up a simple Nodejs server.

Run the example under Nodejs anywhere:

Load the model file and add the relevant object in the file to the group :

varurl = ' Nofloor.json '; varLoader=Newthree. Objectloader ();
var geometry = new three. Geometry ()///store the position coordinates of the objects, which serves as the starting point coordinates of the line loader.load (URL,function(loadedscene) {//scene = Loadedscene; varobjects =Loadedscene.children; for(vari=0;i<objects.length;i++){ if(Objects[i].type = = ' Mesh ') {Objects[i].receiveshadow=true; Objects[i].castshadow=true; Geometry.vertices.push (objects[i].position); Group.add (Objects[i]); }}}, OnProgress, onError);

The imported model is almost like this (ugly, magnanimous), and in the sample program added stats and Dat.gui to detect rendering effects and change the effect parameters.

Step Three

The goal of the interaction is to click a bar selected, the corresponding line appears, and let the selected bar and line glow.

Now use Raycaster to select the object:

var New  = (event.clientx/window.innerwidth) * 2-1=-(event.clienty/window.innerheight) * 2 + 1; ra Ycaster.setfromcamera (mouse, camera);//Raycaster action Scenario vartrue

Once the intersects is not empty, the Intersects[0].object is the object that the mouse selects, can be in the square body, also can be in the floor.

Next, you can connect to the selected object. There are two ways to even floss.

First Kind

The code is as follows:

var New three. Linebasicmaterial ({    0x0000ff}); var New three. Geometry (); Geometry.vertices.push (    geometry.vertices
);
Three. Line will connect all the coordinate points in the geometry.vertices into a single continuous thread, but not the end-to
For example, geometry.vertices stored in the v1,v2,v3,v4 four three-dimensional coordinate points, will generate v1->v2->v3->v4 continuous line, the middle of three lines.
var New Three. Line (geometry, material);

But one drawback is that with WebGL on the Windows platform due to the angle layer (ANGLE layer), the lineweight will always be 1 regardless of the value set. So once the model is five or six meters high, but the line is less than 1cm width, it looks like the model will be very strange. In this case, the second method is necessary.

The second Kind

Draw a cylinder, with a cylinder instead of a line segment, but creating a cylinder is more complex than a line segment. As you know, Threejs only specifies the position (center) of an object, and cannot specify the position of both ends (I have not found that if there is an error, please correct), so the original cylinder is upright, such as

Let's ask for such a cylinder (collectively referred to as the "pillar Line")

Because the radius is 0.02, so it looks like a line segment, which is why the cylinder is used to simulate the cause of the line, lifelike, but also according to the size of the model to adjust the column line "LineWidth".

Let's look at how to dynamically generate a pillar line based on the coordinates of a cube sphere.

Above we talked about how to select the object, when selected, we put this object adjacent to the object (when modeling, all objects in the coordinate order in the geometry.vertices, where the default coordinates adjacent to the object adjacent) position coordinates to join In Geometrychange.vertices

varObject = Intersects[0].object; Geometrychange=Newthree.                        Geometry (); varPosition = Intersects[0].object.position;//The coordinates of the currently selected object//search geometry.vertices in position to redraw the selected object related Linet                        varp =geometry.vertices.length;  for(i=0;i<p;i++){                            if(Geometry.vertices[i] = =position) {                                if(i = = P-1) {//Add the last object's coordinates to GeometryChange.vertices.push (geometry.vertices[p-2]);                                GeometryChange.vertices.push (position); }                                Else if(i = = 0) {//Add the last coordinate of the first object to GeometryChange.vertices.push (position); GeometryChange.vertices.push (Geometry.vertices[i+1]); }                                Else{GeometryChange.vertices.push (geometry.vertices[i-1]); GeometryChange.vertices.push (position);//The addition of objects adjacent to the GeometryChange.vertices.push (GeoMet Ry.vertices[i+1]); }                            }                        }

This allows us to place the coordinates of the object adjacent to the selected object in the Geometrychange.vertices. Now that we know the starting and ending coordinates of the pillar line, how to draw the column line and where to draw it?

var temp = geometryChange.vertices.length;                         var xyz = geometrychange.vertices;                 //position (x, y, z), which is the midpoint position of the pillar line, XW is the x-axis distance from the start and midpoint, and ZH is the z-axis distance from the start and midpoint, and the cheight is the spatial distance between The starting point and the midpoint. var x,y,z,xw,zh,cheight;

First know the position (x, y, z) of the Pillar Line, Xyz[i] is the beginning of the pillar line, xyz[i+1] is the end of the pillar line.

x= (xyz[i].x+xyz[i+1].x)/2;y=0.1; // line I was drawing near the ground, so y default 0.1z= (XYZ[I].Z+XYZ[I+1].Z)/2

and find the length of the pillar line.

Xw=xyz[i].x-xyz[i+1].x;zh=xyz[i].z-xyz[i+1].z;cheight=math.sqrt (XW*XW+ZH*ZH); // cylinder length, Pythagorean theorem

Here, draw the pillar line.

var New three. Meshphongmaterial ({                                        0x156289,                                        0x00ffff,                                        side:three. Doubleside,                                        Shading:three. Flatshading,                                        Vertexcolors:three. Facecolors                                    }); var New three. Mesh (geometrycylinderline, material); Cylinder.position.set (x, y, z); // Two the midpoint of the entity, which is the midpoint of the Pillar line, understands

But we found that the pillars were straight up.

At this time, we need to change the model matrix of the pillar line and rotate it to achieve our ideal effect.

Let us first analyze how to rotate, first of all around the x-axis to 90°, so that the pillar line lying on the ground.

cylinder.rotation.x-= Math.PI * 0.5;

Then, as the analysis shows, the Red line is the pillar lying on the ground (self-repairing 3D scene).

Where the red and black lines are the same length, the red line only need to rotate the θ angle can be coincident with the black lines, to achieve our desired effect.

θ= Math.asin (xw/cheight);//Radian System

This time know how many degrees, turn on OK

//considering the transformation of the local and global coordinate system, the cylinder is rotated in the global coordinate system                            if(xyz[i].x > xyz[i+1].x && xyz[i].z < xyz[i+1].z) cylinder.rotation.z-= Math.asin (xw/cheight);//math.asin (xw/cheight) is the angle at which the cylinder is to be rotatedElse if(xyz[i].x > xyz[i+1].x && xyz[i].z > Xyz[i+1].z) cylinder.rotation.z+ = Math.asin (xw/cheight);Else if(Xyz[i].x < xyz[i+1].x && Xyz[i].z < xyz[i+1].z) cylinder.rotation.z-= Math.asin (xw/cheight);Elsecylinder.rotation.z+ = Math.asin (xw/cheight);

Well, the pillar line is drawn out.

Of course, there is more than one pillar line, add the current to the Linegroup

Linegroup.add (cylinder); Scene.add (Linegroup);

The next time you draw, just remove the current linegroup.

Scene.remove (Linegroup);

Fourth Step

Add Light effect

With Threejs's Outlinepass channel

Composer =Newthree.                Effectcomposer (renderer); varRenderpass =Newthree.                Renderpass (scene, camera);                Composer.addpass (Renderpass); Outlinepass=NewThree. Outlinepass (Newthree.                Vector2 (Window.innerwidth, Window.innerheight), scene, camera);                Composer.addpass (Outlinepass); varOnLoad =function(texture) {outlinepass.patterntexture=texture; Texture.wraps=three.                    repeatwrapping; Texture.wrapt=three.                repeatwrapping;                }; varLoader =Newthree.                Textureloader (); Loader.load (' Tri_pattern.jpg ', OnLoad); Effectfxaa=Newthree. Shaderpass (three.                Fxaashader); effectfxaa.uniforms[' Resolution '].value.set (1/window.innerwidth, 1/window.innerheight); Effectfxaa.rendertoscreen=true; Composer.addpass (EFFECTFXAA);

When selected, add the object and the corresponding pillar line to the Outlinepass render target.

Selectedobjects = [];                        Selectedobjects.push (linegroup); // Add light effects                        to selected lines and objects Selectedobjects.push (intersects[0 ].object);                         = Selectedobjects;

OK, this is achieved, click the interactive simple effect.

Of course, this is just an example, in order to use it in a complex 3D scene, but also need a lot of things to do, refueling.

Please correct me if there is an error.

Threejs Animation interactive logic and effects

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.