在 X3Dom 中添加一个 IndexedLineSet

Adding an IndexedLineSet in X3Dom

当通过 X3Dom 使用 X3D 时,有时我想动态添加对象。例如,我可能有一个像下面这样的函数来添加一行:

function add_line(lineString) {
    var lineString = lineString || random_line();
    var orbit = $("<shape></shape>");
    scene.append(orbit);
    var indexedLineSet = $("<IndexedLineSet></IndexedLineSet>");
    orbit.append(indexedLineSet).attr('coordIndex', '0 1');
    var coordinate = $("<coordinate></coordinate>");
    coordinate.attr('point', lineString);   
    indexedLineSet.append(coordinate)
}

在此代码中,scene 是一个现有的 X3D 场景,random_line 是一个生成定义随机线的字符串的函数,我正在使用 JQuery 操纵场景.在页面加载时调用函数时,它工作得很好。但是,当调用该函数以响应按钮按下时,该行不会出现,尽管它已添加到场景中。

备注:

如果您打开开发者控制台,您会发现:

x3dom.js:3014 Uncaught TypeError: Cannot read property 'getPoints' of null_
buildGeometry @ x3dom.js:3014
nodeChanged @ x3dom.js:3046
x3dom.NodeNameSpace.setupTree @ x3dom.js:2744
onNodeInserted @ x3dom.js:1100
(anonymous function) @ jquery-1.12.4.min.js:3
Ha @ jquery-1.12.4.min.js:3
append @ jquery-1.12.4.min.js:3
add_line @ IndexedLineSet-Test.html:76
(anonymous function) @ IndexedLineSet-Test.html:90
dispatch @ jquery-1.12.4.min.js:3
r.handle @ jquery-1.12.4.min.js:3

查看你原来代码的第76行后,你会发现你必须改变添加点和添加索引的顺序:

var indexedLineSet = $("<IndexedLineSet></IndexedLineSet>");
var coordinate = $("<coordinate></coordinate>");
coordinate.attr('point', lineString);   
indexedLineSet.append(coordinate);
orbit.append(indexedLineSet).attr('coordIndex', '0 1');

它在初始加载时很适合你,因为你在 X3DOM 准备好之前构建了 x3d,检查这个调用何时出现(在你对 add_line 的调用完成之后):

x3dom.runtime.ready = function() {
    console.log('ready');
};

这意味着所有的事件和监听器都还没有设置好。但稍后当您单击该按钮时,X3DOM 已完全初始化。因此它可以监听所有事件并在您将轨道附加到场景后立即触发 onNodeInserted 事件。另一种解决方案是在您的函数末尾进行此调用:

  1. 完整构建 3D 对象
  2. 将对象(轨道)添加到场景中。