Reusing JSON object nodes with SceneJS
I've created a webgl animation using the scenejs framework. As it'll contain a lot of identical elements, I want to minimize the amount of code used and re-use the elements as much as possible.
Firstly, I've got diskJSON defined as following:
var diskJSON = [{
type: "disk",
radius: 3,
inner_radius: 2}];
When I run the following code with sceneJS, it works fine.
{
type: "material",
emit: 0,
baseColor: {
r: 0.3,
g: 0.3,
b: 0.9
},
specularColor: {
r: 0.9,
g: 0.9,
b: 0.9
},
specular: 0.9,
shine: 100.0,
nodes: [ {
type: "translate",
x:10,
y:1,
nodes: [
{
type: "translate",
z:speedMultiplier*0.8,
nodes:[{
type: "disk",
radius: 3,
inner_radius: 2
}]
},
{
type: "translate",
z:speedMultiplier*9.8,
开发者_如何学C nodes:[{
type: "disk",
radius: 3,
inner_radius: 2
}]
},
{
type: "translate",
z:speedMultiplier*11.64,
nodes:[{
type: "disk",
radius: 3,
inner_radius: 2
}]
},
{
type: "translate",
z:speedMultiplier*13.32,
nodes:[{
type: "disk",
radius: 3,
inner_radius: 2
}]
}
]
}
]
}
However, when I try to reuse the same diskJSON as defined previously, it only creates one node, instead of 4:
{
type: "material",
emit: 0,
baseColor: {
r: 0.3,
g: 0.3,
b: 0.9
},
specularColor: {
r: 0.9,
g: 0.9,
b: 0.9
},
specular: 0.9,
shine: 100.0,
nodes: [ {
type: "translate",
x:10,
y:1,
nodes: [
{
type: "translate",
z:speedMultiplier*0.8,
nodes:diskJSON
},
{
type: "translate",
z:speedMultiplier*9.8,
nodes:diskJSON
},
{
type: "translate",
z:speedMultiplier*11.64,
nodes:diskJSON
},
{
type: "translate",
z:speedMultiplier*13.32,
nodes:diskJSON
}
]
}
]
}
The application will have thousands of these nodes, so having to redefine it every single time seems quite a waste. Is this a problem with scenejs or is this working as intended in regards to Javascript/JSON functionality?
Hey Niklas, you've found a bug in the way SceneJS is parsing the JSON - SceneJS is marking the node objects as visited in a map while it DFS traverses them. So in this case it's marking your "disk" node once as it parses it, then never parsing it again.
Raised an issue here: https://github.com/xeolabs/scenejs/issues/99
Fixing this one as priority.
In the meantime, you could use a factory function:
function newDiskJSON() { return [{ type: "disk", radius: 3, inner_radius: 2}]; };
//...
nodes: [
{
type: "translate",
z:speedMultiplier*0.8,
nodes: newDiskJSON()
// ...
Or use the "instance" node:
http://scenejs.wikispaces.com/instance
cheers, LK
精彩评论