A-Frame: Невозможно успешно установить мировое положение дочернего объекта сцены. - PullRequest
1 голос
/ 11 апреля 2019

По сути, в моей сцене у меня есть существо с лазерным управлением и raycaster в следующей структуре:

   <a-scene>
        <a-entity laser-controls raycaster ...>
        <!--<a-entity id="inventory" ...> Could be inserted here-->
        </a-entity>
        <!--<a-entity id="inventory" ...> Could be inserted here-->
    </a-scene>

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

Подходы, которые я пробовал и потерпел неудачу:

  • Начало инвентаризации в роли ребенка от Raycaster и смена родителя на сцене и применение мировой матрицы Raycaster
  • Хранение инвентаря как ребенка-рейкастера, захват его начальной матрицы мира и установка той же самой матрицы мира на каждом тике

И, наконец, мой текущий подход (с кодом), который все еще не работает

1. Преобразование локальных координат конца линии в мировые координаты

2. Добавление инвентаря к сцене

3. Преобразование мировых координат от конца строки в локальные координаты сцены

4.Применение позиции в 3 к инвентарю

let v = this.emptyVec
v.copy(this.raycaster.components.line.data.end)
this.raycaster.object3D.localToWorld(v);
this.el.appendChild(inventoryNode) //this.el is the scene
this.el.object3D.worldToLocal(v);
const {x,y} = v
inventoryNode.object3D.position.set(x,y,inventoryZDistance)

TLDR: Как установить объект в положение конца линии raycaster в тот момент, когда я добавляю его в сцену и оставляю его в этом положении навсегда

1 Ответ

0 голосов
/ 11 апреля 2019

Закончилось поиском решения.Он запускается на приемнике событий для события щелчка контроллера (если ему не нужно запускаться на каждом тике, он запускается только один раз)

  1. Создан фиктивный узел, который является дочерним дляraycaster и установите его положение в координаты x, y конца линии и любую желаемую координату z
  2. Добавил соответствующий узел инвентаря к сцене
  3. Установите положение инвентаряиз мировой матрицы фиктивного узла с помощью метода setFromMatrixPosition ()

    let dummyNode = document.createElement("a-entity")
    dummyNode.setAttribute("id", "dummyinventory")
    dummyNode.setAttribute("visible", false) //maybe unnecessary
    const {x,y} = this.raycaster.components.line.data.end
    dummyNode.object3D.position.set(x,y,inventoryZDistance)
    this.raycaster.appendChild(dummyNode)
    
    inventoryNode.setAttribute('look-at', "[camera]") //if you want inventory to face the camera
    this.el.appendChild(inventoryNode)
    setTimeout(()=>{
        let newMatrix = dummyNode.object3D.matrixWorld
        inventoryNode.object3D.position.setFromMatrixPosition(newMatrix)
    },50) //give the world matrix of dummyNode some time to update, with no timeout sometimes fails
    

Тот же самый мыслительный процесс может быть применен, если кто-то хочет порождать некоторую сущность, на которую смотрит пользователь, имеяфиктивный узел будет дочерним элементом камеры вместо raycaster

...