Сущность не обновляется визуально при изменении ее положения

Название говорит само за себя, я не могу заставить объект перемещаться по земному шару визуально, даже если его положение перемещается. Этот код воспроизведет проблему в Sandcastle:

var viewer = new Cesium.Viewer('cesiumContainer');

var e = viewer.entities.add({
    name : 'Sphere',
    position: Cesium.Cartesian3.fromDegrees(-100, 30.0, 300000.0),
    ellipsoid : {
        radii : new Cesium.Cartesian3(200000.0, 200000.0, 200000.0)
    }
});

viewer.scene.postRender.addEventListener(function(scene, time) {
    var pos = e.position._value;

    var cart = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pos);

    pos = Cesium.Cartesian3.fromRadians(cart.longitude + (1 * Math.PI / 180), cart.latitude, cart.height);

    e.position = pos;
});

Если вы выберете сферу в демоверсии, вы увидите, что зеленый индикатор выбора будет перемещаться по земному шару, но сфера застрянет на одном месте. Я предполагаю, что мне не хватает какого-то простого вызова функции, но я гуглил последние несколько часов и не могу найти решение.

Я уже просмотрел демонстрацию Picking на Sandcastle, но там нет ничего подходящего. Функциональность, которую я ищу, состоит в том, чтобы просто иметь форму, бесконечно повторяющую один и тот же набор координат, поэтому я не могу использовать SampledPositionProperty, насколько я видел в любом случае.


person RIPTuan    schedule 11.01.2016    source источник
comment
Привет RIPTuan, Добро пожаловать в SO. К вашему сведению: вам не нужны теги в заголовке. Я пошел вперед и внес изменения.   -  person Trisped    schedule 14.01.2016
comment
Если вы выберете сферу в демо.. Можете ли вы поделиться ссылкой на демо?   -  person meen    schedule 14.01.2016
comment
@Trisped Спасибо, извините за название.   -  person RIPTuan    schedule 14.01.2016
comment
@meen, код, который я разместил в вопросе, можно вставить в Cesium's Sandcastle для создания демонстрации, на которую я ссылался.   -  person RIPTuan    schedule 14.01.2016


Ответы (1)


Я подозреваю, что причина этого немного сложна: в Cesium геометрия эллипсоида строится асинхронно Web Worker. Запрашивая изменение позиции с каждым событием postRender, вы, по сути, изматываете работника, он не может выполнить один запрос до того, как начнется следующий. Таким образом, мы вообще никогда не видим обновления позиции. Если вы немного уменьшите скорость, вы заметите, что позиция обновляется.

Например, вот ваш код снова с заменой postRender на setInterval из 400 мс. Это больше похоже на тиканье часов, чем на плавную анимацию, но показывает обновляемую позицию:

var viewer = new Cesium.Viewer('cesiumContainer');

var e = viewer.entities.add({
    name : 'Sphere',
    position: Cesium.Cartesian3.fromDegrees(-100, 30.0, 300000.0),
    ellipsoid : {
        radii : new Cesium.Cartesian3(200000.0, 200000.0, 200000.0)
    }
});

window.setInterval(function() {
    var pos = e.position._value;

    var cart = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pos);

    pos = Cesium.Cartesian3.fromRadians(cart.longitude + (1 * Math.PI / 180), cart.latitude, cart.height);

    e.position = pos;
}, 400);

В настоящее время из Entity API невозможно узнать, когда рабочий процесс закончит обновление геометрии. Возможно, вам придется переместить этот пример из Entity API и вместо этого использовать Primitive API.

person emackey    schedule 13.01.2016
comment
Спасибо, я изменил его на примитив, и он без проблем работает в прослушивателе postRender. Однако я не уверен, как получить позицию из примитива; Я храню Cartesian3 под названием 'pos' вне примитива, обновляю его и устанавливаю позицию примитива, используя 'p.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(pos);' который взят прямо из вики. Есть ли лучший способ сделать это, и является ли прослушиватель postRender приемлемым местом для его размещения? - person RIPTuan; 14.01.2016
comment
Это звучит нормально для меня. Если у вас есть опасения по этому поводу, вы можете опубликовать новый вопрос с конкретными деталями. - person emackey; 14.01.2016