The Internet of Things, or IoT, simply means that objects are connected via the Internet. Everything in the world can be intelligently managed by changing data. The rise of IoT has the potential to save lives in the healthcare industry. IoT is sure to become ubiquitous in the medical industry in the future as it constantly collects user information and performs diagnostics in real time. The following is a medical logistics system I recently made to observe the medical logistics process.

The demo link:

Increase the light source

The whole scene is actually very dark, so we need to use the lighting effect to illuminate the whole scene and make it close to the real world scene.

Let’s look at the comparison.

Some properties of light:

Type indicates the type of light

Color stands for the color of the light

Intensity represents the intensity of the light (1 is the maximum)

Range stands for range

addLight() {
        const skyBox ='skyBox'This.gv.setskybox (skyBox) const light = new ht.Light() const lightSource = ()'sunlight').p3()

        const config = {
            'light.type': 'point'.'light.color': 'white'.'light.intensity': 0.3.'light.range': 10000

Copy the code

Look at the object

A small window in the bottom left corner is actually another 3D scene. I positioned it in the bottom left corner. Both scenes were deserialized.

The flyTo method is used to locate the motion of the medical kit.

var renderCanvas = function (medical, duration) {
       easing(v, t) {
         return t
       action(v, t) {
         outScreenG3d.flyTo(medical, { direction: [-5, 3, 5], distance: 300 })
 }Copy the code

Encapsulation animation

If you want to achieve so many animations, the first thing that comes to mind is the process of moving objects. We can encapsulate the movement of the medical box, the lifting of the elevator, the delivery of the medical box and so on.

As can be seen in the figure, the medical box is always moving, so a walking animation is defined, and the distance, direction and configuration of the animation are transmitted for each medical box.

The parameters to specify here:

1. Node (corresponding element)

2.fn (callback function after animation execution)

3. Config (Animation configuration)

4. Coord (Direction axis)

WalkAnim (node, fn, config, coord) {const {duration, space} = config const positionArray = node.p3()let isShadow = false
   letShadowNode = null // Get the shadow of the moving element if it is icu or supplyif (node.getTag() === 'supply' || node.getTag() === 'icuCar') {isShadow =trueShadowNode =`${node.getTag()}Shadow ')} ht.default.startanim ({duration, easing:function(t) {returnt }, action(v, t) {if (coord === 'x') {node.p3(positionArray[0] + t * space, positionArray[1], PositionArray [2]) isShadow && ShadowNode.p3(positionArray[0] + T * space, positionArray[1], positionArray[2])}else if (coord === 'y') {node.p3(positionArray[0], positionArray[1] + t * space, PositionArray [2]) isShadow && ShadowNode.p3(positionArray[0], positionArray[1] + T * space, positionArray[2])}else {
           node.p3(positionArray[0], positionArray[1], positionArray[2] + t * space)
           isShadow && ShadowNode.p3(positionArray[0], positionArray[1], positionArray[2] + t * space)
      finishFunc() {
         typeof fn === 'function' && fn(node)
}Copy the code

The influence between objects

The rise and fall of the elevator will affect many things, such as the movement of the channel with conveyor belts and medical boxes. Here, I use the Sethost adsorption method (adsorption: the node designates the host, and the change of the host will affect the node).

It is very suitable in many scenarios. I need to take the medical case and the platform to rise together when the elevator goes up and down, and when the medical case is put on the conveyor belt, the medical case should move, and it feels like the conveyor belt is really driving the medical case to move.

The parameters to specify here:

1. Node (Operating elevator element)

2. MedicalKit

3.fn (callback function after animation execution)

4. Status (elevator ascending and descending state)

5. Config (Animation configuration)

// elevatorAnim(node, medicalKit, fn, status, Config) {const self = this const elevatorIndex = node.getTag().replace(/[^0-9]/ig,' 'Const medicalKitIndex = medicalkit.getTag ().replace(/[^0-9]/ig,' ') - 0
        const positionArray = node.p3()
        const station =`station${elevatorIndex}') // Adsorb the host station.sethost (node) medicalKit.sethost (node) // Set the ascending and descending stateif (elevatorIndex === 3) self.elevatorRunning = true/ / lifting distance status of 0 is falling when the lowest parts of the distance is fixed So you just need to control rising distance const medicalKitLevel = self. ReturnMedicalKitLevel (medicalKitIndex) OrbitalP orbitalP // The first floor is located in distanceletspace const addSpace = medicalKitIndex === 7 ? 100:0if (status == 1) {
            space = config.orbitalP ? config.orbitalP : config.distance + addSpace + (400 * medicalKitLevel)
        } else{space = config.lowest} // The medical box does not take action while descendingif (status === 0) {

        returnht.Default.startAnim({ duration: config.orbitalP ? 2000 : (medicalKitLevel === 0 && elevatorIndex == 3 ? 700: 2500 + (medicalKitLevel * 1000)), action(v, t) { node.p3( positionArray[0], positionArray[1] + ((space - positionArray[1]) * t), positionArray[2] ) },finishFunc() {
                typeof fn === 'function' && fn(node)
    }Copy the code

Animation method

In the process of animation, there is a problem that needs to be dealt with, which is the animation of waiting for the elevator. During the animation, the medical box needs to determine whether the elevator is rising or not. If it is not on the ground, it needs to wait.

My idea is that when the medical box is a little distance from the elevator, we need to determine whether the elevator is rising, if so, we need to call the animation pause method.

When elevatorRunning is false, the elevator is not moving, otherwise it is in motion.

Set the elevator animation to true at the beginning and false at the end to monitor its state.

The HT.default. startAnim method returns an instance that uses the Action method to implement polling to listen for animation state and then operate.

When elevatorRunning is true, use im.pause() to pause the current animation.

When elevatorRunning is false, use im.resume() to continue the current animation.

Const anim = ht.default. startAnim({duration, action(v, t) {node.p3(positionArray[0], PositionArray [1], positionArray[2] - (tpmax-positionArray [2]) * t);if (index > 1 && self.elevatorRunning === true) {if(Node.p3 ()[2] <= stopMax) {im.pause(); const t =setInterval(() => {if (self.elevatorRunning === false) {anim. Resume (); ClearInterval (t); }}, 100); }}},finishFunc() { typeof fn ==="function"&& fn(); }});Copy the code

Event listening (publish, subscribe)

Because you need to listen for the end of one of the current animations and then do the camera shift.

As shown, I need to listen for the first 3D scene to display the prompt text animation to end, and then perform the second 3D scene display. Since the two scenarios are different and cannot be monitored by callback, the eventBus is used here.

Here is the use of eventBus, with the first parameter representing the name of the registration function to listen on and the second the callback function.

Eventbus. on('animation1', _ => {
  const medical = dm.getDataByTag('medicalKit1')
  renderView(medical, dm, gv)
})Copy the code

Here is the use of eventBus emission, where the first parameter represents the name of the function to fire and the second parameter is the parameter to fire to the function.

// Eventbus.emit ("animation1", null);Copy the code