在 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 操纵场景.在页面加载时调用函数时,它工作得很好。但是,当调用该函数以响应按钮按下时,该行不会出现,尽管它已添加到场景中。
备注:
- 问题似乎取决于我尝试添加的对象类型。可以毫无问题地添加球体。
- 根据 Firefox 的检查器,
IndexedLineScene
似乎已正确添加到场景中;它只是没有出现在图像中。
如果您打开开发者控制台,您会发现:
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
事件。另一种解决方案是在您的函数末尾进行此调用:
- 完整构建 3D 对象
- 将对象(轨道)添加到场景中。
当通过 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 操纵场景.在页面加载时调用函数时,它工作得很好。但是,当调用该函数以响应按钮按下时,该行不会出现,尽管它已添加到场景中。
备注:
- 问题似乎取决于我尝试添加的对象类型。可以毫无问题地添加球体。
- 根据 Firefox 的检查器,
IndexedLineScene
似乎已正确添加到场景中;它只是没有出现在图像中。
如果您打开开发者控制台,您会发现:
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
事件。另一种解决方案是在您的函数末尾进行此调用:
- 完整构建 3D 对象
- 将对象(轨道)添加到场景中。