preface

As soon as the concept of Internet + came out, it instantly attracted talented people from all walks of life who wanted to share a slice of the pie in this field. At present, the concept of Internet + is often used in traditional industrial production, but in the context of mass entrepreneurship and innovation, “Internet +” has poured out an endless stream of “ways”, such as smart cities, tunnel traffic, smart parks, industrial production, and even the smart plane this time! At present, the scope of remote collaborative manufacturing is mostly limited to the main engine manufacturers, with little involvement of engine and airborne system. “Internet plus Aircraft” can greatly improve navigation safety by improving the effective monitoring and emergency response capabilities of all types of aircraft. “With these two capabilities improved, incidents like the loss of the plane will no longer occur.” The ground will be able to monitor the aircraft as it flies off its scheduled route and even take over when the aircraft is maliciously manipulated. Moreover, the “Internet plus Plane” will have all the data of each aircraft at its finger tips, effectively improving the safety of navigation. In my opinion, “Internet plus aircraft” will go beyond the traditional “Internet plus aircraft manufacturing” stage and make the Internet play a major role in the whole life of aircraft, which will provide a major opportunity for the transformation and upgrading of traditional manufacturing industry.

Hightopo.com/guide/guide…

Code section

Loading aircraft model

First of all, the most important thing is our aircraft model. As mentioned in the previous article, there is a method hT.default.loadobj (hightopo.com/guide/guide…) encapsulated inside the HT. To load the OBJ file:

