WebGL classic 3D virtual machine room roaming animation based on HTML5

The use of first-person in 3D is to refer to the use of first-person in shooters, which is a genre of video games based around guns and other weapons from a first-person perspective; The protagonist's eyes come to experience the action. Since the beginning of the genre, advanced 3D and pseudo-3D graphics have challenged hardware evolution, and multiplayer games have become indispensable.

 

Screenshot of Doom, one of the breakout games of the genre, showing the typical perspective of a first-person shooter

 

Now museums or companies often use 3D animation to make promotional videos, etc. The biggest advantage of 3D animation interpretation is the real feeling of content and form. It is more intuitive than flat works and more realistic than 2D animation, so it can give viewers the feeling of being in the advertising environment and greatly enhance the persuasiveness of advertising. The development of 3D technology even challenges the audience's ability to distinguish, so that the audience's judgment is free between virtual and reality.
Moreover, the application of 3D special effects provides a broader thinking space for creativity, becomes a reliable guarantee for creative execution, and enriches the form and style of creativity. According to the performance demands of the advertising theme, a fantastic and magical atmosphere can be created to stimulate and impress the audience, so as to achieve the purpose of communicating with the audience.
The 3D animation promotional video combines 3D animation, special effects shots, corporate videos, photos, future prospects and other content to form an intuitive, vivid, and popular high-quality corporate advertising video through post-synthesis, dubbing, and commentary. People at different levels of society Have a positive, positive and good impression on the enterprise, thereby establishing goodwill and trust in the enterprise, and trusting the enterprise's products or services.

The rapid development of 3D is also thanks to the pursuit of "reality" by human beings, so learning to use 3D well is an essential part of future success.

The idea of ​​the example in this article is to enter a computer room for a visit. The action of opening the door is impossible to move again. Coupled with appropriate turns, it basically completely simulates the effect of people visiting the computer room. Another advantage is that if you want to demonstrate to the leader without having to operate it, the leader will be very satisfied with this cool effect!

http://www.hightopo.com/demo/room-walkthrough/index.html

The "reset" and "start" buttons on the interface are buttons directly added to the body, and click events are added to these two buttons:

 

<div class="button" style="right: 50px;background-image: url(run.png);" onclick="startAnim();"></div>
<div class="button" style="right: 100px;background-image: url(reset.png);" onclick="reset();"></div>

The entire scene is built with HT-encapsulated 3D components. It takes a certain amount of code to construct such a large scene. To simplify, I took the scene out separately and used the HT-encapsulated ht.JSONSerializer class to serialize the scene into json. Only the generated json file is introduced in the code. In order to make it clearer, I will give an example here, assuming that the 3D scene has been built:

 

 

dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);
//....... Build the scene
dm.serialize();//You can fill in the number parameter as a space indentation value

Now that we have set up the environment and converted it into a json file, the code is not easy to control. In this case, we will deserialize the DataModel data model. The function of this function is to convert the json format into an object and deserialize it. The serialized object is passed into the DataModel data model. For details, please refer to the  HT for Web Serialization Manual :

 

 

var g3d = window.g3d = new ht.graph3d.Graph3dView(),
    dataModel = g3d.dm(),
    view = g3d.getView(),
    path = null;
g3d.setMovableFunc(function(data) {
    return false;
});
g3d.setVisibleFunc(function(data) {
    if (data.getName() === "path") {
        return false;
    }
    return true;
});
g3d.setEye([523, 5600, 8165]);
g3d.setFar(60000);
dataModel.deserialize(json);

We currently need to operate the "door" in the scene and the route "path" we will take, traverse the DataModel data model, and obtain these two data:

 

 

for (var i = 0; i < dataModel.size(); i++) {
    var data = dataModel.getDatas().get(i);
    if (data.getName() === "door") {//Name set in json
       window.door = data;
    }
    if (data.getName() === "path") {
        path = data;
    }
    if (window.door && path) {//Get out of the loop after getting the data of door and path
        break;
    }
}

In this example, there are only four actions, "reset" back to the origin, "start action", "move forward", "stop". Click the "Start" button. In the "Start Action", we only do one action, the "Open Door" action. After the action is completed, the "forward" function is called to move forward:

 

 

function startAnim() {
    if (window.isAnimationRunning) {
        return;
    }
    reset();
    window.isAnimationRunning = true;//Is the animation in progress
    ht.Default.startAnim({
        frames: 30, // The number of animation frames, the default is `ht.Default.animFrames`.
        interval: 20, // Animation frame interval, the default is `ht.Default.animInterval`.   
        finishFunc: function() {// The function called after the animation ends.
            forward();
        },
        action: function(t){ // The action function must be provided to implement property changes during animation.
            door.setRotationY(-120 * Math.PI / 180 * t);
        }
    });
}

The "reset" function here is the function of "resetting" back to the origin. We use this function to restore everything that has changed to the original position, including the position of the "door":

 

function reset() {
    if (window.isAnimationRunning) {
        return;
    }
    g3d.setCenter([0,0,0]);
    g3d.setEye([523, 5600, 8165]);
    window.forwardIndex = 0;
    door.setRotationY(0);
}

 

To "move", you must need to walk the "path", which is the "path" we just got, get all the elements in the "path" through window.points = path.getPoints()._as; and initialize window.forwardIndex = 0; Set the Eye and Center in the 3D scene by controlling the two points before and after the "path", so that we can create an effect that we are the first person:

 

 

var point1 = points[forwardIndex],
     point2 = points[forwardIndex + 1];
var distanceX = (point2.x - point1.x),
     distanceY = (point2.y - point1.y),
     distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY)-200;//The distance between two points is calculated by the triangle Pythagorean theorem. I am afraid of hitting the wall, so -200
g3d.setEye([point1.x, 1600, point1.y]);//eye
g3d.setCenter([point2.x, 1600, point2.y]);//我

The 3D component in HT has a walk(step, anim, firstPersonMode) method, which changes the position of eye and center at the same time, that is, eye and center move the same offset in the vector direction established by the two points at the same time. step is the vector length value of the offset. When the firstPersonMode parameter is empty, the current value of Graph3dView#isFirstPersonMode() is used by default. If the walk operation is called for the first-person mode, the function will take into account the boundary restrictions of Graph3dView#getBoundaries().

 

 

g3d.walk(distance, {
    frames: 50,
    interval: 30,
    easing: function(t) {return t; },
    finishFunc: function() {
        forwardIndex += 1;
        if (points.length - 2 > forwardIndex) {//points.length = 5
            g3d.setCenter([point2.x, 1600, point2.y]);//把结束点变成起始点
            g3d.rotate(Math.PI / 2, 0, {
                frames: 30,
                interval: 30,
                easing: function(t) {return t;},
                finishFunc:function() { forward();}
            });
        } else {
            var lastPoint = points[points.length  - 1];//json 中path的points 的最后一个点
            g3d.setCenter([lastPoint.x, 1400, lastPoint.y]);
            g3d.rotate(-Math.PI / 2, 0, {
                frames: 30,
                interval: 30,
                finishFunc: function() {
                    window.isAnimationRunning = false;
                }
            });
        }
    }
});

不管“path”的点有多少个,这个判断语句还是能运作,只在最后一个点是跳出 finishFunc 动画结束后调用的函数,并将 window.isAnimationRunning 值设为 false 停止 startAnim 函数。如果不是最后一个点,用户“旋转”之后,回调 forward 函数。至此,全部代码解释完毕,很短的代码量,却做出了这么大的工程!

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326473797&siteId=291194637