1. A concise explanation of the problem you’re experiencing.
Hi,I wrote a custom geometry(GroundTinGeometry) that used to add a small triangle on terria,some parts of triangle isn’t rendered.
Here is my codes,please give me more suggestions.
2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it.
var positions = Cesium.Cartesian3.fromDegreesArrayHeights([
104.3, 31.5, 8000,
104.5, 31.6, 8000,
104.4, 31.7, 8000
]);
var numPositions = positions.length;
var pos = new Float64Array(numPositions * 3);
for (var i = 0; i < numPositions; ++i) {
pos[i * 3] = positions[i].x;
pos[i * 3 + 1] = positions[i].y;
pos[i * 3 + 2] = positions[i].z;
}
var geometry = new Cesium.GroundTinGeometry({
attributes: {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: pos
})
},
indices: new Uint32Array([0, 1, 2])
});
var geoInstance = new Cesium.GeometryInstance({
geometry: geometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
}
});
viewer.scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstances: [geoInstance],
asynchronous: true,
appearance: new Cesium.PerInstanceColorAppearance({
flat: true,
translucent: false
})
}));
// based on Cesium.RectangleGeometry
define(‘Core/GroundTinGeometry’,[
‘./arrayFill’,
‘./BoundingSphere’,
‘./Cartesian2’,
‘./Cartesian3’,
‘./Cartographic’,
‘./Check’,
‘./ComponentDatatype’,
‘./defaultValue’,
‘./defined’,
‘./defineProperties’,
‘./DeveloperError’,
‘./Ellipsoid’,
‘./Geometry’,
‘./GeometryAttribute’,
‘./GeometryAttributes’,
‘./GeometryInstance’,
‘./GeometryOffsetAttribute’,
‘./GeometryPipeline’,
‘./IndexDatatype’,
‘./Math’,
‘./Matrix2’,
‘./Matrix3’,
‘./PolygonPipeline’,
‘./PrimitiveType’,
‘./Quaternion’,
‘./Rectangle’,
‘./RectangleGeometryLibrary’,
‘./VertexFormat’],function(
arrayFill,
BoundingSphere,
Cartesian2,
Cartesian3,
Cartographic,
Check,
ComponentDatatype,
defaultValue,
defined,
defineProperties,
DeveloperError,
Ellipsoid,
Geometry,
GeometryAttribute,
GeometryAttributes,
GeometryInstance,
GeometryOffsetAttribute,
GeometryPipeline,
IndexDatatype,
CesiumMath,
Matrix2,
Matrix3,
PolygonPipeline,
PrimitiveType,
Quaternion,
Rectangle,
RectangleGeometryLibrary,
VertexFormat){
‘use strict’;
var bottomBoundingSphere = new BoundingSphere();
var topBoundingSphere = new BoundingSphere();
var normalScratch = new Cartesian3();
function GroundTinGeometry(options){
var vertices=options.attributes.position.values;
this._positions=;
var i=0;
for(;i<vertices.length;i+=3){
this._positions.push(new Cartesian3(vertices[i],vertices[i+1],vertices[i+2]));
}
this.attributes = options.attributes;
this.indices=options.indices;
this.primitiveType=PrimitiveType.TRIANGLES;
this.boundingSphere=BoundingSphere.fromVertices(vertices);
this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT));
this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84));
this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE);
this._height = defaultValue(options.height, 0.0);
this._extrudedHeight = defaultValue(options.extrudedHeight, this._height);
this._surfaceHeight = Math.max(this._height, this._extrudedHeight);
this._workerName = ‘createGroundTinGeometry’;
this._rectangle = undefined;
this._textureCoordinateRotationPoints = undefined;
}
GroundTinGeometry.createGeometry=function(groundTinGeometry){
var vertexFormat = groundTinGeometry._vertexFormat;
var ellipsoid = groundTinGeometry._ellipsoid;
var granularity = groundTinGeometry._granularity;
var t_positions=groundTinGeometry._positions;
var t_indices=groundTinGeometry.indices;
var rectangle = groundTinGeometry._rectangle;
var extrudedHeight = groundTinGeometry._extrudedHeight;
var surfaceHeight=groundTinGeometry._surfaceHeight;
var extrude = !CesiumMath.equalsEpsilon(surfaceHeight, extrudedHeight, 0, CesiumMath.EPSILON2);
var geometries = ;
var i=0;
var boundingSphere;
for(;i<t_indices.length;i+=3){
var triangle=[t_positions[t_indices[i]],t_positions[t_indices[i+1]],t_positions[t_indices[i+2]]];
var geo;
if(extrude){
geo=constructExtrudedTriangle(triangle,ellipsoid,extrudedHeight,surfaceHeight);
}else{
geo=constructTriangle(triangle,ellipsoid);
geo.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geo.attributes.position.values, surfaceHeight, ellipsoid, false);
}
geometries.push(new GeometryInstance({
geometry : geo
}));
}
var geometry = GeometryPipeline.combineInstances(geometries)[0];
geometry.attributes.position.values = new Float64Array(geometry.attributes.position.values);
geometry.indices = IndexDatatype.createTypedArray(geometry.attributes.position.values.length / 3, geometry.indices);
var attributes = geometry.attributes;
boundingSphere = BoundingSphere.fromVertices(attributes.position.values);
return new Geometry({
attributes : attributes,
indices : geometry.indices,
primitiveType : geometry.primitiveType,
boundingSphere : boundingSphere
});
}
GroundTinGeometry.createShadowVolume=function(groundTinGeometry, minHeightFunc, maxHeightFunc){
var granularity = groundTinGeometry._granularity;
var ellipsoid = groundTinGeometry._ellipsoid;
var minHeight = minHeightFunc(granularity, ellipsoid);
var maxHeight = maxHeightFunc(granularity, ellipsoid);
return new GroundTinGeometry({
attributes:groundTinGeometry.attributes,
indices:groundTinGeometry.indices,
granularity : granularity,
extrudedHeight : minHeight,
height : maxHeight,
vertexFormat : VertexFormat.POSITION_ONLY,
shadowVolume: true
});
}
function constructTriangle(triangle,ellipsoid,data){
var numPositions = triangle.length;
var pos = new Float64Array(numPositions * 3);
var normals = new Float32Array(numPositions*3);
var normal = normalScratch;
for (var i = 0; i < numPositions; ++i) {
pos[i * 3] = triangle[i].x;
pos[i * 3 + 1] = triangle[i].y;
pos[i * 3 + 2] = triangle[i].z;
var p=new Cartesian3(triangle[i].x,triangle[i].y,triangle[i].z);
normal = ellipsoid.geodeticSurfaceNormal(p, normal);
normals[i * 3] = normal.x;
normals[i * 3+1] = normal.y;
normals[i * 3+2] = normal.z;
}
return new Geometry({
attributes: {
position: new GeometryAttribute({
componentDatatype: ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: pos
}),
normal:new GeometryAttribute({
componentDatatype : ComponentDatatype.FLOAT,
componentsPerAttribute : 3,
values : normals
})
},
indices: new Uint32Array([0, 1, 2]),
primitiveType: PrimitiveType.TRIANGLES,
boundingSphere: BoundingSphere.fromVertices(pos)
});
}
function constructExtrudedTriangle(triangle,ellipsoid,minHeight,maxHeight,data){
var topBottomGeo = constructTriangle(triangle,ellipsoid);
var topPositions = PolygonPipeline.scaleToGeodeticHeight(topBottomGeo.attributes.position.values, maxHeight, ellipsoid, false);
topPositions = new Float64Array(topPositions);
var length = topPositions.length;
var newLength = length * 2;
var positions = new Float64Array(newLength);
positions.set(topPositions);
var bottomPositions = PolygonPipeline.scaleToGeodeticHeight(topBottomGeo.attributes.position.values, minHeight, ellipsoid);
positions.set(bottomPositions, length);
topBottomGeo.attributes.position.values = positions;
var normals =new Float32Array(newLength);
var topNormals = topBottomGeo.attributes.normal.values;
normals.set(topNormals);
for (var i = 0; i < length; i++) {
topNormals[i] = -topNormals[i];
}
normals.set(topNormals, length);
topBottomGeo.attributes.normal.values = normals;
topBottomGeo.indices = new Uint32Array([0,1,2,5,4,3]);
var wallIndices =new Uint32Array([0,1,4,
4,3,0,
1,2,4,
4,5,2,
0,2,3,
3,5,2]);
var wallGeo = new Geometry({
attributes: {
position: new GeometryAttribute({
componentDatatype: ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: positions
}),
normal:new GeometryAttribute({
componentDatatype : ComponentDatatype.FLOAT,
componentsPerAttribute : 3,
values : normals
})
},
indices: wallIndices,
primitiveType: PrimitiveType.TRIANGLES,
boundingSphere: BoundingSphere.fromVertices(positions)
});
var geo = GeometryPipeline.combineInstances([
new GeometryInstance({
geometry : topBottomGeo
}),
new GeometryInstance({
geometry : wallGeo
})
]);
return geo[0];
}
function computeRectangle(positions, ellipsoid, result){
if (!defined(positions) || positions.length < 3) {
if (!defined(result)) {
return new Rectangle();
}
result.west = 0.0;
result.north = 0.0;
result.south = 0.0;
result.east = 0.0;
return result;
}
return Rectangle.fromCartesianArray(positions, ellipsoid, result);
}
function textureCoordinateRotationPoints(groundTinGeometry) {
return [0, 0, 0, 1, 1, 0];
}
defineProperties(GroundTinGeometry.prototype, {
rectangle : {
get : function() {
if (!defined(this._rectangle)) {
this._rectangle = computeRectangle(this._positions, this._ellipsoid);
}
return this._rectangle;
}
},
textureCoordinateRotationPoints : {
get : function() {
if (!defined(this._textureCoordinateRotationPoints)) {
this._textureCoordinateRotationPoints = textureCoordinateRotationPoints(this);
}
return this._textureCoordinateRotationPoints;
}
}
});
return GroundTinGeometry;
});
3. Context. Why do you need to do this? We might know a better way to accomplish your goal.
4. The Cesium version you’re using, your operating system and browser.
Cesium 1.53