Finding direction of 3d model

Hello. I’m new in Cesium. That’s why my questions may be strange. I used cesium samples and combined two samples as following code. The problem is that I want the force applied to the particles be in direction of the car move. But when I want to get the position of the car and subtract that from the particle system position to get the direction, the position is undefined and gives an error in the console. How can I find the right direction? Thank you for helping me.

My code :
var viewer = new Cesium.Viewer(“cesiumContainer”);

//Set the random number seed for consistent results.
Cesium.Math.setRandomNumberSeed(3);

//Set bounds of our simulation time
var start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16));
var stop = Cesium.JulianDate.addSeconds(
start,
120,
new Cesium.JulianDate()
);

//Make sure viewer is at the desired time.
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
viewer.clock.multiplier = 1;
viewer.clock.shouldAnimate = true;

//Set timeline to simulation bounds
viewer.timeline.zoomTo(start, stop);

var entityPosition = new Cesium.Cartesian3();
var entityOrientation = new Cesium.Quaternion();
var rotationMatrix = new Cesium.Matrix3();
var modelMatrix = new Cesium.Matrix4();

function computeModelMatrix(entity, time) {
return entity.computeModelMatrix(time, new Cesium.Matrix4());
}

var emitterModelMatrix = new Cesium.Matrix4();
var translation = new Cesium.Cartesian3();
var rotation = new Cesium.Quaternion();
var hpr = new Cesium.HeadingPitchRoll();
var trs = new Cesium.TranslationRotationScale();

function computeEmitterModelMatrix() {
hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, hpr);
trs.translation = Cesium.Cartesian3.fromElements(
-14.0,
0.0,
1.4,
translation
);
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, rotation);

return Cesium.Matrix4.fromTranslationRotationScale(
trs,
emitterModelMatrix
);
}

var pos1 = Cesium.Cartesian3.fromDegrees(
-75.15787310614596,
39.97862668312678,
1000
);
var pos2 = Cesium.Cartesian3.fromDegrees(
-75.1633691390455,
39.95355089912078,
100
);
var position = new Cesium.SampledPositionProperty();

position.addSample(start, pos1);
position.addSample(stop, pos2);

var planePosition = Cesium.Cartesian3.fromDegrees(
-75.59777,
140.03883,
800.0
);

var m = {

model: {
uri: “…/SampleData/models/CesiumMilkTruck/CesiumMilkTruck.glb”,
minimumPixelSize: 30,
maximumPixelSize:30
},
viewFrom: new Cesium.Cartesian3(-100.0, 0.0, 100.0),
position: position,
orientation: new Cesium.VelocityOrientationProperty(position),
};
var entity = viewer.entities.add(m);
viewer.trackedEntity = entity;

var scene = viewer.scene;

viewer.scene.preUpdate.addEventListener(function (scene, time) {
rocketSystems[0].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[1].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[2].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[3].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[4].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[5].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[6].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[7].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[8].modelMatrix = computeModelMatrix(entity, time);
rocketSystems[9].modelMatrix = computeModelMatrix(entity, time);
});

var particlesOffset = new Cesium.Cartesian3(
-50.950115473940969,
-10.852766731753945,
0.235411095432937
);

var particleCanvas;
function getImage() {
if (!Cesium.defined(particleCanvas)) {
particleCanvas = document.createElement(“canvas”);
particleCanvas.width = 20;
particleCanvas.height = 20;
var context2D = particleCanvas.getContext(“2d”);
context2D.beginPath();
context2D.arc(8, 8, 8, 0, Cesium.Math.TWO_PI, true);
context2D.closePath();
context2D.fillStyle = “rgb(255, 255, 255)”;
context2D.fill();
}
return particleCanvas;
}

// creating the particle systems
var rocketOptions = {
numberOfSystems: 10.0,
iterationOffset: 0.1,
cartographicStep: 0.000001,
baseRadius: 0.0005,

colorOptions: [
{
minimumRed: 1.0,
green: 0.5,
minimumBlue: 0.05,
alpha: 1.0,
},
{
red: 0.9,
minimumGreen: 0.6,
minimumBlue: 0.01,
alpha: 1.0,
},
{
red: 0.8,
green: 0.05,
minimumBlue: 0.09,
alpha: 1.0,
},
{
minimumRed: 1,
minimumGreen: 0.05,
blue: 0.09,
alpha: 1.0,
},
],
};

var scratchCartesian3 = new Cesium.Cartesian3();
var scratchCartographic = new Cesium.Cartographic();
var forceFunction = function (options, iteration) {

console.log(m.position[1]);

return function (particle, dt) {
dt = Cesium.Math.clamp(dt, 0.0, 0.05);

scratchCartesian3 = Cesium.Cartesian3.normalize(
  particle.position,
  new Cesium.Cartesian3()
);
scratchCartesian3 = Cesium.Cartesian3.multiplyByScalar(
  scratchCartesian3,
  -40.0 * dt,
  scratchCartesian3
);

scratchCartesian3 = Cesium.Cartesian3.add(
  particle.position,
  scratchCartesian3,
  scratchCartesian3
);

scratchCartographic = Cesium.Cartographic.fromCartesian(
  scratchCartesian3,
  Cesium.Ellipsoid.WGS84,
  scratchCartographic
);

var angle =
  (Cesium.Math.PI * 2.0 * iteration) / options.numberOfSystems;
iteration += options.iterationOffset;
scratchCartographic.longitude +=
  Math.cos(angle) * options.cartographicStep * 10.0 * dt;
scratchCartographic.latitude +=
  Math.sin(angle) * options.cartographicStep * 10.0 * dt;

particle.position = Cesium.Cartographic.toCartesian(
  scratchCartographic
);

};
};

var matrix4Scratch = new Cesium.Matrix4();
var scratchAngleForOffset = 0.0;
var scratchOffset = new Cesium.Cartesian3();
var imageSize = new Cesium.Cartesian2(15.0, 15.0);

function createParticleSystems(options, systemsArray) {
var length = options.numberOfSystems;
for (var i = 0; i < length; ++i) {
scratchAngleForOffset =
(Math.PI * 2.0 * i) / options.numberOfSystems;
scratchOffset.x +=
options.baseRadius * Math.cos(scratchAngleForOffset);
scratchOffset.y +=
options.baseRadius * Math.sin(scratchAngleForOffset);

var emitterModelMatrix = Cesium.Matrix4.fromTranslation(
  scratchOffset,
  matrix4Scratch
);
var color = Cesium.Color.fromRandom(
  options.colorOptions[i % options.colorOptions.length]
);
var force = forceFunction(options, i);

var item = viewer.scene.primitives.add(
  new Cesium.ParticleSystem({
    image: "../SampleData/smoke.png",
    startColor: color,
    endColor: color.withAlpha(0.0),
    particleLife: 3.5,
    speed: 0.00005,
    imageSize: imageSize,
    emissionRate: 30.0,
    emitter: new Cesium.CircleEmitter(0.1),
    lifetime: 0.1,
    updateCallback: force,

    emitterModelMatrix: computeEmitterModelMatrix(),
  })
);
systemsArray.push(item);

}
}

var rocketSystems = ;
createParticleSystems(rocketOptions, rocketSystems);

To get a dynamic entity’s postion, use entity.position.getValue(viewer.clock.currentTime). There’s an example of this in this code example that gets the velocity at each timestamp in order to create a label with the vehicle’s speed: https://sandcastle.cesium.com/index.html?src=Time%20Dynamic%20Wheels.html.

When sharing your code, please follow the instructions here to share a Sandcastle example on the forum: How to share custom Sandcastle examples

thank you . it is working.

1 Like