@tangram.gl/tangram-renderer 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -2
- package/dist/core.js +36923 -0
- package/dist/core.js.map +6 -0
- package/dist/index.js +32 -0
- package/dist/loaders-gl-worker.js +82 -0
- package/dist/loaders-gl-worker.js.map +6 -0
- package/dist/map-logic.js +2 -0
- package/dist/map-logic.js.map +6 -0
- package/dist/projected-basemaps-worker.js +3 -0
- package/dist/projected-basemaps-worker.js.map +6 -0
- package/dist/shader-modules.js +141 -0
- package/dist/shader-modules.js.map +6 -0
- package/dist/style-schema.js +126 -0
- package/dist/style-schema.js.map +6 -0
- package/dist/tangram-style.schema.json +882 -0
- package/dist/tangram.debug.mjs +37139 -0
- package/dist/tangram.debug.mjs.map +6 -0
- package/dist/tangram.min.mjs +4950 -0
- package/dist/types/builders/earcut.d.ts +15 -0
- package/dist/types/core.d.ts +29 -0
- package/dist/types/gl/constants.d.ts +2 -0
- package/dist/types/gl/globe_mesh.d.ts +48 -0
- package/dist/types/gl/glsl.d.ts +17 -0
- package/dist/types/gl/vertex-constants.d.ts +4 -0
- package/dist/types/gl/vertex-types.d.ts +34 -0
- package/dist/types/gl/vertex_data.d.ts +32 -0
- package/dist/types/gl/vertex_elements.d.ts +8 -0
- package/dist/types/gl/vertex_layout.d.ts +32 -0
- package/dist/types/glsl.d.ts +14 -0
- package/dist/types/gpu/luma_device_renderer.d.ts +66 -0
- package/dist/types/gpu/resource_lifecycle.d.ts +4 -0
- package/dist/types/gpu/tangram_gpu_backend.d.ts +151 -0
- package/dist/types/index.d.ts +155 -0
- package/dist/types/lights/light-definitions.d.ts +121 -0
- package/dist/types/map-logic/draped-terrain-bounds.d.ts +41 -0
- package/dist/types/map-logic/globe-terrain-preparation.d.ts +85 -0
- package/dist/types/map-logic/globe-terrain.d.ts +54 -0
- package/dist/types/map-logic/index.d.ts +33 -0
- package/dist/types/map-logic/label-identity.d.ts +22 -0
- package/dist/types/map-logic/label-placement.d.ts +32 -0
- package/dist/types/map-logic/screen-bounds.d.ts +15 -0
- package/dist/types/map-logic/terrain-data.d.ts +55 -0
- package/dist/types/map-logic/terrain-error.d.ts +51 -0
- package/dist/types/map-logic/terrain-ground-topology.d.ts +26 -0
- package/dist/types/map-logic/terrain-height-field.d.ts +59 -0
- package/dist/types/map-logic/terrain-navigation.d.ts +27 -0
- package/dist/types/map-logic/terrain-neighborhood.d.ts +5 -0
- package/dist/types/map-logic/terrain-query.d.ts +33 -0
- package/dist/types/map-logic/terrain-resource-budget.d.ts +51 -0
- package/dist/types/map-logic/terrain-transition-topology.d.ts +23 -0
- package/dist/types/map-logic/tile-build-queue.d.ts +51 -0
- package/dist/types/map-logic/tile-cache-policy.d.ts +46 -0
- package/dist/types/map-logic/tile-residency.d.ts +17 -0
- package/dist/types/map-logic/triangle-query-index.d.ts +87 -0
- package/dist/types/procedures/js-yaml.d.ts +15 -0
- package/dist/types/procedures/mesh-projector.d.ts +107 -0
- package/dist/types/procedures/mvt-dependencies.d.ts +20 -0
- package/dist/types/procedures/projected-coordinate-transform.d.ts +27 -0
- package/dist/types/procedures/projection-batch-executor.d.ts +53 -0
- package/dist/types/procedures/scene-yaml-legacy.d.ts +6 -0
- package/dist/types/procedures/terrain-draping.d.ts +165 -0
- package/dist/types/procedures/terrain-globe.d.ts +6 -0
- package/dist/types/procedures/terrain-styled-topology.d.ts +34 -0
- package/dist/types/procedures/web-mercator-legacy.d.ts +4 -0
- package/dist/types/procedures/web-mercator-math.d.ts +4 -0
- package/dist/types/scene/globals.d.ts +11 -0
- package/dist/types/scene/ground_footprint.d.ts +16 -0
- package/dist/types/scene/host_frame.d.ts +54 -0
- package/dist/types/scene/projection_math.d.ts +52 -0
- package/dist/types/scene/scene-resource-types.d.ts +177 -0
- package/dist/types/scene/scene_bundle.d.ts +69 -0
- package/dist/types/scene/visibility_adapter.d.ts +106 -0
- package/dist/types/selection/draped-terrain-surface.d.ts +78 -0
- package/dist/types/selection/terrain_surface.d.ts +149 -0
- package/dist/types/shader-modules/globe-horizon.d.ts +15 -0
- package/dist/types/shader-modules/height-decode.d.ts +13 -0
- package/dist/types/shader-modules/hillshade.d.ts +13 -0
- package/dist/types/shader-modules/index.d.ts +6 -0
- package/dist/types/shader-modules/planar.d.ts +12 -0
- package/dist/types/shader-modules/sphere-map.d.ts +13 -0
- package/dist/types/shader-modules/triplanar.d.ts +15 -0
- package/dist/types/sources/decoded_tile_store.d.ts +95 -0
- package/dist/types/sources/tile_source_metadata.d.ts +32 -0
- package/dist/types/styles/text/fontfaceobserver.d.ts +10 -0
- package/dist/types/tile/tile_id.d.ts +37 -0
- package/dist/types/tile/tile_traversal_adapter.d.ts +63 -0
- package/dist/types/types.d.ts +293 -0
- package/dist/types/utils/geo.d.ts +57 -0
- package/dist/types/utils/hash.d.ts +1 -0
- package/dist/types/utils/log.d.ts +27 -0
- package/dist/types/utils/props.d.ts +6 -0
- package/dist/types/utils/subscribe.d.ts +10 -0
- package/dist/types/utils/thread.d.ts +6 -0
- package/dist/types/utils/urls.d.ts +26 -0
- package/dist/types/utils/utils.d.ts +26 -0
- package/dist/types/utils/version.d.ts +2 -0
- package/dist/types/utils/worker-types.d.ts +68 -0
- package/dist/types/utils/worker_broker.d.ts +3 -0
- package/package.json +103 -3
- package/src/builders/common.ts +41 -0
- package/src/builders/earcut.d.ts +15 -0
- package/src/builders/geometry-types.ts +60 -0
- package/src/builders/points.ts +115 -0
- package/src/builders/polygons.ts +225 -0
- package/src/builders/polylines.ts +682 -0
- package/src/builders/wireframe.ts +31 -0
- package/src/core.d.ts +29 -0
- package/src/core.ts +33 -0
- package/src/experimental/loaders-gl-worker.ts +19 -0
- package/src/experimental/projected-basemaps-worker.ts +13 -0
- package/src/experimental/projected-mesh-cache.ts +137 -0
- package/src/experimental/projected-mesh-domain.ts +110 -0
- package/src/experimental/projected-mesh-refinement.ts +193 -0
- package/src/experimental/projected-mesh.ts +399 -0
- package/src/experimental/projected-normal.ts +26 -0
- package/src/experimental/projected-symbol-mesh.ts +74 -0
- package/src/gl/constants.ts +18 -0
- package/src/gl/context.ts +103 -0
- package/src/gl/extensions.ts +30 -0
- package/src/gl/globe_mesh.ts +285 -0
- package/src/gl/glsl.ts +257 -0
- package/src/gl/mesh-types.ts +56 -0
- package/src/gl/render_state.ts +111 -0
- package/src/gl/shader_program.ts +1310 -0
- package/src/gl/texture.ts +814 -0
- package/src/gl/uniform_buffer.ts +340 -0
- package/src/gl/vao.ts +154 -0
- package/src/gl/vbo_mesh.ts +349 -0
- package/src/gl/vertex-constants.ts +19 -0
- package/src/gl/vertex-types.ts +35 -0
- package/src/gl/vertex_data.ts +126 -0
- package/src/gl/vertex_elements.ts +54 -0
- package/src/gl/vertex_layout.ts +241 -0
- package/src/glsl.d.ts +14 -0
- package/src/gpu/luma_device_renderer.ts +579 -0
- package/src/gpu/pixel_readback.ts +51 -0
- package/src/gpu/resource_lifecycle.ts +32 -0
- package/src/gpu/tangram_gpu_backend.ts +195 -0
- package/src/index.d.ts +155 -0
- package/src/index.ts +105 -0
- package/src/labels/collision-types.ts +94 -0
- package/src/labels/collision.ts +273 -0
- package/src/labels/collision_grid.ts +61 -0
- package/src/labels/intersect.ts +30 -0
- package/src/labels/label-types.ts +91 -0
- package/src/labels/label.ts +207 -0
- package/src/labels/label_line.ts +801 -0
- package/src/labels/label_point.ts +131 -0
- package/src/labels/main-pass-types.ts +73 -0
- package/src/labels/main_pass.ts +221 -0
- package/src/labels/point_anchor.ts +100 -0
- package/src/labels/point_placement.ts +150 -0
- package/src/labels/projected-pass.ts +259 -0
- package/src/labels/repeat_group.ts +72 -0
- package/src/lights/ambient_light.glsl +18 -0
- package/src/lights/directional_light.glsl +39 -0
- package/src/lights/geographic-lights.ts +21 -0
- package/src/lights/light-definitions.ts +285 -0
- package/src/lights/light.ts +590 -0
- package/src/lights/lighting-uniforms.ts +80 -0
- package/src/lights/lighting-wgsl.ts +116 -0
- package/src/lights/material.glsl +237 -0
- package/src/lights/material.ts +145 -0
- package/src/lights/native-falloff.ts +37 -0
- package/src/lights/point_light.glsl +96 -0
- package/src/lights/spot_light.glsl +111 -0
- package/src/map-logic/draped-terrain-bounds.ts +71 -0
- package/src/map-logic/globe-terrain-preparation.ts +217 -0
- package/src/map-logic/globe-terrain.ts +296 -0
- package/src/map-logic/index.ts +37 -0
- package/src/map-logic/label-identity.ts +36 -0
- package/src/map-logic/label-placement.ts +117 -0
- package/src/map-logic/screen-bounds.ts +34 -0
- package/src/map-logic/terrain-data.ts +107 -0
- package/src/map-logic/terrain-error.ts +134 -0
- package/src/map-logic/terrain-ground-topology.ts +164 -0
- package/src/map-logic/terrain-height-field.ts +254 -0
- package/src/map-logic/terrain-navigation.ts +50 -0
- package/src/map-logic/terrain-neighborhood.ts +43 -0
- package/src/map-logic/terrain-query.ts +51 -0
- package/src/map-logic/terrain-resource-budget.ts +124 -0
- package/src/map-logic/terrain-transition-topology.ts +164 -0
- package/src/map-logic/tile-build-queue.ts +110 -0
- package/src/map-logic/tile-cache-policy.ts +89 -0
- package/src/map-logic/tile-residency.ts +50 -0
- package/src/map-logic/triangle-query-index.ts +265 -0
- package/src/procedures/js-yaml.d.ts +15 -0
- package/src/procedures/mesh-projector.ts +191 -0
- package/src/procedures/mlt-loaders.ts +55 -0
- package/src/procedures/mvt-dependencies.d.ts +20 -0
- package/src/procedures/mvt-legacy.ts +150 -0
- package/src/procedures/mvt-loaders.ts +53 -0
- package/src/procedures/mvt-parser.ts +48 -0
- package/src/procedures/mvt-properties.ts +36 -0
- package/src/procedures/mvt-tile-provider.ts +72 -0
- package/src/procedures/pmtiles-loader.ts +75 -0
- package/src/procedures/projected-coordinate-transform.ts +79 -0
- package/src/procedures/projection-batch-executor.ts +140 -0
- package/src/procedures/scene-yaml-legacy.ts +16 -0
- package/src/procedures/scene-yaml-loaders.ts +10 -0
- package/src/procedures/terrain-draping.ts +713 -0
- package/src/procedures/terrain-globe.ts +32 -0
- package/src/procedures/terrain-styled-topology.ts +184 -0
- package/src/procedures/web-mercator-legacy.ts +24 -0
- package/src/procedures/web-mercator-math.ts +50 -0
- package/src/scene/camera.ts +298 -0
- package/src/scene/camera_base.ts +116 -0
- package/src/scene/classic_scene.ts +20 -0
- package/src/scene/external_camera.ts +101 -0
- package/src/scene/globals.ts +120 -0
- package/src/scene/ground_footprint.ts +139 -0
- package/src/scene/host_frame.ts +326 -0
- package/src/scene/projected_tile_lod.ts +125 -0
- package/src/scene/projection_math.ts +142 -0
- package/src/scene/projection_shaders.ts +183 -0
- package/src/scene/renderer.ts +516 -0
- package/src/scene/scene-resource-types.ts +174 -0
- package/src/scene/scene.ts +2378 -0
- package/src/scene/scene_bundle.ts +304 -0
- package/src/scene/scene_debug.ts +129 -0
- package/src/scene/scene_loader.ts +402 -0
- package/src/scene/scene_worker.ts +528 -0
- package/src/scene/view.ts +683 -0
- package/src/scene/visibility_adapter.ts +319 -0
- package/src/scene/worker_url.ts +15 -0
- package/src/selection/draped-terrain-surface.ts +377 -0
- package/src/selection/selection-types.ts +79 -0
- package/src/selection/selection.ts +542 -0
- package/src/selection/selection_fragment.glsl +18 -0
- package/src/selection/selection_globals.glsl +9 -0
- package/src/selection/selection_pixels.ts +59 -0
- package/src/selection/selection_vertex.glsl +15 -0
- package/src/selection/terrain_surface.ts +298 -0
- package/src/shader-modules/globe-horizon.ts +52 -0
- package/src/shader-modules/height-decode.ts +41 -0
- package/src/shader-modules/hillshade.ts +70 -0
- package/src/shader-modules/index.ts +10 -0
- package/src/shader-modules/planar.ts +24 -0
- package/src/shader-modules/sphere-map.ts +38 -0
- package/src/shader-modules/triplanar.ts +45 -0
- package/src/sources/aligned_tile_source.ts +122 -0
- package/src/sources/data_source.ts +655 -0
- package/src/sources/decoded_tile_store.ts +245 -0
- package/src/sources/geojson.ts +300 -0
- package/src/sources/mvt.ts +247 -0
- package/src/sources/raster.ts +341 -0
- package/src/sources/shared_tile_source_adapter.ts +117 -0
- package/src/sources/sources.ts +10 -0
- package/src/sources/tile_source_adapter.ts +84 -0
- package/src/sources/tile_source_metadata.ts +65 -0
- package/src/sources/tile_source_state.ts +112 -0
- package/src/sources/topojson.ts +90 -0
- package/src/styles/feature_annotations.ts +16 -0
- package/src/styles/filter.ts +190 -0
- package/src/styles/geometry-style-types.ts +209 -0
- package/src/styles/globe_visibility_wgsl.ts +22 -0
- package/src/styles/layer-types.ts +45 -0
- package/src/styles/layer.ts +586 -0
- package/src/styles/lines/dasharray.ts +49 -0
- package/src/styles/lines/lines.ts +707 -0
- package/src/styles/lines/lines_wgsl.ts +224 -0
- package/src/styles/points/point-runtime-types.ts +125 -0
- package/src/styles/points/points.ts +1079 -0
- package/src/styles/points/points_fragment.glsl +126 -0
- package/src/styles/points/points_vertex.glsl +230 -0
- package/src/styles/points/points_wgsl.ts +189 -0
- package/src/styles/polygons/polygons.ts +268 -0
- package/src/styles/polygons/polygons_fragment.glsl +173 -0
- package/src/styles/polygons/polygons_vertex.glsl +213 -0
- package/src/styles/polygons/polygons_wgsl.ts +127 -0
- package/src/styles/property-types.ts +125 -0
- package/src/styles/raster/raster.ts +33 -0
- package/src/styles/raster/raster_globals.glsl +46 -0
- package/src/styles/style-mixing-types.ts +101 -0
- package/src/styles/style-runtime-types.ts +220 -0
- package/src/styles/style-schema.ts +133 -0
- package/src/styles/style.ts +1033 -0
- package/src/styles/style_globals.glsl +69 -0
- package/src/styles/style_manager.ts +464 -0
- package/src/styles/style_parser.ts +620 -0
- package/src/styles/text/font_manager.ts +180 -0
- package/src/styles/text/fontfaceobserver.d.ts +10 -0
- package/src/styles/text/text-types.ts +220 -0
- package/src/styles/text/text.ts +378 -0
- package/src/styles/text/text_canvas.ts +773 -0
- package/src/styles/text/text_labels.ts +436 -0
- package/src/styles/text/text_segments.ts +142 -0
- package/src/styles/text/text_settings.ts +228 -0
- package/src/styles/text/text_wgsl.ts +159 -0
- package/src/styles/text/text_wrap.ts +194 -0
- package/src/tile/globe_tile_preload.ts +40 -0
- package/src/tile/tangram_tileset_2d.ts +108 -0
- package/src/tile/tile-build-types.ts +155 -0
- package/src/tile/tile.ts +807 -0
- package/src/tile/tile_id.ts +172 -0
- package/src/tile/tile_manager.ts +889 -0
- package/src/tile/tile_pyramid.ts +119 -0
- package/src/tile/tile_resource_cache.ts +91 -0
- package/src/tile/tile_traversal_adapter.ts +132 -0
- package/src/types.ts +332 -0
- package/src/utils/debounce.ts +17 -0
- package/src/utils/debug_settings.ts +43 -0
- package/src/utils/errors.ts +12 -0
- package/src/utils/functions.ts +95 -0
- package/src/utils/geo.ts +364 -0
- package/src/utils/hash.ts +14 -0
- package/src/utils/log.ts +108 -0
- package/src/utils/media_capture.ts +193 -0
- package/src/utils/merge.ts +44 -0
- package/src/utils/obb.ts +134 -0
- package/src/utils/props.ts +43 -0
- package/src/utils/slice.ts +14 -0
- package/src/utils/subscribe.ts +58 -0
- package/src/utils/task.ts +154 -0
- package/src/utils/thread.ts +26 -0
- package/src/utils/urls.ts +223 -0
- package/src/utils/utils.ts +310 -0
- package/src/utils/vector.ts +197 -0
- package/src/utils/version.ts +8 -0
- package/src/utils/worker-types.ts +79 -0
- package/src/utils/worker_broker.ts +523 -0
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
// Tangram
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) 2013-2016 Brett Camper and Mapzen
|
|
4
|
+
// Copyright (c) 2026 vis.gl contributors
|
|
5
|
+
|
|
6
|
+
// Geometry building functions
|
|
7
|
+
|
|
8
|
+
import type {GeometryLine, GeometryCoordinate, GeometryVertexData, PolylineStyle, PolylineVertexIndices, PolylineBuildContext} from './geometry-types';
|
|
9
|
+
import Vector from '../utils/vector';
|
|
10
|
+
import Geo from '../utils/geo';
|
|
11
|
+
import {outsideTile, isCoordOutsideTile} from './common';
|
|
12
|
+
|
|
13
|
+
const zero_vec2 = [0, 0];
|
|
14
|
+
|
|
15
|
+
// Build tessellated triangles for a polyline
|
|
16
|
+
const CAP_TYPE = {
|
|
17
|
+
butt: 0,
|
|
18
|
+
square: 1,
|
|
19
|
+
round: 2
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const JOIN_TYPE = {
|
|
23
|
+
miter: 0,
|
|
24
|
+
bevel: 1,
|
|
25
|
+
round: 2
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const DEFAULT_MITER_LIMIT = 3;
|
|
29
|
+
const MIN_FAN_WIDTH = 5; // Width of line in tile units to place 1 triangle per fan
|
|
30
|
+
const TEXCOORD_NORMALIZE = 65535; // Scaling factor for UV attribute values
|
|
31
|
+
|
|
32
|
+
// Scaling factor to add precision to line texture V coordinate packed as normalized short
|
|
33
|
+
const V_SCALE_ADJUST = Geo.tile_scale;
|
|
34
|
+
const zero_v = [0, 0], one_v = [1, 0], mid_v = [0.5, 0]; // reusable instances, updated with V coordinate
|
|
35
|
+
|
|
36
|
+
export function buildPolylines (
|
|
37
|
+
lines: GeometryLine[],
|
|
38
|
+
style: PolylineStyle,
|
|
39
|
+
vertex_data: GeometryVertexData,
|
|
40
|
+
vertex_template: number[],
|
|
41
|
+
vindex: PolylineVertexIndices,
|
|
42
|
+
closed_polygon: boolean | undefined,
|
|
43
|
+
remove_tile_edges: boolean | undefined,
|
|
44
|
+
tile_edge_tolerance: number): number {
|
|
45
|
+
|
|
46
|
+
var cap_type = style.cap ? CAP_TYPE[style.cap] : CAP_TYPE.butt;
|
|
47
|
+
var join_type = style.join ? JOIN_TYPE[style.join] : JOIN_TYPE.miter;
|
|
48
|
+
|
|
49
|
+
// Configure miter limit
|
|
50
|
+
if (join_type === JOIN_TYPE.miter) {
|
|
51
|
+
const miter_limit = style.miter_limit || DEFAULT_MITER_LIMIT; // default miter limit
|
|
52
|
+
var miter_len_sq: number | undefined = miter_limit * miter_limit;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Texture Variables
|
|
56
|
+
var v_scale;
|
|
57
|
+
if (vindex.a_texcoord) {
|
|
58
|
+
v_scale = 1 / (style.texcoord_width * V_SCALE_ADJUST); // scales line texture as a ratio of the line's width
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Values that are constant for each line and are passed to helper functions
|
|
62
|
+
var context: PolylineBuildContext = {
|
|
63
|
+
closed_polygon,
|
|
64
|
+
remove_tile_edges,
|
|
65
|
+
tile_edge_tolerance,
|
|
66
|
+
miter_len_sq,
|
|
67
|
+
join_type,
|
|
68
|
+
cap_type,
|
|
69
|
+
vertex_data,
|
|
70
|
+
vertex_template,
|
|
71
|
+
half_width: style.width / 2,
|
|
72
|
+
extrude_index: vindex.a_extrude,
|
|
73
|
+
offset_index: vindex.a_offset,
|
|
74
|
+
v_scale,
|
|
75
|
+
texcoord_index: vindex.a_texcoord,
|
|
76
|
+
texcoord_width: style.texcoord_width,
|
|
77
|
+
offset: style.offset,
|
|
78
|
+
projected_normals_index: vindex.a_projected_normals,
|
|
79
|
+
projected_widths_index: vindex.a_projected_widths,
|
|
80
|
+
geom_count: 0
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Process lines
|
|
84
|
+
for (let i = 0; i < lines.length; i++) {
|
|
85
|
+
buildPolyline(lines[i], context);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Process extra lines (which are created above if lines need to be mutated for easier processing)
|
|
89
|
+
if (context.extra_lines) {
|
|
90
|
+
for (let i = 0; i < context.extra_lines.length; i++) {
|
|
91
|
+
buildPolyline(context.extra_lines[i], context);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return context.geom_count;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function buildPolyline(line: GeometryLine, context: PolylineBuildContext): void {
|
|
99
|
+
// Skip if line is not valid
|
|
100
|
+
if (line.length < 2) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
var coordCurr: GeometryCoordinate, coordNext: GeometryCoordinate, normPrev: number[], normNext: number[];
|
|
105
|
+
var {join_type, cap_type, closed_polygon, remove_tile_edges, tile_edge_tolerance, v_scale, miter_len_sq} = context;
|
|
106
|
+
var has_texcoord = (context.texcoord_index != null);
|
|
107
|
+
var v = 0; // Texture v-coordinate
|
|
108
|
+
|
|
109
|
+
// Loop backwards through line to a tile boundary if found
|
|
110
|
+
// since you need to draw lines that are only partially inside the tile,
|
|
111
|
+
// so we start at the first index where it is safe to loop through to the last index within the tile
|
|
112
|
+
if (closed_polygon && join_type === JOIN_TYPE.miter) {
|
|
113
|
+
var boundaryIndex = getTileBoundaryIndex(line);
|
|
114
|
+
if (boundaryIndex !== 0) {
|
|
115
|
+
// create new line that is a cyclic permutation of the original
|
|
116
|
+
var permutedLine = permuteLine(line, boundaryIndex);
|
|
117
|
+
context.extra_lines = context.extra_lines || [];
|
|
118
|
+
context.extra_lines.push(permutedLine);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
var index_start = 0;
|
|
124
|
+
var index_end = line.length - 1;
|
|
125
|
+
var ignored_indices_count = 0;
|
|
126
|
+
|
|
127
|
+
// FIRST POINT
|
|
128
|
+
// loop through beginning points if duplicates
|
|
129
|
+
coordCurr = line[index_start];
|
|
130
|
+
coordNext = line[index_start + 1];
|
|
131
|
+
while (Vector.isEqual(coordCurr, coordNext)) {
|
|
132
|
+
index_start++;
|
|
133
|
+
coordCurr = coordNext;
|
|
134
|
+
coordNext = line[index_start + 1];
|
|
135
|
+
ignored_indices_count++;
|
|
136
|
+
if (index_start === line.length - 1) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// loop through ending points to check for duplicates
|
|
142
|
+
while (Vector.isEqual(line[index_end], line[index_end - 1])) {
|
|
143
|
+
index_end--;
|
|
144
|
+
ignored_indices_count++;
|
|
145
|
+
if (index_end === 0) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (line.length < 2 + ignored_indices_count) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
normNext = Vector.normalize(Vector.perp(coordCurr, coordNext));
|
|
155
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normNext, ...normNext];
|
|
156
|
+
|
|
157
|
+
// Skip tile boundary lines and append a new line if needed
|
|
158
|
+
if (remove_tile_edges && outsideTile(coordCurr, coordNext, tile_edge_tolerance)) {
|
|
159
|
+
var nonBoundarySegment = getNextNonBoundarySegment(line, index_start, tile_edge_tolerance);
|
|
160
|
+
if (nonBoundarySegment) {
|
|
161
|
+
context.extra_lines = context.extra_lines || [];
|
|
162
|
+
context.extra_lines.push(nonBoundarySegment);
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (closed_polygon){
|
|
168
|
+
// Begin the polygon with a join (connecting the first and last segments)
|
|
169
|
+
normPrev = Vector.normalize(Vector.perp(line[index_end - 1], coordCurr));
|
|
170
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normPrev, ...normNext];
|
|
171
|
+
startPolygon(coordCurr, normPrev, normNext, join_type, context);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// If line begins at edge, don't add a cap
|
|
175
|
+
if (!isCoordOutsideTile(coordCurr)) {
|
|
176
|
+
addCap(coordCurr, v, normNext, cap_type, true, context);
|
|
177
|
+
if (has_texcoord && cap_type !== CAP_TYPE.butt) {
|
|
178
|
+
v += 0.5 * v_scale! * context.texcoord_width;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Add first pair of points for the line strip
|
|
183
|
+
addVertex(coordCurr, normNext, normNext, 1, v, context, 1);
|
|
184
|
+
addVertex(coordCurr, normNext, normNext, 0, v, context, -1);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// INTERMEDIARY POINTS
|
|
188
|
+
if (has_texcoord) {
|
|
189
|
+
v += v_scale! * Vector.length(Vector.sub(coordNext, coordCurr));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (var i = index_start + 1; i < index_end; i++) {
|
|
193
|
+
var currIndex = i;
|
|
194
|
+
var nextIndex = i + 1;
|
|
195
|
+
coordCurr = line[currIndex];
|
|
196
|
+
coordNext = line[nextIndex];
|
|
197
|
+
|
|
198
|
+
// Skip redundant vertices
|
|
199
|
+
if (Vector.isEqual(coordCurr, coordNext)) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Remove tile boundaries
|
|
204
|
+
if (remove_tile_edges && outsideTile(coordCurr, coordNext, tile_edge_tolerance)) {
|
|
205
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normNext, ...normNext];
|
|
206
|
+
addVertex(coordCurr, normNext, normNext, 1, v, context, 1);
|
|
207
|
+
addVertex(coordCurr, normNext, normNext, 0, v, context, -1);
|
|
208
|
+
|
|
209
|
+
indexPairs(1, context);
|
|
210
|
+
|
|
211
|
+
var nonBoundaryLines = getNextNonBoundarySegment(line, currIndex + 1, tile_edge_tolerance);
|
|
212
|
+
if (nonBoundaryLines) {
|
|
213
|
+
context.extra_lines = context.extra_lines || [];
|
|
214
|
+
context.extra_lines.push(nonBoundaryLines);
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
normPrev = normNext;
|
|
220
|
+
normNext = Vector.normalize(Vector.perp(coordCurr, coordNext));
|
|
221
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normPrev, ...normNext];
|
|
222
|
+
|
|
223
|
+
// Add join
|
|
224
|
+
if (join_type === JOIN_TYPE.miter) {
|
|
225
|
+
addMiter(v, coordCurr, normPrev, normNext, miter_len_sq!, false, context);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
addJoin(join_type, v, coordCurr, normPrev, normNext, false, context);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (has_texcoord) {
|
|
232
|
+
v += v_scale! * Vector.length(Vector.sub(coordNext, coordCurr));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// LAST POINT
|
|
237
|
+
coordCurr = coordNext;
|
|
238
|
+
normPrev = normNext;
|
|
239
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normPrev, ...normPrev];
|
|
240
|
+
|
|
241
|
+
if (closed_polygon) {
|
|
242
|
+
// Close the polygon with a miter joint or butt cap if on a tile boundary
|
|
243
|
+
normNext = Vector.normalize(Vector.perp(coordCurr, line[1]));
|
|
244
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normPrev, ...normNext];
|
|
245
|
+
endPolygon(coordCurr, normPrev, normNext, join_type, v, context);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// Finish the line strip
|
|
249
|
+
addVertex(coordCurr, normPrev, normNext, 1, v, context, 1);
|
|
250
|
+
addVertex(coordCurr, normPrev, normNext, 0, v, context, -1);
|
|
251
|
+
|
|
252
|
+
indexPairs(1, context);
|
|
253
|
+
|
|
254
|
+
// If line ends at edge, don't add a cap
|
|
255
|
+
if (!isCoordOutsideTile(coordCurr)) {
|
|
256
|
+
addCap(coordCurr, v, normPrev, cap_type, false, context);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function getTileBoundaryIndex(line: GeometryLine): number {
|
|
263
|
+
if (isCoordOutsideTile(line[0])) {
|
|
264
|
+
return 0;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
for (var backIndex = 0; backIndex < line.length; backIndex++) {
|
|
268
|
+
var coordCurr = line[line.length - 1 - backIndex];
|
|
269
|
+
if (isCoordOutsideTile(coordCurr)) {
|
|
270
|
+
return line.length - 1 - backIndex;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Iterate through line from startIndex to find a segment not on a tile boundary, if any.
|
|
278
|
+
function getNextNonBoundarySegment (line: GeometryLine, startIndex: number, tolerance: number): GeometryLine | false {
|
|
279
|
+
var endIndex = startIndex;
|
|
280
|
+
while (line[endIndex + 1] && outsideTile(line[endIndex], line[endIndex + 1], tolerance)) {
|
|
281
|
+
endIndex++;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// If there is a line segment remaining that is within the tile, push it to the lines array
|
|
285
|
+
return (line.length - endIndex >= 2) ? line.slice(endIndex) : false;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Begin a polygon with a join connecting to the last segment (if valid join-type specified)
|
|
289
|
+
function startPolygon(coordCurr: GeometryCoordinate, normPrev: number[], normNext: number[], join_type: number | undefined, context: PolylineBuildContext): void {
|
|
290
|
+
// If polygon starts on a tile boundary, don't add a join
|
|
291
|
+
if (join_type === undefined || isCoordOutsideTile(coordCurr)) {
|
|
292
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normNext, ...normNext];
|
|
293
|
+
addVertex(coordCurr, normNext, normNext, 1, 0, context, 1);
|
|
294
|
+
addVertex(coordCurr, normNext, normNext, 0, 0, context, -1);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
// If polygon starts within a tile, add a join
|
|
298
|
+
var v = 0;
|
|
299
|
+
if (join_type === JOIN_TYPE.miter) {
|
|
300
|
+
addMiter(v, coordCurr, normPrev, normNext, context.miter_len_sq!, true, context);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
addJoin(join_type, v, coordCurr, normPrev, normNext, true, context);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// End a polygon appropriately
|
|
309
|
+
function endPolygon(coordCurr: GeometryCoordinate, normPrev: number[], normNext: number[], join_type: number, v: number, context: PolylineBuildContext): void {
|
|
310
|
+
// If polygon ends on a tile boundary, don't add a join
|
|
311
|
+
if (isCoordOutsideTile(coordCurr)) {
|
|
312
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normPrev, ...normPrev];
|
|
313
|
+
addVertex(coordCurr, normPrev, normPrev, 1, v, context, 1);
|
|
314
|
+
addVertex(coordCurr, normPrev, normPrev, 0, v, context, -1);
|
|
315
|
+
indexPairs(1, context);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
// If polygon ends within a tile, add Miter or no joint (join added on startPolygon)
|
|
319
|
+
var miterVec = createMiterVec(normPrev, normNext);
|
|
320
|
+
|
|
321
|
+
if (join_type === JOIN_TYPE.miter && Vector.lengthSq(miterVec) > context.miter_len_sq!) {
|
|
322
|
+
join_type = JOIN_TYPE.bevel; // switch to bevel
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (join_type === JOIN_TYPE.miter) {
|
|
326
|
+
addVertex(coordCurr, miterVec, normPrev, 1, v, context, 1);
|
|
327
|
+
addVertex(coordCurr, miterVec, normPrev, 0, v, context, -1);
|
|
328
|
+
indexPairs(1, context);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
if (context.projected_normals_index !== undefined) context.projected_normals = [...normPrev, ...normPrev];
|
|
332
|
+
addVertex(coordCurr, normPrev, normPrev, 1, v, context, 1);
|
|
333
|
+
addVertex(coordCurr, normPrev, normPrev, 0, v, context, -1);
|
|
334
|
+
indexPairs(1, context);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function createMiterVec(normPrev: number[], normNext: number[]): number[] {
|
|
340
|
+
var miterVec = Vector.normalize(Vector.add(normPrev, normNext));
|
|
341
|
+
var scale = 2 / (1 + Math.abs(Vector.dot(normPrev, miterVec)));
|
|
342
|
+
return Vector.mult(miterVec, scale * scale);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Add a miter vector or a join if the miter is too sharp
|
|
346
|
+
function addMiter (v: number, coordCurr: GeometryCoordinate, normPrev: number[], normNext: number[], miter_len_sq: number, isBeginning: boolean, context: PolylineBuildContext): void {
|
|
347
|
+
var miterVec = createMiterVec(normPrev, normNext);
|
|
348
|
+
|
|
349
|
+
// Miter limit: if miter join is too sharp, convert to bevel instead
|
|
350
|
+
if (Vector.lengthSq(miterVec) > miter_len_sq) {
|
|
351
|
+
addJoin(JOIN_TYPE.bevel, v, coordCurr, normPrev, normNext, isBeginning, context);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
addVertex(coordCurr, miterVec, miterVec, 1, v, context, 1);
|
|
355
|
+
addVertex(coordCurr, miterVec, miterVec, 0, v, context, -1);
|
|
356
|
+
if (!isBeginning) {
|
|
357
|
+
indexPairs(1, context);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Add a bevel or round join
|
|
363
|
+
function addJoin(join_type: number, v: number, coordCurr: GeometryCoordinate, normPrev: number[], normNext: number[], isBeginning: boolean, context: PolylineBuildContext): void {
|
|
364
|
+
var miterVec = createMiterVec(normPrev, normNext);
|
|
365
|
+
var isClockwise = (normNext[0] * normPrev[1] - normNext[1] * normPrev[0] > 0);
|
|
366
|
+
|
|
367
|
+
if (context.texcoord_index != null) {
|
|
368
|
+
zero_v[1] = v;
|
|
369
|
+
one_v[1] = v;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (isClockwise){
|
|
373
|
+
addVertex(coordCurr, miterVec, miterVec, 1, v, context, 1);
|
|
374
|
+
addVertex(coordCurr, normPrev, miterVec, 0, v, context, -1);
|
|
375
|
+
|
|
376
|
+
if (!isBeginning) {
|
|
377
|
+
indexPairs(1, context);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
addFan(coordCurr,
|
|
381
|
+
// extrusion vector of first vertex
|
|
382
|
+
Vector.neg(normPrev),
|
|
383
|
+
// controls extrude distance of pivot vertex
|
|
384
|
+
miterVec,
|
|
385
|
+
// extrusion vector of last vertex
|
|
386
|
+
Vector.neg(normNext),
|
|
387
|
+
// line normal (unused here)
|
|
388
|
+
miterVec,
|
|
389
|
+
// uv coordinates
|
|
390
|
+
zero_v, one_v, zero_v,
|
|
391
|
+
false, (join_type === JOIN_TYPE.bevel), context
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
addVertex(coordCurr, miterVec, miterVec, 1, v, context, 1);
|
|
395
|
+
addVertex(coordCurr, normNext, miterVec, 0, v, context, -1);
|
|
396
|
+
} else {
|
|
397
|
+
addVertex(coordCurr, normPrev, miterVec, 1, v, context, 1);
|
|
398
|
+
addVertex(coordCurr, miterVec, miterVec, 0, v, context, -1);
|
|
399
|
+
|
|
400
|
+
if (!isBeginning) {
|
|
401
|
+
indexPairs(1, context);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
addFan(coordCurr,
|
|
405
|
+
// extrusion vector of first vertex
|
|
406
|
+
normPrev,
|
|
407
|
+
// extrusion vector of pivot vertex
|
|
408
|
+
Vector.neg(miterVec),
|
|
409
|
+
// extrusion vector of last vertex
|
|
410
|
+
normNext,
|
|
411
|
+
// line normal for offset
|
|
412
|
+
miterVec,
|
|
413
|
+
// uv coordinates
|
|
414
|
+
one_v, zero_v, one_v,
|
|
415
|
+
false, (join_type === JOIN_TYPE.bevel), context
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
addVertex(coordCurr, normNext, miterVec, 1, v, context, 1);
|
|
419
|
+
addVertex(coordCurr, miterVec, miterVec, 0, v, context, -1);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Add indices to vertex_elements
|
|
424
|
+
function indexPairs(num_pairs: number, context: PolylineBuildContext): void {
|
|
425
|
+
var vertex_elements = context.vertex_data.vertex_elements;
|
|
426
|
+
var num_vertices = context.vertex_data.vertex_count;
|
|
427
|
+
var offset = num_vertices - 2 * num_pairs - 2;
|
|
428
|
+
|
|
429
|
+
for (var i = 0; i < num_pairs; i++){
|
|
430
|
+
vertex_elements.push(offset + 2 * i + 2);
|
|
431
|
+
vertex_elements.push(offset + 2 * i + 1);
|
|
432
|
+
vertex_elements.push(offset + 2 * i + 0);
|
|
433
|
+
vertex_elements.push(offset + 2 * i + 2);
|
|
434
|
+
vertex_elements.push(offset + 2 * i + 3);
|
|
435
|
+
vertex_elements.push(offset + 2 * i + 1);
|
|
436
|
+
context.geom_count += 2;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function addVertex(position: GeometryCoordinate, extrude: number[], normal: number[], u: number, v: number, context: PolylineBuildContext, flip: number): void {
|
|
441
|
+
var vertex_template = context.vertex_template;
|
|
442
|
+
var vertex_data = context.vertex_data;
|
|
443
|
+
|
|
444
|
+
// set vertex position
|
|
445
|
+
vertex_template[0] = position[0];
|
|
446
|
+
vertex_template[1] = position[1];
|
|
447
|
+
|
|
448
|
+
// set line extrusion vector
|
|
449
|
+
let len = context.half_width * flip;
|
|
450
|
+
vertex_template[context.extrude_index + 0] = extrude[0] * len;
|
|
451
|
+
vertex_template[context.extrude_index + 1] = extrude[1] * len;
|
|
452
|
+
|
|
453
|
+
if (context.projected_normals_index !== undefined && context.projected_normals) {
|
|
454
|
+
for (let component = 0; component < 4; component++) {
|
|
455
|
+
vertex_template[context.projected_normals_index + component] = context.projected_normals[component];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (context.projected_widths_index !== undefined) {
|
|
459
|
+
vertex_template[context.projected_widths_index] = context.half_width;
|
|
460
|
+
vertex_template[context.projected_widths_index + 1] = context.offset;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// set line offset vector
|
|
464
|
+
if (context.offset) {
|
|
465
|
+
// Nonzero offsets select a packed offset attribute rather than a constant.
|
|
466
|
+
const offsetIndex = context.offset_index as number;
|
|
467
|
+
vertex_template[offsetIndex + 0] = normal[0] * context.offset;
|
|
468
|
+
vertex_template[offsetIndex + 1] = normal[1] * context.offset;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// set UVs
|
|
472
|
+
if (context.texcoord_index != null) {
|
|
473
|
+
vertex_template[context.texcoord_index + 0] = u * TEXCOORD_NORMALIZE;
|
|
474
|
+
vertex_template[context.texcoord_index + 1] = v * TEXCOORD_NORMALIZE;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
vertex_data.addVertex(vertex_template);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Tesselate a fan geometry between points A ----- B
|
|
481
|
+
// using their normals from a center p \ . . /
|
|
482
|
+
// and interpolating their UVs \ p /
|
|
483
|
+
// \./
|
|
484
|
+
// C
|
|
485
|
+
var uvCurr = [0, 0];
|
|
486
|
+
|
|
487
|
+
function addFan (coord: GeometryCoordinate, eA: number[], eC: number[], eB: number[], normal: number[], uvA: number[], uvC: number[], uvB: number[], isCap: boolean, isBevel: boolean, context: PolylineBuildContext): void {
|
|
488
|
+
// eA = extrusion vector of first outer vertex
|
|
489
|
+
// eC = extrusion vector of inner vertex
|
|
490
|
+
// eA, eC, eB = extrusion vectors
|
|
491
|
+
// normal = line normal for calculating cap offsets
|
|
492
|
+
// coord = center point p - vertex connecting two line segments
|
|
493
|
+
|
|
494
|
+
var cross = eA[0] * eB[1] - eA[1] * eB[0];
|
|
495
|
+
var dot = Vector.dot(eA, eB);
|
|
496
|
+
|
|
497
|
+
var angle = Math.atan2(cross, dot);
|
|
498
|
+
while (angle >= Math.PI) {
|
|
499
|
+
angle -= 2*Math.PI;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (isBevel) {
|
|
503
|
+
numTriangles = 1;
|
|
504
|
+
} else {
|
|
505
|
+
// vary number of triangles in fan with angle (based on MIN_FAN_WIDTH)
|
|
506
|
+
var numTriangles = trianglesPerArc(angle, context.half_width);
|
|
507
|
+
if (numTriangles < 1) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
var pivotIndex = context.vertex_data.vertex_count;
|
|
513
|
+
var vertex_elements = context.vertex_data.vertex_elements;
|
|
514
|
+
if (angle < 0) { // cw
|
|
515
|
+
addVertex(coord, eC, normal, uvC[0], uvC[1], context, 1);
|
|
516
|
+
addVertex(coord, eA, normal, uvA[0], uvA[1], context, 1);
|
|
517
|
+
} else { // ccw
|
|
518
|
+
addVertex(coord, eC, normal, uvC[0], uvC[1], context, 1);
|
|
519
|
+
addVertex(coord, eA, normal, uvA[0], uvA[1], context, 1);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
var blade = eA;
|
|
523
|
+
|
|
524
|
+
var has_texcoord = (context.texcoord_index != null);
|
|
525
|
+
if (has_texcoord) {
|
|
526
|
+
if (isCap){
|
|
527
|
+
var affine_uvCurr = Vector.sub(uvA, uvC);
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
uvCurr = Vector.copy(uvA);
|
|
531
|
+
var uv_delta = Vector.div(Vector.sub(uvB, uvA), numTriangles);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
var angle_step = angle / numTriangles;
|
|
536
|
+
let flip = ((angle < 0) ? -1 : 1); // if angle < 0, is cw - set 'flip' flag
|
|
537
|
+
|
|
538
|
+
// add outside vertices in reverse order depending on sign of angle
|
|
539
|
+
let v1, v2;
|
|
540
|
+
if (cross > 0) {
|
|
541
|
+
v1 = 2;
|
|
542
|
+
v2 = 1;
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
v1 = 1;
|
|
546
|
+
v2 = 2;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
for (var i = 0; i < numTriangles; i++) {
|
|
550
|
+
if (i === 0 && angle < 0) {
|
|
551
|
+
// if ccw, flip the extrusion vector so offsets work properly
|
|
552
|
+
blade = Vector.neg(blade);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
blade = Vector.rot(blade, angle_step);
|
|
556
|
+
|
|
557
|
+
if (has_texcoord) {
|
|
558
|
+
if (isCap){
|
|
559
|
+
// UV textures go "through" the cap
|
|
560
|
+
affine_uvCurr = Vector.rot(affine_uvCurr!, angle_step);
|
|
561
|
+
uvCurr[0] = affine_uvCurr[0] + uvC[0];
|
|
562
|
+
uvCurr[1] = affine_uvCurr[1] * context.texcoord_width * context.v_scale! + uvC[1]; // scale the v-coordinate
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
// UV textures go "around" the join
|
|
566
|
+
uvCurr = Vector.add(uvCurr, uv_delta!);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
addVertex(coord, blade, normal, uvCurr[0], uvCurr[1], context, flip);
|
|
571
|
+
|
|
572
|
+
vertex_elements.push(pivotIndex + i + v1);
|
|
573
|
+
vertex_elements.push(pivotIndex);
|
|
574
|
+
vertex_elements.push(pivotIndex + i + v2);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Function to add the vertices needed for line caps,
|
|
579
|
+
// because to re-use the buffers they need to be at the end
|
|
580
|
+
function addCap (coord: GeometryCoordinate, v: number, normal: number[], type: number, isBeginning: boolean, context: PolylineBuildContext): void {
|
|
581
|
+
var neg_normal = Vector.neg(normal);
|
|
582
|
+
var has_texcoord = (context.texcoord_index != null);
|
|
583
|
+
|
|
584
|
+
switch (type){
|
|
585
|
+
case CAP_TYPE.square:
|
|
586
|
+
var tangent;
|
|
587
|
+
// first vertex on the lineString
|
|
588
|
+
if (isBeginning){
|
|
589
|
+
tangent = [normal[1], -normal[0]];
|
|
590
|
+
|
|
591
|
+
addVertex(coord, Vector.add(normal, tangent), normal, 1, v, context, 1);
|
|
592
|
+
addVertex(coord, Vector.add(neg_normal, tangent), normal, 0, v, context, 1);
|
|
593
|
+
|
|
594
|
+
if (has_texcoord) {
|
|
595
|
+
// Add length of square cap to texture coordinate
|
|
596
|
+
v += 0.5 * context.texcoord_width * context.v_scale!;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
addVertex(coord, normal, normal, 1, v, context, 1);
|
|
600
|
+
addVertex(coord, neg_normal, normal, 0, v, context, 1);
|
|
601
|
+
|
|
602
|
+
}
|
|
603
|
+
// last vertex on the lineString
|
|
604
|
+
else {
|
|
605
|
+
tangent = [-normal[1], normal[0]];
|
|
606
|
+
|
|
607
|
+
addVertex(coord, normal, normal, 1, v, context, 1);
|
|
608
|
+
addVertex(coord, neg_normal, normal, 0, v, context, 1);
|
|
609
|
+
|
|
610
|
+
if (has_texcoord) {
|
|
611
|
+
// Add length of square cap to texture coordinate
|
|
612
|
+
v += 0.5 * context.texcoord_width * context.v_scale!;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
addVertex(coord, Vector.add(normal, tangent), normal, 1, v, context, 1);
|
|
616
|
+
addVertex(coord, Vector.add(neg_normal, tangent), normal, 0, v, context, 1);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
indexPairs(1, context);
|
|
620
|
+
break;
|
|
621
|
+
case CAP_TYPE.round:
|
|
622
|
+
// default for end cap, beginning cap will overwrite below (this way we're always passing a non-null value,
|
|
623
|
+
// even if texture coords are disabled)
|
|
624
|
+
var uvA = zero_v, uvB = one_v, uvC = mid_v;
|
|
625
|
+
var nA, nB;
|
|
626
|
+
|
|
627
|
+
// first vertex on the lineString
|
|
628
|
+
if (isBeginning) {
|
|
629
|
+
nA = normal;
|
|
630
|
+
nB = neg_normal;
|
|
631
|
+
|
|
632
|
+
if (has_texcoord){
|
|
633
|
+
v += 0.5 * context.texcoord_width * context.v_scale!;
|
|
634
|
+
uvA = one_v, uvB = zero_v, uvC = mid_v; // update cap UV order
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
// last vertex on the lineString - flip the direction of the cap
|
|
638
|
+
else {
|
|
639
|
+
nA = neg_normal;
|
|
640
|
+
nB = normal;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (has_texcoord) {
|
|
644
|
+
zero_v[1] = v, one_v[1] = v, mid_v[1] = v; // update cap UV values
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
addFan(coord,
|
|
648
|
+
nA, zero_vec2, nB, // extrusion normal
|
|
649
|
+
normal, // line normal, for offsets
|
|
650
|
+
uvA, uvC, uvB, // texture coords (ignored if disabled)
|
|
651
|
+
true, false, context
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
break;
|
|
655
|
+
case CAP_TYPE.butt:
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Calculate number of triangles for a fan given an angle and line width
|
|
661
|
+
function trianglesPerArc (angle: number, width: number): number {
|
|
662
|
+
if (angle < 0) {
|
|
663
|
+
angle = -angle;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
var numTriangles = (width > 2 * MIN_FAN_WIDTH) ? Math.log2(width / MIN_FAN_WIDTH) : 1;
|
|
667
|
+
return Math.ceil(angle / Math.PI * numTriangles);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Cyclically permute closed line starting at an index
|
|
671
|
+
function permuteLine(line: GeometryLine, startIndex: number): GeometryLine {
|
|
672
|
+
var newLine: GeometryLine = [];
|
|
673
|
+
for (let i = 0; i < line.length; i++){
|
|
674
|
+
var index = (i + startIndex) % line.length;
|
|
675
|
+
// skip the first (repeated) index
|
|
676
|
+
if (index !== 0) {
|
|
677
|
+
newLine.push(line[index]);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
newLine.push(newLine[0]);
|
|
681
|
+
return newLine;
|
|
682
|
+
}
|