Reputation: 35
I am trying to draw several triangles in one instance with cesium. My code works for drawing only one triangle but when I extend the positions (for two or many triangles) I get errors.
var extent = Cesium.Rectangle.fromDegrees(100, 30, 108, 36);
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
Cesium.Camera.DEFAULT_VIEW_FACTOR = 0.5;
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationHelpButton: false, animation: false, timeline: false
});
// original sample begins here
var mypositions = Cesium.Cartesian3.fromDegreesArrayHeights([
-94.6714,35.9641,322.543,
-94.6717,35.9642,325.51,
-94.6717, 35.9639, 324.724,
-94.6717,35.9639,324.717,
-94.6717,35.9639,324.724,
-94.6717,35.9639,324.719 ]);
// unroll 'mypositions' into a flat array here
var numPositions = mypositions.length;
var pos = new Float64Array(numPositions * 3);
for (var i = 0; i < numPositions; ++i) {
pos[i * 3] = mypositions[i].x;
pos[i * 3 + 1] = mypositions[i].y;
pos[i * 3 + 2] = mypositions[i].z;
}
var geometry = new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE, // not FLOAT
componentsPerAttribute: 3,
values: pos
}),
normal: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: new Float32Array([255.0, 0.0, 0.0, 0.0, 255.0, 0.0, 0.0, 0.0, 255.0])
})
},
indices: new Uint32Array([0, 1, 2]),
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: Cesium.BoundingSphere.fromVertices(pos)
});
var myInstance = new Cesium.GeometryInstance({
geometry: geometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
},
show: new Cesium.ShowGeometryInstanceAttribute(true)
});
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: [myInstance],
asynchronous: false,
appearance: new Cesium.PerInstanceColorAppearance({
closed: true,
translucent: false
})
}));
And the error I get is:
All attributes lists must have the same number of attributes.
How can I extend this code to draw multiple triangles?
Upvotes: 1
Views: 1571
Reputation: 12448
This error is telling you that the positions, normals, and indices (if present) must all agree on the total number of points. In the case above, you've provided normal vectors and indices for only one of the two triangles.
Actually you don't need to provide indices if your triangles don't share a vertex anywhere. So, I've commented that line out in the code below, and wrote normal vectors for all triangles.
Note that this is the lowest-level way to create geometry in Cesium, there are much easier ways at the higher level, for example CZML Polygons or Entity.polygon.
Still, here's a copy of your code with some issues fixed:
var extent = Cesium.Rectangle.fromDegrees(-98, 30, -90, 39);
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
Cesium.Camera.DEFAULT_VIEW_FACTOR = 0.5;
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationHelpButton: false, animation: false, timeline: false
});
var mypositions = Cesium.Cartesian3.fromDegreesArrayHeights([
// Triangle A
-90.6714, 35.9641, 322.543,
-94.6717, 38.9642, 325.51,
-97.6717, 35.9639, 324.724,
// Triangle B
-94.6717, 30.9639, 324.717,
-90.6717, 32.9639, 324.724,
-94.6717, 34.9639, 324.719 ]);
// unroll 'mypositions' into a flat array here
var numPositions = mypositions.length;
var pos = new Float64Array(numPositions * 3);
var normals = new Float32Array(numPositions * 3);
for (var i = 0; i < numPositions; ++i) {
pos[i * 3] = mypositions[i].x;
pos[i * 3 + 1] = mypositions[i].y;
pos[i * 3 + 2] = mypositions[i].z;
normals[i * 3] = 0.0;
normals[i * 3 + 1] = 0.0;
normals[i * 3 + 2] = 1.0;
}
var geometry = new Cesium.Geometry({
attributes: {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE, // not FLOAT
componentsPerAttribute: 3,
values: pos
}),
normal: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: normals
})
},
// Don't need the following line if no vertices are shared.
//indices: new Uint32Array([0, 1, 2, 3, 4, 5]),
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: Cesium.BoundingSphere.fromVertices(pos)
});
var myInstance = new Cesium.GeometryInstance({
geometry: geometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
},
show: new Cesium.ShowGeometryInstanceAttribute(true)
});
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances: [myInstance],
asynchronous: false,
appearance: new Cesium.PerInstanceColorAppearance({
closed: true,
translucent: false
})
}));
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.16/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.16/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>
Upvotes: 3