|
|
|
|
@ -59,11 +59,29 @@ const NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES;
|
|
|
|
|
|
|
|
|
|
const scratchTextureSize = new Cartesian2();
|
|
|
|
|
|
|
|
|
|
const attributeLocations = {
|
|
|
|
|
let attributeLocations;
|
|
|
|
|
|
|
|
|
|
const attributeLocationsBatched = {
|
|
|
|
|
positionHighAndScale: 0,
|
|
|
|
|
positionLowAndRotation: 1,
|
|
|
|
|
compressedAttribute0: 2, // pixel offset, translate, horizontal origin, vertical origin, show, direction, image coordinates (px)
|
|
|
|
|
compressedAttribute1: 3, // aligned axis, translucency by distance, image width
|
|
|
|
|
compressedAttribute2: 4, // image height, color, pick color, size in meters, valid aligned axis, 13 bits free
|
|
|
|
|
eyeOffset: 5, // 4 bytes free
|
|
|
|
|
scaleByDistance: 6,
|
|
|
|
|
pixelOffsetScaleByDistance: 7,
|
|
|
|
|
compressedAttribute3: 8,
|
|
|
|
|
textureCoordinateBoundsOrLabelTranslate: 9,
|
|
|
|
|
a_batchId: 10,
|
|
|
|
|
sdf: 11,
|
|
|
|
|
splitDirection: 12,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const attributeLocationsInstanced = {
|
|
|
|
|
direction: 0,
|
|
|
|
|
positionHighAndScale: 1,
|
|
|
|
|
positionLowAndRotation: 2, // texture offset in w
|
|
|
|
|
compressedAttribute0: 3,
|
|
|
|
|
positionLowAndRotation: 2,
|
|
|
|
|
compressedAttribute0: 3, // image lower-left coordinates (px) in w
|
|
|
|
|
compressedAttribute1: 4,
|
|
|
|
|
compressedAttribute2: 5,
|
|
|
|
|
eyeOffset: 6,
|
|
|
|
|
@ -662,7 +680,44 @@ BillboardCollection.prototype.get = function (index) {
|
|
|
|
|
return this._billboards[index];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function getIndexBuffer(context) {
|
|
|
|
|
let getIndexBuffer;
|
|
|
|
|
|
|
|
|
|
function getIndexBufferBatched(context) {
|
|
|
|
|
const sixteenK = 16 * 1024;
|
|
|
|
|
|
|
|
|
|
let indexBuffer = context.cache.billboardCollection_indexBufferBatched;
|
|
|
|
|
if (defined(indexBuffer)) {
|
|
|
|
|
return indexBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Subtract 6 because the last index is reserverd for primitive restart.
|
|
|
|
|
// https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.18
|
|
|
|
|
const length = sixteenK * 6 - 6;
|
|
|
|
|
const indices = new Uint16Array(length);
|
|
|
|
|
for (let i = 0, j = 0; i < length; i += 6, j += 4) {
|
|
|
|
|
indices[i] = j;
|
|
|
|
|
indices[i + 1] = j + 1;
|
|
|
|
|
indices[i + 2] = j + 2;
|
|
|
|
|
|
|
|
|
|
indices[i + 3] = j + 0;
|
|
|
|
|
indices[i + 4] = j + 2;
|
|
|
|
|
indices[i + 5] = j + 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PERFORMANCE_IDEA: Should we reference count billboard collections, and eventually delete this?
|
|
|
|
|
// Is this too much memory to allocate up front? Should we dynamically grow it?
|
|
|
|
|
indexBuffer = Buffer.createIndexBuffer({
|
|
|
|
|
context: context,
|
|
|
|
|
typedArray: indices,
|
|
|
|
|
usage: BufferUsage.STATIC_DRAW,
|
|
|
|
|
indexDatatype: IndexDatatype.UNSIGNED_SHORT,
|
|
|
|
|
});
|
|
|
|
|
indexBuffer.vertexArrayDestroyable = false;
|
|
|
|
|
context.cache.billboardCollection_indexBufferBatched = indexBuffer;
|
|
|
|
|
return indexBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getIndexBufferInstanced(context) {
|
|
|
|
|
let indexBuffer = context.cache.billboardCollection_indexBufferInstanced;
|
|
|
|
|
if (defined(indexBuffer)) {
|
|
|
|
|
return indexBuffer;
|
|
|
|
|
@ -712,7 +767,14 @@ BillboardCollection.prototype.computeNewBuffersUsage = function () {
|
|
|
|
|
return usageChanged;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function createVAF(context, numberOfBillboards, buffersUsage, batchTable, sdf) {
|
|
|
|
|
function createVAF(
|
|
|
|
|
context,
|
|
|
|
|
numberOfBillboards,
|
|
|
|
|
buffersUsage,
|
|
|
|
|
instanced,
|
|
|
|
|
batchTable,
|
|
|
|
|
sdf,
|
|
|
|
|
) {
|
|
|
|
|
const attributes = [
|
|
|
|
|
{
|
|
|
|
|
index: attributeLocations.positionHighAndScale,
|
|
|
|
|
@ -783,12 +845,14 @@ function createVAF(context, numberOfBillboards, buffersUsage, batchTable, sdf) {
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Instancing requires one non-instanced attribute.
|
|
|
|
|
attributes.push({
|
|
|
|
|
index: attributeLocations.direction,
|
|
|
|
|
componentsPerAttribute: 2,
|
|
|
|
|
componentDatatype: ComponentDatatype.FLOAT,
|
|
|
|
|
vertexBuffer: getVertexBufferInstanced(context),
|
|
|
|
|
});
|
|
|
|
|
if (instanced) {
|
|
|
|
|
attributes.push({
|
|
|
|
|
index: attributeLocations.direction,
|
|
|
|
|
componentsPerAttribute: 2,
|
|
|
|
|
componentDatatype: ComponentDatatype.FLOAT,
|
|
|
|
|
vertexBuffer: getVertexBufferInstanced(context),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (defined(batchTable)) {
|
|
|
|
|
attributes.push({
|
|
|
|
|
@ -809,8 +873,10 @@ function createVAF(context, numberOfBillboards, buffersUsage, batchTable, sdf) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When instancing is enabled, only one vertex is needed for each billboard.
|
|
|
|
|
const sizeInVertices = numberOfBillboards;
|
|
|
|
|
return new VertexArrayFacade(context, attributes, sizeInVertices, true);
|
|
|
|
|
const sizeInVertices = instanced
|
|
|
|
|
? numberOfBillboards
|
|
|
|
|
: 4 * numberOfBillboards;
|
|
|
|
|
return new VertexArrayFacade(context, attributes, sizeInVertices, instanced);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
@ -828,6 +894,7 @@ function writePositionScaleAndRotation(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const positionHighWriter =
|
|
|
|
|
vafWriters[attributeLocations.positionHighAndScale];
|
|
|
|
|
const positionLowWriter =
|
|
|
|
|
@ -859,9 +926,22 @@ function writePositionScaleAndRotation(
|
|
|
|
|
const high = writePositionScratch.high;
|
|
|
|
|
const low = writePositionScratch.low;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
positionHighWriter(i, high.x, high.y, high.z, scale);
|
|
|
|
|
positionLowWriter(i, low.x, low.y, low.z, rotation);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
positionHighWriter(i, high.x, high.y, high.z, scale);
|
|
|
|
|
positionLowWriter(i, low.x, low.y, low.z, rotation);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
positionHighWriter(i + 0, high.x, high.y, high.z, scale);
|
|
|
|
|
positionHighWriter(i + 1, high.x, high.y, high.z, scale);
|
|
|
|
|
positionHighWriter(i + 2, high.x, high.y, high.z, scale);
|
|
|
|
|
positionHighWriter(i + 3, high.x, high.y, high.z, scale);
|
|
|
|
|
|
|
|
|
|
positionLowWriter(i + 0, low.x, low.y, low.z, rotation);
|
|
|
|
|
positionLowWriter(i + 1, low.x, low.y, low.z, rotation);
|
|
|
|
|
positionLowWriter(i + 2, low.x, low.y, low.z, rotation);
|
|
|
|
|
positionLowWriter(i + 3, low.x, low.y, low.z, rotation);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const UPPER_BOUND = 32768.0; // 2^15
|
|
|
|
|
@ -876,6 +956,11 @@ const LEFT_SHIFT2 = 4.0;
|
|
|
|
|
|
|
|
|
|
const RIGHT_SHIFT8 = 1.0 / 256.0;
|
|
|
|
|
|
|
|
|
|
const LOWER_LEFT = 0.0;
|
|
|
|
|
const LOWER_RIGHT = 2.0;
|
|
|
|
|
const UPPER_RIGHT = 3.0;
|
|
|
|
|
const UPPER_LEFT = 1.0;
|
|
|
|
|
|
|
|
|
|
const scratchBoundingRectangle = new BoundingRectangle();
|
|
|
|
|
|
|
|
|
|
function writeCompressedAttrib0(
|
|
|
|
|
@ -884,6 +969,7 @@ function writeCompressedAttrib0(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.compressedAttribute0];
|
|
|
|
|
const pixelOffset = billboard.pixelOffset;
|
|
|
|
|
const pixelOffsetX = pixelOffset.x;
|
|
|
|
|
@ -921,17 +1007,17 @@ function writeCompressedAttrib0(
|
|
|
|
|
billboardCollection._allVerticalCenter &&
|
|
|
|
|
verticalOrigin === VerticalOrigin.CENTER;
|
|
|
|
|
|
|
|
|
|
// Compute offset (in pixels) from lower-left of the texture atlas.
|
|
|
|
|
let imageOffsetX = 0;
|
|
|
|
|
let imageOffsetY = 0;
|
|
|
|
|
// Compute image coordinates and size, in pixels. Coordinates are from lower-left of texture atlas.Z
|
|
|
|
|
let imageX = 0;
|
|
|
|
|
let imageY = 0;
|
|
|
|
|
let imageWidth = 0;
|
|
|
|
|
let imageHeight = 0;
|
|
|
|
|
if (billboard.ready) {
|
|
|
|
|
const imageRectangle = billboard.computeTextureCoordinates(
|
|
|
|
|
scratchBoundingRectangle,
|
|
|
|
|
);
|
|
|
|
|
const { width: atlasWidth, height: atlasHeight } =
|
|
|
|
|
billboardCollection.textureAtlas.texture;
|
|
|
|
|
imageOffsetX = imageRectangle.x * atlasWidth;
|
|
|
|
|
imageOffsetY = imageRectangle.y * atlasHeight;
|
|
|
|
|
billboard.computeImageCoordinates(scratchBoundingRectangle);
|
|
|
|
|
imageX = scratchBoundingRectangle.x;
|
|
|
|
|
imageY = scratchBoundingRectangle.y;
|
|
|
|
|
imageWidth = scratchBoundingRectangle.width;
|
|
|
|
|
imageHeight = scratchBoundingRectangle.height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let compressed0 =
|
|
|
|
|
@ -969,10 +1055,48 @@ function writeCompressedAttrib0(
|
|
|
|
|
compressed1 += upperTranslateY;
|
|
|
|
|
compressed2 += lowerTranslateY;
|
|
|
|
|
|
|
|
|
|
const compressedImageOffsetLL = imageOffsetX * LEFT_SHIFT16 + imageOffsetY;
|
|
|
|
|
// Compress image coordinates (px), integers 0-2^12 from lower-left of atlas. Avoid
|
|
|
|
|
// `AttributeCompression.compressTextureCoordinates` for lossless pixel values.
|
|
|
|
|
const compressedImageLL = imageX * LEFT_SHIFT12 + imageY;
|
|
|
|
|
const compressedImageLR = (imageX + imageWidth) * LEFT_SHIFT12 + imageY;
|
|
|
|
|
const compressedImageUR =
|
|
|
|
|
(imageX + imageWidth) * LEFT_SHIFT12 + imageY + imageHeight;
|
|
|
|
|
const compressedImageUL = imageX * LEFT_SHIFT12 + imageY + imageHeight;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1, compressed2, compressedImageOffsetLL);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1, compressed2, compressedImageLL);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(
|
|
|
|
|
i + 0,
|
|
|
|
|
compressed0 + LOWER_LEFT,
|
|
|
|
|
compressed1,
|
|
|
|
|
compressed2,
|
|
|
|
|
compressedImageLL,
|
|
|
|
|
);
|
|
|
|
|
writer(
|
|
|
|
|
i + 1,
|
|
|
|
|
compressed0 + LOWER_RIGHT,
|
|
|
|
|
compressed1,
|
|
|
|
|
compressed2,
|
|
|
|
|
compressedImageLR,
|
|
|
|
|
);
|
|
|
|
|
writer(
|
|
|
|
|
i + 2,
|
|
|
|
|
compressed0 + UPPER_RIGHT,
|
|
|
|
|
compressed1,
|
|
|
|
|
compressed2,
|
|
|
|
|
compressedImageUR,
|
|
|
|
|
);
|
|
|
|
|
writer(
|
|
|
|
|
i + 3,
|
|
|
|
|
compressed0 + UPPER_LEFT,
|
|
|
|
|
compressed1,
|
|
|
|
|
compressed2,
|
|
|
|
|
compressedImageUL,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeCompressedAttrib1(
|
|
|
|
|
@ -981,6 +1105,7 @@ function writeCompressedAttrib1(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.compressedAttribute1];
|
|
|
|
|
const alignedAxis = billboard.alignedAxis;
|
|
|
|
|
if (!Cartesian3.equals(alignedAxis, Cartesian3.ZERO)) {
|
|
|
|
|
@ -1030,8 +1155,16 @@ function writeCompressedAttrib1(
|
|
|
|
|
farValue = farValue === 1.0 ? 255.0 : (farValue * 255.0) | 0;
|
|
|
|
|
compressed1 = compressed1 * LEFT_SHIFT8 + farValue;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1, near, far);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1, near, far);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, compressed0, compressed1, near, far);
|
|
|
|
|
writer(i + 1, compressed0, compressed1, near, far);
|
|
|
|
|
writer(i + 2, compressed0, compressed1, near, far);
|
|
|
|
|
writer(i + 3, compressed0, compressed1, near, far);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeCompressedAttrib2(
|
|
|
|
|
@ -1040,6 +1173,7 @@ function writeCompressedAttrib2(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.compressedAttribute2];
|
|
|
|
|
const color = billboard.color;
|
|
|
|
|
const pickColor = !defined(billboardCollection._batchTable)
|
|
|
|
|
@ -1079,8 +1213,16 @@ function writeCompressedAttrib2(
|
|
|
|
|
Color.floatToByte(pickColor.alpha) * LEFT_SHIFT8;
|
|
|
|
|
compressed2 += sizeInMeters * 2.0 + validAlignedAxis;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1, compressed2, compressed3);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1, compressed2, compressed3);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, compressed0, compressed1, compressed2, compressed3);
|
|
|
|
|
writer(i + 1, compressed0, compressed1, compressed2, compressed3);
|
|
|
|
|
writer(i + 2, compressed0, compressed1, compressed2, compressed3);
|
|
|
|
|
writer(i + 3, compressed0, compressed1, compressed2, compressed3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeEyeOffset(
|
|
|
|
|
@ -1089,6 +1231,7 @@ function writeEyeOffset(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.eyeOffset];
|
|
|
|
|
const eyeOffset = billboard.eyeOffset;
|
|
|
|
|
|
|
|
|
|
@ -1104,8 +1247,16 @@ function writeEyeOffset(
|
|
|
|
|
Math.abs(eyeOffsetZ),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0);
|
|
|
|
|
writer(i + 1, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0);
|
|
|
|
|
writer(i + 2, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0);
|
|
|
|
|
writer(i + 3, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeScaleByDistance(
|
|
|
|
|
@ -1114,6 +1265,7 @@ function writeScaleByDistance(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.scaleByDistance];
|
|
|
|
|
let near = 0.0;
|
|
|
|
|
let nearValue = 1.0;
|
|
|
|
|
@ -1134,8 +1286,16 @@ function writeScaleByDistance(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, near, nearValue, far, farValue);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, near, nearValue, far, farValue);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, near, nearValue, far, farValue);
|
|
|
|
|
writer(i + 1, near, nearValue, far, farValue);
|
|
|
|
|
writer(i + 2, near, nearValue, far, farValue);
|
|
|
|
|
writer(i + 3, near, nearValue, far, farValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writePixelOffsetScaleByDistance(
|
|
|
|
|
@ -1144,6 +1304,7 @@ function writePixelOffsetScaleByDistance(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.pixelOffsetScaleByDistance];
|
|
|
|
|
let near = 0.0;
|
|
|
|
|
let nearValue = 1.0;
|
|
|
|
|
@ -1164,8 +1325,16 @@ function writePixelOffsetScaleByDistance(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, near, nearValue, far, farValue);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, near, nearValue, far, farValue);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, near, nearValue, far, farValue);
|
|
|
|
|
writer(i + 1, near, nearValue, far, farValue);
|
|
|
|
|
writer(i + 2, near, nearValue, far, farValue);
|
|
|
|
|
writer(i + 3, near, nearValue, far, farValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeCompressedAttribute3(
|
|
|
|
|
@ -1174,6 +1343,7 @@ function writeCompressedAttribute3(
|
|
|
|
|
vafWriters,
|
|
|
|
|
billboard,
|
|
|
|
|
) {
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.compressedAttribute3];
|
|
|
|
|
let near = 0.0;
|
|
|
|
|
let far = Number.MAX_VALUE;
|
|
|
|
|
@ -1217,8 +1387,16 @@ function writeCompressedAttribute3(
|
|
|
|
|
const h = Math.floor(CesiumMath.clamp(imageHeight, 0.0, LEFT_SHIFT12));
|
|
|
|
|
const dimensions = w * LEFT_SHIFT12 + h;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, near, far, disableDepthTestDistance, dimensions);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, near, far, disableDepthTestDistance, dimensions);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, near, far, disableDepthTestDistance, dimensions);
|
|
|
|
|
writer(i + 1, near, far, disableDepthTestDistance, dimensions);
|
|
|
|
|
writer(i + 2, near, far, disableDepthTestDistance, dimensions);
|
|
|
|
|
writer(i + 3, near, far, disableDepthTestDistance, dimensions);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeTextureCoordinateBoundsOrLabelTranslate(
|
|
|
|
|
@ -1250,9 +1428,16 @@ function writeTextureCoordinateBoundsOrLabelTranslate(
|
|
|
|
|
translateX = billboard._labelTranslate.x;
|
|
|
|
|
translateY = billboard._labelTranslate.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, translateX, translateY, 0.0, 0.0);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, translateX, translateY, 0.0, 0.0);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, translateX, translateY, 0.0, 0.0);
|
|
|
|
|
writer(i + 1, translateX, translateY, 0.0, 0.0);
|
|
|
|
|
writer(i + 2, translateX, translateY, 0.0, 0.0);
|
|
|
|
|
writer(i + 3, translateX, translateY, 0.0, 0.0);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1274,8 +1459,16 @@ function writeTextureCoordinateBoundsOrLabelTranslate(
|
|
|
|
|
const maxX = minX + width;
|
|
|
|
|
const maxY = minY + height;
|
|
|
|
|
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, minX, minY, maxX, maxY);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, minX, minY, maxX, maxY);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, minX, minY, maxX, maxY);
|
|
|
|
|
writer(i + 1, minX, minY, maxX, maxY);
|
|
|
|
|
writer(i + 2, minX, minY, maxX, maxY);
|
|
|
|
|
writer(i + 3, minX, minY, maxX, maxY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeBatchId(billboardCollection, frameState, vafWriters, billboard) {
|
|
|
|
|
@ -1286,8 +1479,17 @@ function writeBatchId(billboardCollection, frameState, vafWriters, billboard) {
|
|
|
|
|
const writer = vafWriters[attributeLocations.a_batchId];
|
|
|
|
|
const id = billboard._batchIndex;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, id);
|
|
|
|
|
let i;
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, id);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, id);
|
|
|
|
|
writer(i + 1, id);
|
|
|
|
|
writer(i + 2, id);
|
|
|
|
|
writer(i + 3, id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeSDF(billboardCollection, frameState, vafWriters, billboard) {
|
|
|
|
|
@ -1295,6 +1497,7 @@ function writeSDF(billboardCollection, frameState, vafWriters, billboard) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let i;
|
|
|
|
|
const writer = vafWriters[attributeLocations.sdf];
|
|
|
|
|
|
|
|
|
|
const outlineColor = billboard.outlineColor;
|
|
|
|
|
@ -1311,8 +1514,16 @@ function writeSDF(billboardCollection, frameState, vafWriters, billboard) {
|
|
|
|
|
Color.floatToByte(outlineColor.alpha) * LEFT_SHIFT16 +
|
|
|
|
|
Color.floatToByte(outlineDistance) * LEFT_SHIFT8;
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1);
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, compressed0, compressed1);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, compressed0 + LOWER_LEFT, compressed1);
|
|
|
|
|
writer(i + 1, compressed0 + LOWER_RIGHT, compressed1);
|
|
|
|
|
writer(i + 2, compressed0 + UPPER_RIGHT, compressed1);
|
|
|
|
|
writer(i + 3, compressed0 + UPPER_LEFT, compressed1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeSplitDirection(
|
|
|
|
|
@ -1329,8 +1540,17 @@ function writeSplitDirection(
|
|
|
|
|
direction = split;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const i = billboard._index;
|
|
|
|
|
writer(i, direction);
|
|
|
|
|
let i;
|
|
|
|
|
if (billboardCollection._instanced) {
|
|
|
|
|
i = billboard._index;
|
|
|
|
|
writer(i, direction);
|
|
|
|
|
} else {
|
|
|
|
|
i = billboard._index * 4;
|
|
|
|
|
writer(i + 0, direction);
|
|
|
|
|
writer(i + 1, direction);
|
|
|
|
|
writer(i + 2, direction);
|
|
|
|
|
writer(i + 3, direction);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeBillboard(
|
|
|
|
|
@ -1542,6 +1762,13 @@ BillboardCollection.prototype.update = function (frameState) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const context = frameState.context;
|
|
|
|
|
this._instanced = context.instancedArrays;
|
|
|
|
|
attributeLocations = this._instanced
|
|
|
|
|
? attributeLocationsInstanced
|
|
|
|
|
: attributeLocationsBatched;
|
|
|
|
|
getIndexBuffer = this._instanced
|
|
|
|
|
? getIndexBufferInstanced
|
|
|
|
|
: getIndexBufferBatched;
|
|
|
|
|
|
|
|
|
|
let billboards = this._billboards;
|
|
|
|
|
let billboardsLength = billboards.length;
|
|
|
|
|
@ -1614,6 +1841,7 @@ BillboardCollection.prototype.update = function (frameState) {
|
|
|
|
|
context,
|
|
|
|
|
billboardsLength,
|
|
|
|
|
this._buffersUsage,
|
|
|
|
|
this._instanced,
|
|
|
|
|
this._batchTable,
|
|
|
|
|
this._sdf,
|
|
|
|
|
);
|
|
|
|
|
@ -1653,7 +1881,9 @@ BillboardCollection.prototype.update = function (frameState) {
|
|
|
|
|
properties[SHOW_INDEX]
|
|
|
|
|
) {
|
|
|
|
|
writers.push(writeCompressedAttrib0);
|
|
|
|
|
writers.push(writeEyeOffset);
|
|
|
|
|
if (this._instanced) {
|
|
|
|
|
writers.push(writeEyeOffset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
@ -1730,7 +1960,11 @@ BillboardCollection.prototype.update = function (frameState) {
|
|
|
|
|
writers[o](this, frameState, vafWriters, bb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._vaf.subCommit(bb._index, 1);
|
|
|
|
|
if (this._instanced) {
|
|
|
|
|
this._vaf.subCommit(bb._index, 1);
|
|
|
|
|
} else {
|
|
|
|
|
this._vaf.subCommit(bb._index * 4, 4);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this._vaf.endSubCommits();
|
|
|
|
|
}
|
|
|
|
|
@ -1864,6 +2098,9 @@ BillboardCollection.prototype.update = function (frameState) {
|
|
|
|
|
defines: vertDefines,
|
|
|
|
|
sources: [vsSource],
|
|
|
|
|
});
|
|
|
|
|
if (this._instanced) {
|
|
|
|
|
vs.defines.push("INSTANCED");
|
|
|
|
|
}
|
|
|
|
|
if (this._shaderRotation) {
|
|
|
|
|
vs.defines.push("ROTATION");
|
|
|
|
|
}
|
|
|
|
|
@ -2063,8 +2300,10 @@ BillboardCollection.prototype.update = function (frameState) {
|
|
|
|
|
command.debugShowBoundingVolume = this.debugShowBoundingVolume;
|
|
|
|
|
command.pickId = pickId;
|
|
|
|
|
|
|
|
|
|
command.count = 6;
|
|
|
|
|
command.instanceCount = billboardsLength;
|
|
|
|
|
if (this._instanced) {
|
|
|
|
|
command.count = 6;
|
|
|
|
|
command.instanceCount = billboardsLength;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
commandList.push(command);
|
|
|
|
|
}
|
|
|
|
|
|