Time Dynamic Wheels.html 5.91 KB
Newer Older
Schaaf's avatar
Schaaf committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <meta
      name="description"
      content="Dynamically rotate a model's wheels based on its velocity using node transformations."
    />
    <meta name="cesium-sandcastle-labels" content="Showcases" />
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script
      type="text/javascript"
      src="../../../Build/CesiumUnminified/Cesium.js"
      nomodule
    ></script>
    <script type="module" src="../load-cesium-es6.js"></script>
  </head>
  <body
    class="sandcastle-loading"
    data-sandcastle-bucket="bucket-requirejs.html"
  >
    <style>
      @import url(../templates/bucket.css);
    </style>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="loadingOverlay"><h1>Loading...</h1></div>
    <div id="toolbar"></div>
    <script id="cesium_sandcastle_script">
      function startup(Cesium) {
        "use strict";
        //Sandcastle_Begin
        var viewer = new Cesium.Viewer("cesiumContainer", {
          shouldAnimate: true,
        });

        //Make sure viewer is at the desired time.
        var start = Cesium.JulianDate.fromDate(new Date(2018, 11, 12, 15));
        var totalSeconds = 10;
        var stop = Cesium.JulianDate.addSeconds(
          start,
          totalSeconds,
          new Cesium.JulianDate()
        );
        viewer.clock.startTime = start.clone();
        viewer.clock.stopTime = stop.clone();
        viewer.clock.currentTime = start.clone();
        viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
        viewer.timeline.zoomTo(start, stop);

        // Create a path for our vehicle by lerping between two positions.
        var position = new Cesium.SampledPositionProperty();
        var startPosition = new Cesium.Cartesian3(
          -2379556.799372864,
          -4665528.205030263,
          3628013.106599678
        );
        var endPosition = new Cesium.Cartesian3(
          -2379603.7074103747,
          -4665623.48990283,
          3627860.82704567
        );
        // A velocity vector property will give us the entity's speed and direction at any given time.
        var velocityVectorProperty = new Cesium.VelocityVectorProperty(
          position,
          false
        );
        var velocityVector = new Cesium.Cartesian3();
        // Store the wheel's rotation over time in a SampledProperty.
        var wheelAngleProperty = new Cesium.SampledProperty(Number);
        var wheelAngle = 0;

        var numberOfSamples = 100;
        for (var i = 0; i <= numberOfSamples; ++i) {
          var factor = i / numberOfSamples;
          var time = Cesium.JulianDate.addSeconds(
            start,
            factor * totalSeconds,
            new Cesium.JulianDate()
          );

          // Lerp using a non-linear factor so that the vehicle accelerates.
          var locationFactor = Math.pow(factor, 2);
          var location = Cesium.Cartesian3.lerp(
            startPosition,
            endPosition,
            locationFactor,
            new Cesium.Cartesian3()
          );
          position.addSample(time, location);
          // Rotate the wheels based on how fast the vehicle is moving at each timestep.
          velocityVectorProperty.getValue(time, velocityVector);
          var metersPerSecond = Cesium.Cartesian3.magnitude(velocityVector);
          var wheelRadius = 0.52; //in meters.
          var circumference = Math.PI * wheelRadius * 2;
          var rotationsPerSecond = metersPerSecond / circumference;

          wheelAngle +=
            ((Math.PI * 2 * totalSeconds) / numberOfSamples) *
            rotationsPerSecond;
          wheelAngleProperty.addSample(time, wheelAngle);
        }

        function updateSpeedLabel(time, result) {
          velocityVectorProperty.getValue(time, velocityVector);
          var metersPerSecond = Cesium.Cartesian3.magnitude(velocityVector);
          var kmPerHour = Math.round(metersPerSecond * 3.6);

          return kmPerHour + " km/hr";
        }

        var rotationProperty = new Cesium.CallbackProperty(function (
          time,
          result
        ) {
          return Cesium.Quaternion.fromAxisAngle(
            Cesium.Cartesian3.UNIT_X,
            wheelAngleProperty.getValue(time),
            result
          );
        },
        false);

        var wheelTransformation = new Cesium.NodeTransformationProperty({
          rotation: rotationProperty,
        });

        var nodeTransformations = {
          Wheels: wheelTransformation,
          Wheels_mid: wheelTransformation,
          Wheels_rear: wheelTransformation,
        };

        // Add our vehicle model.
        var vehicleEntity = viewer.entities.add({
          position: position,
          orientation: new Cesium.VelocityOrientationProperty(position), // Automatically set the vehicle's orientation to the direction it's facing.
          model: {
            uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb",
            runAnimations: false,
            nodeTransformations: nodeTransformations,
          },
          label: {
            text: new Cesium.CallbackProperty(updateSpeedLabel, false),
            font: "20px sans-serif",
            showBackground: true,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              0.0,
              100.0
            ),
            eyeOffset: new Cesium.Cartesian3(0, 3.5, 0),
          },
        });

        viewer.trackedEntity = vehicleEntity;
        vehicleEntity.viewFrom = new Cesium.Cartesian3(-10.0, 7.0, 4.0);
        //Sandcastle_End
        Sandcastle.finishedLoading();
      }
      if (typeof Cesium !== "undefined") {
        window.startupCalled = true;
        startup(Cesium);
      }
    </script>
  </body>
</html>