ht.Default.loadObj('obj/plane.obj'.'obj/plane.mtl', {                    
    center: true.r3: [0, -Math.PI/2.0].// make plane face right
    s3: [0.15.0.15.0.15].// make plane smaller
    finishFunc: function(modelMap, array, rawS3){
        if(modelMap){                            
            modelMap.propeller.r3 = { // Propeller
            func: function(data){
                return [data.a('angle'), 0.0]; }};// Set the size of the model to 1, 1.2 and 1.2 times the original (equivalent to x axis enlarged by 1, Y axis enlarged by 1.2, z axis enlarged by 1.2)
        modelMap.propeller.s3 = [1.1.2.1.2]; 
        modelMap.propeller.color = 'yellow'; }});Copy the code

To bind the model information parsed by OBJ to primitives, call the model registry in the modeling manual (hightopo.com/guide/guide…). Chapter introduces the ht. Default. SetShape3dModel (name, model) function to register, after primitive simply shape3d attribute is set to register the name of the style. Of course, we now encapsulate this method and use a simpler method to load the model, but we still need the principle of loading:

// models/plane.json
{
    "modelType": "obj"."obj": "obj/plane.obj"."mtl": "obj/plane.mtl" // If there is no MTL file set to ""
}
Copy the code

S (‘shape3d’, ‘models/plane.json’) by setting the node’s style shape3D property to this JSON: node.s(‘shape3d’, ‘models/plane.json’).

Attention! Regardless of the method used to load the model, if maps are used in the MTL file, the path of the map needs to be relative to the path of the OBj file.

Modelmap. propeller in the previous code is a Propeller object in the modelMap object defined in the OBJ file, so try printing modelMap and see the output.

Load the tail indicator light

FinishFunc (modelMap, array, rawS3) in this method is used for post-load callback processing. See the HT for Web OBJ manual (hightopo.com/guide/guide…). We also added a “red flashing indicator” for the tail of the plane that was not in the OBJ model. Here we used the composite model Array (an array of all materials containing at least one model). We added a new ball model to the array:

// Add a circular model of indicators
array.push({
    shape3d: ht.Default.createSmoothSphereModel(),
    t3: [- 40.10.0].s3: [6.6.6].color: {
        func: function(data){
            return data.a('light')?'red': 'black'; }}});Copy the code

Where shape3D is an attribute name wrapped in HT, the registered 3D model is either registered by setShape3dModel(name, model) function or returned by getShape3dModel(name) function. How to register 3D models can be found in the HT for Web Modeling Manual (hightopo.com/guide/guide…) .

Data.getattr (‘a’) gets the value of data.setattr (‘a’, value) directly from data.getattr (‘a’). Therefore, THE HT defines the ATTR attribute type, which is reserved for users to store service data. Second, it also makes data binding easier. We can call setAttr methods where we need to change properties, which is very convenient.

Then we pass ht. Default. SetShape3dModel (name, model) to register array we just assembled model into we want “plane” model:

ht.Default.setShape3dModel('plane', array);
Copy the code

Create model nodes

We can use the shape3D attribute to call the model and customize the light and Angle attributes shown in the code above:

plane = new ht.Node();
plane.s3(200.200.200);
plane.s3(rawS3);
plane.s({
    'shape3d': 'plane'.'shape3d.scaleable': false.'wf.visible': true.// Whether the wireframe is visible
    'wf.color': 'white'.'wf.short': true // Whether to display closed wireframes, true is not closed short wireframes
});
plane.a({
    'angle': 0.'light': false
});
Copy the code

animation

Since the plane also has propeller and indicator light functions, we also need to animate these two models. Please refer to the HT for Web animation manual (hightopo.com/guide/guide…). , by the user in the form form the result of choice to decide on the aircraft flight duration, look at the plane Angle, the plane flew along the “route” to rotation Angle, the tail lamp “flashing” function and so on, finally don’t forget the plane stop flight, if you want to keep the plane flying, have to callback the animation, and set up the light no longer flashing, Don’t forget to start the animation:

params = {
    delay: 1500.duration: 20000.easing: function(t){ 
        return (t *= 2) < 1 ? 0.5 * t * t : 0.5 * (1 - (--t) * (t - 2));
    },
    action: function(v, t){
        var length = g3d.getLineLength(polyline),
        offset = g3d.getLineOffset(polyline, length*v),
        point = offset.point,
        px = point.x,
        py = point.y,
        pz = point.z,
        tangent = offset.tangent,
        tx = tangent.x,
        ty = tangent.y,
        tz = tangent.z;
        plane.p3(px, py, pz);
        plane.lookAt([px + tx, py + ty, pz + tz], 'right');
                        
        var camera = formPane.v('Camera');
        if(camera === 'Look At'){
            g3d.setCenter(px, py, pz);
        }
        else if(camera === 'First Person'){                            
            g3d.setEye(px - tx * 400, py - ty * 400 + 30, pz - tz * 400);
            g3d.setCenter(px, py, pz);                            
        }
                        
        plane.a('angle', v*Math.PI*120);                        
        if(this.duration * t % 1000 > 500){
            plane.a('light'.false);
        }else{
            plane.a('light'.true); }},finishFunc: function(){
        animation = ht.Default.startAnim(params);
        plane.a('light'.false); }}; animation = ht.Default.startAnim(params);Copy the code

In fact, what makes us curious is that the path described has nothing to do with the flight of the plane itself. There are so many left and right turns. How can we do it?

Plot the trajectory of an aircraft

polyline = new ht.Polyline();   
polyline.setThickness(2);
polyline.s({
    'shape.border.pattern': [16.16].'shape.border.color': 'red'.'shape.border.gradient.color': 'yellow'.'shape3d.resolution': 300.'3d.selectable': false
});
dataModel.add(polyline);
Copy the code

The above code simply adds a polyline pipeline to the datamodel datamodel. It does not display anything. To display the “channel”, first set the point where the channel is located.

points = [{ x: 0.y: 0.e: 0 }];
segments = [1];
Copy the code

The points and segments are HT for Web Shape manual (hightopo.com/guide/guide…) {x: 100, y: 200}, {x: 100, y: 200}, {x: 100, y: 200} Segments is an array of hT. List line segments that represent the array ordering of the vertices in the points array.

The multiple circular tracks to the left of the “channel” are also set by points and segments:

for(var k=0; k<count+1; k++){
    var angle = k * Math.PI * 2 * round / count;
    points.push({
        x: cx + radius * Math.cos(angle),
        y: cy + radius * Math.sin(angle),
        e: k * height / count
    }); 
    segments.push(2);
}
Copy the code

Segments can only take the value between 1 and 5, with 1 representing the starting point of a new path; 2 indicates the connection from the last point to this point; 3. Information of two points is occupied. The first point is the control point of the curve, and the second point is the end point of the curve. The first and second points are the control points of the curve, and the third point is the end point of the curve. 5 If no point information is occupied, the drawing of the path is complete and the path is closed to the start point:

points.push({ x: cx+radius, y: 0.e: height/2 });
points.push({ x: 0.y: 0.e: height/2 });
segments.push(3);

points.push({ x: radius, y: -radius, e: height/2*0.7 });
points.push({ x: radius*2.y: radius, e: height/2*0.3 });
points.push({ x: radius*3.y: 0.e: 0 });
segments.push(4);   

points.push({ x: 0.y: 0.e: 0 });
segments.push(2);  
Copy the code

We have added all the points on the path to the “channel”, now we need to set all the points on the pipe to display on the screen:

polyline.setPoints(points);
polyline.setSegments(segments);  
Copy the code

The runway

runway = new ht.Node();
runway.s3(-cx+radius*3.1.200);
runway.p3(cx+runway.getWidth()/2.- 22.0);
runway.s({
    'all.color': '#FAFAFA'.'all.transparent': true.'all.reverse.cull': true.'all.opacity': 0.8.'3d.selectable': false
});
dataModel.add(runway);
Copy the code

Finally, add a formPane form panel to the interface. Once defined, it can be added directly to the body, so that it doesn’t have a display connection to the graph3dView.

The form panel

Hightopo.com/guide/guide…

{
    checkBox: {
        label: 'Animation'.selected: true.onValueChanged: function(){
            if(this.isSelected()){
                animation.resume();
            }else{ animation.pause(); }}}}Copy the code

You can also set “ID” to record dynamically changing values, and formPane will retrieve the current value by calling Formpane.v (ID).

The last

The concept of Industrial Internet was first put forward by GE in 2012, which means that the Internet enters the upper reaches of the Industrial chain and radically innovates industries. In-flight connectivity is already available on 78 percent of flights in the United States, according to flight Standard. In the aerospace field, the industrial Internet will break down the information barrier between software, hardware and personnel. Relying on the analysis of big data, the aircraft can establish its own voice, and express to the pilot and maintenance personnel pilot, the specific flight status or where the maintenance. The deep application of industrial Internet technology is changing the use efficiency and manufacturing cost of civil aviation aircraft.

Hightopo.com/demo/large-…

Hightopo.com/demo/cloud-…

Hightopo.com/demo/HTBuil…