Skip to content

Commit

Permalink
depth work
Browse files Browse the repository at this point in the history
  • Loading branch information
mpulkki-mapbox committed Jan 28, 2020
1 parent 27c4014 commit 4c18404
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 196 deletions.
7 changes: 4 additions & 3 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {SymbolLayoutArray,
SymbolOpacityArray,
CollisionBoxLayoutArray,
CollisionCircleLayoutArray,
StructArrayLayout4i8,
CollisionVertexArray,
PlacedSymbolArray,
SymbolInstanceArray,
Expand Down Expand Up @@ -317,7 +318,7 @@ class SymbolBucket implements Bucket {
sortedAngle: number;
featureSortOrder: Array<number>;

collisionCircleArrayTemp: CollisionCircleLayoutArrayTemp;
collisionCircleArrayTemp: StructArrayLayout4i8;

text: SymbolBuffers;
icon: SymbolBuffers;
Expand Down Expand Up @@ -348,7 +349,7 @@ class SymbolBucket implements Bucket {
this.hasRTLText = false;
this.sortKeyRanges = [];

this.collisionCircleArrayTemp = new CollisionCircleLayoutArray();
this.collisionCircleArrayTemp = new StructArrayLayout4i8();

const layer = this.layers[0];
const unevaluatedLayoutValues = layer._unevaluatedLayout._values;
Expand Down Expand Up @@ -745,7 +746,7 @@ class SymbolBucket implements Bucket {
const y1 = box.y1;
const x2 = box.x2;
const y2 = box.y2;
console.log(x1 + " " + y1 + " " + x2 + " " + y2);

// If the radius > 0, this collision box is actually a circle
// The data we add to the buffers is exactly the same, but we'll render with a different shader.
const isCircle = box.radius > 0;
Expand Down
237 changes: 66 additions & 171 deletions src/render/draw_collision_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,13 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache,
layer.indexBuffer2 = context.createIndexBuffer(array, false);
}

// Gather collision circle quads and render them in batches
let batchQuadIdx = 0;
// We need to know the projection matrix that was used for projecting collision circles to the screen
// This might vary between buckets as the symbol placement is a continous process. For improved rendering
// performance circles with same projection matrix are batched together
//const tilesPerMatrix = {};

// Render circle arrays grouped by projection matrices. Blue circles and collided red circles
// will be rendered in separate batches
const quadProperties = new Float32Array(maxQuadsPerDrawCall * 4);

for (let i = 0; i < coords.length; i++) {
Expand All @@ -109,33 +114,51 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache,
if (!arr.length)
continue;

let posMatrix = coord.posMatrix;
if (translate[0] !== 0 || translate[1] !== 0) {
posMatrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor);
}

// Create a transformation matrix that will transform points from screen space that was used
// during placement logic to the current screen space
const batchInvTransform = mat4.multiply([], bucket.invProjMatCircles, painter.transform.glCoordMatrix);
const batchTransform = posMatrix;// painter.transform.projMatrix.slice();

//batchTransform[12] = batchTransform[13] = 0.0;

//mat4.multiply(batchProjMatrix, painter.transform.projMatrix, tilesPerMatrix[key].matrix);
//mat4.multiply(batchProjMatrix, batchProjMatrix, painter.transform.glCoordMatrix);

//mat4.multiply(batchProjMatrix, painter.transform.projMatrix, painter.transform.invProjMatrix);
//mat4.multiply(batchProjMatrix, batchProjMatrix, painter.transform.glCoordMatrix);

//mat4.multiply(batchProjMatrix, painter.transform.invProjMatrix, painter.transform.glCoordMatrix);
//mat4.multiply(batchProjMatrix, painter.transform.projMatrix, batchProjMatrix);

let batchQuadIdx = 0;
let quadOffset = 0;

while (quadOffset < arr.length) {
const quadsLeft = arr.length - quadOffset;
const quadSpaceInBatch = maxQuadsPerDrawCall - batchQuadIdx;
const batchSize = Math.min(quadsLeft, quadSpaceInBatch);

// Copy collision circles from the bucket array
for (let qIdx = quadOffset; qIdx < quadOffset + batchSize; qIdx++) {
quadProperties[batchQuadIdx * 4 + 0] = arr.int16[qIdx * 6 + 0]; // width
quadProperties[batchQuadIdx * 4 + 1] = arr.int16[qIdx * 6 + 1]; // height
quadProperties[batchQuadIdx * 4 + 2] = arr.int16[qIdx * 6 + 2]; // depth
quadProperties[batchQuadIdx * 4 + 3] = arr.int16[qIdx * 6 + 3]; // radius
quadProperties[batchQuadIdx * 4 + 0] = arr.int16[qIdx * 4 + 0]; // width
quadProperties[batchQuadIdx * 4 + 1] = arr.int16[qIdx * 4 + 1]; // height
quadProperties[batchQuadIdx * 4 + 2] = arr.int16[qIdx * 4 + 2]; // radius
quadProperties[batchQuadIdx * 4 + 3] = arr.int16[qIdx * 4 + 3]; // collisionFlag
batchQuadIdx++;
}

quadOffset += batchSize;

if (batchQuadIdx === maxQuadsPerDrawCall) {
// TODO
const prevInvPosMatrix = coord.posMatrix;
const posMatrix = coord.posMatrix;

// TODO: only quad uniforms should be uploaded
const uniforms = collisionUniformValuesTemp(
painter.transform.glCoordMatrix,
prevInvPosMatrix,
posMatrix,
batchTransform,
batchInvTransform,
quadProperties,
painter.transform);

Expand All @@ -162,168 +185,40 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache,
batchQuadIdx = 0;
}
}
}

// Render the leftover batch
if (batchQuadIdx) {
// TODO
const prevInvPosMatrix = new Float32Array(16);
const posMatrix = new Float32Array(16);

// TODO: only quad uniforms should be uploaded
const uniforms = collisionUniformValuesTemp(
painter.transform.glCoordMatrix,
prevInvPosMatrix,
posMatrix,
quadProperties,
painter.transform);

// Upload quads packed in uniform vector
program2.draw(
context,
gl.TRIANGLES,
DepthMode.disabled,
StencilMode.disabled,
painter.colorModeForRenderPass(),
CullFaceMode.disabled,
uniforms,
layer.id,
layer.vertexBuffer2, // layoutVertexBuffer
layer.indexBuffer2, // indexbuffer,
SegmentVector.simpleSegment(0, 0, batchQuadIdx * 4, batchQuadIdx * 2),
null,
painter.transform.zoom,
null,
null, // vertexBuffer
null // vertexBuffer
);
// Render the leftover batch
if (batchQuadIdx) {
// TODO: only quad uniforms should be uploaded
const uniforms = collisionUniformValuesTemp(
batchTransform,
batchInvTransform,
quadProperties,
painter.transform);

// Upload quads packed in uniform vector
program2.draw(
context,
gl.TRIANGLES,
DepthMode.disabled,
StencilMode.disabled,
painter.colorModeForRenderPass(),
CullFaceMode.disabled,
uniforms,
layer.id,
layer.vertexBuffer2, // layoutVertexBuffer
layer.indexBuffer2, // indexbuffer,
SegmentVector.simpleSegment(0, 0, batchQuadIdx * 4, batchQuadIdx * 2),
null,
painter.transform.zoom,
null,
null, // vertexBuffer
null // vertexBuffer
);
}
}

// // Gather collision circles of tiles and render them in batches
// const batchVertices = new StructArrayLayout2i4i12();
// batchVertices.resize(maxVerticesPerBatch);
// batchVertices._trim();

// const appendVertex = (idx, x, y, z, w, c) => {
// batchVertices.int16[idx * 6 + 0] = x; // anchor center
// batchVertices.int16[idx * 6 + 1] = y; // anchor center
// batchVertices.int16[idx * 6 + 2] = z; // radius
// batchVertices.int16[idx * 6 + 3] = w; // radius
// batchVertices.int16[idx * 6 + 4] = c; // collision
// batchVertices.int16[idx * 6 + 5] = 0; // reserved
// }

// for (let i = 0; i < coords.length; i++) {
// const coord = coords[i];
// const tile = sourceCache.getTile(coord);
// const bucket: ?SymbolBucket = (tile.getBucket(layer): any);
// if (!bucket) continue;

// const arr = bucket.collisionCircleArrayTemp;

// if (!arr.length)
// continue;

// // Collision circle rendering is a little more complex now that they're stored in screen coordinates.
// // Screen space positions of previous frames can be reused by transforming them first to tile space and
// // then to the new clip space. Depth information of vertices is not preserved during circle generation
// // so it has to be reconstructed in vertex shader
// let posMatrix = coord.posMatrix;
// if (translate[0] !== 0 || translate[1] !== 0) {
// posMatrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor);
// }

// let prevInvPosMatrix = posMatrix;

// if ('posMatrixCircles' in bucket) {
// prevInvPosMatrix = mat4.invert([], bucket['posMatrixCircles']);
// } else {
// prevInvPosMatrix = mat4.invert([], posMatrix);
// }

// const uniforms = collisionUniformValuesTemp(painter.transform.glCoordMatrix, prevInvPosMatrix,
// posMatrix, painter.transform);

// // Upload and render quads in batches
// let batchVertexIdx = 0;
// let vertexOffset = 0;

// while (vertexOffset < arr.length) {
// const verticesLeft = arr.length - vertexOffset;
// const vertexSpaceLeftInBatch = maxVerticesPerBatch - batchVertexIdx;
// const batchSize = Math.min(verticesLeft, vertexSpaceLeftInBatch);

// for (let vIdx = vertexOffset; vIdx < vertexOffset + batchSize; vIdx+=4) {
// const r = arr[vIdx + 2];
// const collision = arr[vIdx + 3];
// appendVertex(batchVertexIdx + 0, arr[vIdx + 0], arr[vIdx + 1], -r, -r, collision);
// appendVertex(batchVertexIdx + 1, arr[vIdx + 0], arr[vIdx + 1], -r, r, collision);
// appendVertex(batchVertexIdx + 2, arr[vIdx + 0], arr[vIdx + 1], r, r, collision);
// appendVertex(batchVertexIdx + 3, arr[vIdx + 0], arr[vIdx + 1], r, -r, collision);

// batchVertexIdx += 4;
// }

// vertexOffset += batchSize;

// // TODO: Proper buffer orphaning. This might currently cause CPU-GPU sync!
// if (batchVertexIdx == maxVerticesPerBatch) {
// // Render the batch
// layer.vertexBuffer2.updateData(batchVertices, 0);

// program2.draw(
// context,
// gl.TRIANGLES,
// DepthMode.disabled,
// StencilMode.disabled,
// painter.colorModeForRenderPass(),
// CullFaceMode.disabled,
// uniforms,
// layer.id,
// layer.vertexBuffer2, // layoutVertexBuffer
// layer.indexBuffer2, // indexbuffer,
// SegmentVector.simpleSegment(0, 0, batchVertexIdx, batchVertexIdx / 2),
// null,
// painter.transform.zoom,
// null,
// null, // vertexBuffer
// null // vertexBuffer
// );

// batchVertexIdx = 0;
// }
// }

// // Render the leftover branch
// if (batchVertexIdx) {
// // Render the batch
// layer.vertexBuffer2.updateData(batchVertices, 0);

// program2.draw(
// context,
// gl.TRIANGLES,
// DepthMode.disabled,
// StencilMode.disabled,
// painter.colorModeForRenderPass(),
// CullFaceMode.disabled,
// uniforms,
// layer.id,
// layer.vertexBuffer2, // layoutVertexBuffer
// layer.indexBuffer2, // indexbuffer,
// SegmentVector.simpleSegment(0, 0, batchVertexIdx, batchVertexIdx / 2),
// null,
// painter.transform.zoom,
// null,
// null, // vertexBuffer
// null // vertexBuffer
// );

// batchVertexIdx = 0;
// }
// }
}

function drawCollisionDebug(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array<OverscaledTileID>, translate: [number, number], translateAnchor: 'map' | 'viewport', isText: boolean) {
drawCollisionDebugGeometry(painter, sourceCache, layer, coords, false, translate, translateAnchor, isText);
drawCollisionDebugGeometry(painter, sourceCache, layer, coords, true, translate, translateAnchor, isText);
//drawCollisionDebugGeometry(painter, sourceCache, layer, coords, true, translate, translateAnchor, isText);
}
12 changes: 4 additions & 8 deletions src/render/program/collision_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ export type CollisionUniformsType = {|

export type CollisionUniformsTypeTemp = {|
'u_matrix': UniformMatrix4f,
'u_invMatrix': UniformMatrix4f,
'u_quads': Uniform4fv,
'u_camera_to_center_distance': Uniform1f,
'u_toWorld': UniformMatrix4f,
'u_fromWorld': UniformMatrix4f,
'u_viewport_size': Uniform2f
|};

Expand All @@ -40,10 +39,9 @@ const collisionUniforms = (context: Context, locations: UniformLocations): Colli

const collisionUniformsTemp = (context: Context, locations: UniformLocations): CollisionUniformsType => ({
'u_matrix': new UniformMatrix4f(context, locations.u_matrix),
'u_invMatrix': new UniformMatrix4f(context, locations.u_invMatrix),
'u_quads': new Uniform4fv(context, locations.u_quads),
'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance),
'u_toWorld': new UniformMatrix4f(context, locations.u_toWorld),
'u_fromWorld': new UniformMatrix4f(context, locations.u_fromWorld),
'u_viewport_size': new Uniform2f(context, locations.u_viewport_size)
});

Expand All @@ -67,17 +65,15 @@ const collisionUniformValues = (

const collisionUniformValuesTemp = (
matrix: Float32Array,
toWorld: Float32Array,
fromWorld: Float32Array,
invMatrix: Float32Array,
quads: Float32Array,
transform: Transform
): UniformValues<CollisionUniformsTypeTemp> => {
return {
'u_matrix': matrix,
'u_invMatrix': invMatrix,
'u_quads': quads,
'u_camera_to_center_distance': transform.cameraToCenterDistance,
'u_toWorld': toWorld,
'u_fromWorld': fromWorld,
'u_viewport_size': [transform.width, transform.height]
};
};
Expand Down
Loading

0 comments on commit 4c18404

Please sign in to comment.