fix syntax
This commit is contained in:
225
line2d.cm
225
line2d.cm
@@ -78,117 +78,147 @@ function build_polyline_mesh(line) {
|
||||
|
||||
// Transform points if in local space
|
||||
var pts = []
|
||||
for (var i = 0; i < length(points); i++) {
|
||||
var p = points[i]
|
||||
var i = 0
|
||||
var p = null
|
||||
var dx = 0
|
||||
var dy = 0
|
||||
|
||||
for (i = 0; i < length(points); i++) {
|
||||
p = points[i]
|
||||
if (points_space == 'local') {
|
||||
push(pts, {x: p.x + pos.x, y: p.y + pos.y})
|
||||
} else {
|
||||
push(pts, {x: p.x, y: p.y})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate cumulative distances
|
||||
var cumulative = [0]
|
||||
for (var i = 1; i < length(pts); i++) {
|
||||
var dx = pts[i].x - pts[i-1].x
|
||||
var dy = pts[i].y - pts[i-1].y
|
||||
for (i = 1; i < length(pts); i++) {
|
||||
dx = pts[i].x - pts[i-1].x
|
||||
dy = pts[i].y - pts[i-1].y
|
||||
push(cumulative, cumulative[i-1] + math.sqrt(dx*dx + dy*dy))
|
||||
}
|
||||
var total_length = cumulative[length(cumulative) - 1]
|
||||
|
||||
|
||||
// Build triangle strip mesh
|
||||
var verts = []
|
||||
var indices = []
|
||||
|
||||
|
||||
// Get width at point i
|
||||
function get_width(i) {
|
||||
if (widths && length(widths) > i) return widths[i]
|
||||
function get_width(idx) {
|
||||
if (widths && length(widths) > idx) return widths[idx]
|
||||
return width
|
||||
}
|
||||
|
||||
|
||||
// Get U coordinate at point i
|
||||
function get_u(i) {
|
||||
var seg_idx = 0
|
||||
var seg_len = 0
|
||||
function get_u(idx) {
|
||||
if (uv_mode == 'stretch') {
|
||||
return total_length > 0 ? cumulative[i] / total_length : 0
|
||||
return total_length > 0 ? cumulative[idx] / total_length : 0
|
||||
} else if (uv_mode == 'per_segment') {
|
||||
if (i == 0) return 0
|
||||
var seg_idx = i - 1
|
||||
var seg_len = cumulative[i] - cumulative[i-1]
|
||||
if (idx == 0) return 0
|
||||
seg_idx = idx - 1
|
||||
seg_len = cumulative[idx] - cumulative[idx-1]
|
||||
return 1 // Each segment ends at u=1
|
||||
} else {
|
||||
// repeat (default)
|
||||
return cumulative[i] * u_per_unit + u_offset
|
||||
return cumulative[idx] * u_per_unit + u_offset
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate normals at each point
|
||||
var normals = []
|
||||
for (var i = 0; i < length(pts); i++) {
|
||||
var prev = i > 0 ? pts[i-1] : (closed ? pts[length(pts)-1] : null)
|
||||
var curr = pts[i]
|
||||
var next = i < length(pts)-1 ? pts[i+1] : (closed ? pts[0] : null)
|
||||
|
||||
var n = {x: 0, y: 0}
|
||||
|
||||
var prev = null
|
||||
var curr = null
|
||||
var next = null
|
||||
var n = null
|
||||
var d1x = 0
|
||||
var d1y = 0
|
||||
var d2x = 0
|
||||
var d2y = 0
|
||||
var len1 = 0
|
||||
var len2 = 0
|
||||
var n1x = 0
|
||||
var n1y = 0
|
||||
var n2x = 0
|
||||
var n2y = 0
|
||||
var nlen = 0
|
||||
var dot = 0
|
||||
var miter_scale = 0
|
||||
var len = 0
|
||||
|
||||
for (i = 0; i < length(pts); i++) {
|
||||
prev = i > 0 ? pts[i-1] : (closed ? pts[length(pts)-1] : null)
|
||||
curr = pts[i]
|
||||
next = i < length(pts)-1 ? pts[i+1] : (closed ? pts[0] : null)
|
||||
|
||||
n = {x: 0, y: 0}
|
||||
|
||||
if (prev && next) {
|
||||
// Middle point - average normals
|
||||
var d1x = curr.x - prev.x
|
||||
var d1y = curr.y - prev.y
|
||||
var d2x = next.x - curr.x
|
||||
var d2y = next.y - curr.y
|
||||
|
||||
var len1 = math.sqrt(d1x*d1x + d1y*d1y)
|
||||
var len2 = math.sqrt(d2x*d2x + d2y*d2y)
|
||||
|
||||
d1x = curr.x - prev.x
|
||||
d1y = curr.y - prev.y
|
||||
d2x = next.x - curr.x
|
||||
d2y = next.y - curr.y
|
||||
|
||||
len1 = math.sqrt(d1x*d1x + d1y*d1y)
|
||||
len2 = math.sqrt(d2x*d2x + d2y*d2y)
|
||||
|
||||
if (len1 > 0.0001) { d1x /= len1; d1y /= len1 }
|
||||
if (len2 > 0.0001) { d2x /= len2; d2y /= len2 }
|
||||
|
||||
|
||||
// Normals (perpendicular)
|
||||
var n1x = -d1y, n1y = d1x
|
||||
var n2x = -d2y, n2y = d2x
|
||||
|
||||
n1x = -d1y
|
||||
n1y = d1x
|
||||
n2x = -d2y
|
||||
n2y = d2x
|
||||
|
||||
// Average
|
||||
n.x = n1x + n2x
|
||||
n.y = n1y + n2y
|
||||
var nlen = math.sqrt(n.x*n.x + n.y*n.y)
|
||||
nlen = math.sqrt(n.x*n.x + n.y*n.y)
|
||||
if (nlen > 0.0001) { n.x /= nlen; n.y /= nlen }
|
||||
|
||||
|
||||
// Miter correction
|
||||
var dot = n1x * n.x + n1y * n.y
|
||||
dot = n1x * n.x + n1y * n.y
|
||||
if (dot > 0.0001) {
|
||||
var miter_scale = 1 / dot
|
||||
miter_scale = 1 / dot
|
||||
if (miter_scale > miter_limit) miter_scale = miter_limit
|
||||
n.x *= miter_scale
|
||||
n.y *= miter_scale
|
||||
}
|
||||
} else if (next) {
|
||||
// Start point
|
||||
var dx = next.x - curr.x
|
||||
var dy = next.y - curr.y
|
||||
var len = math.sqrt(dx*dx + dy*dy)
|
||||
dx = next.x - curr.x
|
||||
dy = next.y - curr.y
|
||||
len = math.sqrt(dx*dx + dy*dy)
|
||||
if (len > 0.0001) { dx /= len; dy /= len }
|
||||
n.x = -dy
|
||||
n.y = dx
|
||||
} else if (prev) {
|
||||
// End point
|
||||
var dx = curr.x - prev.x
|
||||
var dy = curr.y - prev.y
|
||||
var len = math.sqrt(dx*dx + dy*dy)
|
||||
dx = curr.x - prev.x
|
||||
dy = curr.y - prev.y
|
||||
len = math.sqrt(dx*dx + dy*dy)
|
||||
if (len > 0.0001) { dx /= len; dy /= len }
|
||||
n.x = -dy
|
||||
n.y = dx
|
||||
}
|
||||
|
||||
|
||||
push(normals, n)
|
||||
}
|
||||
|
||||
|
||||
// Generate vertices (2 per point - left and right of line)
|
||||
for (var i = 0; i < length(pts); i++) {
|
||||
var p = pts[i]
|
||||
var n = normals[i]
|
||||
var w = get_width(i) * 0.5
|
||||
var u = get_u(i)
|
||||
|
||||
var w = 0
|
||||
var u = 0
|
||||
for (i = 0; i < length(pts); i++) {
|
||||
p = pts[i]
|
||||
n = normals[i]
|
||||
w = get_width(i) * 0.5
|
||||
u = get_u(i)
|
||||
|
||||
// Left vertex (v=0)
|
||||
push(verts, {
|
||||
x: p.x + n.x * w,
|
||||
@@ -197,7 +227,7 @@ function build_polyline_mesh(line) {
|
||||
v: v_offset,
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
|
||||
|
||||
// Right vertex (v=1)
|
||||
push(verts, {
|
||||
x: p.x - n.x * w,
|
||||
@@ -207,10 +237,11 @@ function build_polyline_mesh(line) {
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// Generate indices (triangle strip as triangles)
|
||||
for (var i = 0; i < length(pts) - 1; i++) {
|
||||
var base = i * 2
|
||||
var base = 0
|
||||
for (i = 0; i < length(pts) - 1; i++) {
|
||||
base = i * 2
|
||||
// First triangle
|
||||
push(indices, base + 0)
|
||||
push(indices, base + 1)
|
||||
@@ -220,10 +251,11 @@ function build_polyline_mesh(line) {
|
||||
push(indices, base + 3)
|
||||
push(indices, base + 2)
|
||||
}
|
||||
|
||||
|
||||
// Handle closed path
|
||||
var last = 0
|
||||
if (closed && length(pts) > 2) {
|
||||
var last = (length(pts) - 1) * 2
|
||||
last = (length(pts) - 1) * 2
|
||||
push(indices, last + 0)
|
||||
push(indices, last + 1)
|
||||
push(indices, 0)
|
||||
@@ -234,11 +266,11 @@ function build_polyline_mesh(line) {
|
||||
|
||||
// Add round caps if requested
|
||||
if (!closed && cap == 'round') {
|
||||
add_round_cap(verts, indices, pts[0], normals[0], get_width(0), get_u(0), v_offset, v_scale, true)
|
||||
add_round_cap(verts, indices, pts[length(pts)-1], normals[length(pts)-1], get_width(length(pts)-1), get_u(length(pts)-1), v_offset, v_scale, false)
|
||||
add_round_cap({verts: verts, indices: indices, p: pts[0], n: normals[0], width: get_width(0), u: get_u(0), v_offset: v_offset, v_scale: v_scale, is_start: true})
|
||||
add_round_cap({verts: verts, indices: indices, p: pts[length(pts)-1], n: normals[length(pts)-1], width: get_width(length(pts)-1), u: get_u(length(pts)-1), v_offset: v_offset, v_scale: v_scale, is_start: false})
|
||||
} else if (!closed && cap == 'square') {
|
||||
add_square_cap(verts, indices, pts[0], normals[0], get_width(0), get_u(0), v_offset, v_scale, true, pts[1])
|
||||
add_square_cap(verts, indices, pts[length(pts)-1], normals[length(pts)-1], get_width(length(pts)-1), get_u(length(pts)-1), v_offset, v_scale, false, pts[length(pts)-2])
|
||||
add_square_cap({verts: verts, indices: indices, p: pts[0], n: normals[0], width: get_width(0), u: get_u(0), v_offset: v_offset, v_scale: v_scale, is_start: true, adjacent: pts[1]})
|
||||
add_square_cap({verts: verts, indices: indices, p: pts[length(pts)-1], n: normals[length(pts)-1], width: get_width(length(pts)-1), u: get_u(length(pts)-1), v_offset: v_offset, v_scale: v_scale, is_start: false, adjacent: pts[length(pts)-2]})
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -249,15 +281,25 @@ function build_polyline_mesh(line) {
|
||||
}
|
||||
}
|
||||
|
||||
function add_round_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_start) {
|
||||
var w = width * 0.5
|
||||
function add_round_cap(opts) {
|
||||
var verts = opts.verts
|
||||
var indices = opts.indices
|
||||
var p = opts.p
|
||||
var n = opts.n
|
||||
var rc_width = opts.width
|
||||
var u = opts.u
|
||||
var v_offset = opts.v_offset
|
||||
var v_scale = opts.v_scale
|
||||
var is_start = opts.is_start
|
||||
|
||||
var w = rc_width * 0.5
|
||||
var segments = 8
|
||||
var base_idx = length(verts)
|
||||
|
||||
|
||||
// Direction along the line
|
||||
var dx = is_start ? -n.y : n.y
|
||||
var dy = is_start ? n.x : -n.x
|
||||
|
||||
|
||||
// Center vertex
|
||||
push(verts, {
|
||||
x: p.x,
|
||||
@@ -266,14 +308,18 @@ function add_round_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_sta
|
||||
v: 0.5 * v_scale + v_offset,
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
|
||||
|
||||
// Arc vertices
|
||||
var start_angle = is_start ? math.arc_tangent(n.y, n.x) : math.arc_tangent(-n.y, -n.x)
|
||||
for (var i = 0; i <= segments; i++) {
|
||||
var angle = start_angle + (i / segments) * 3.14159
|
||||
var cx = math.cosine(angle)
|
||||
var cy = math.sine(angle)
|
||||
|
||||
var i = 0
|
||||
var angle = 0
|
||||
var cx = 0
|
||||
var cy = 0
|
||||
for (i = 0; i <= segments; i++) {
|
||||
angle = start_angle + (i / segments) * 3.14159
|
||||
cx = math.cosine(angle)
|
||||
cy = math.sine(angle)
|
||||
|
||||
push(verts, {
|
||||
x: p.x + cx * w,
|
||||
y: p.y + cy * w,
|
||||
@@ -282,30 +328,41 @@ function add_round_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_sta
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// Fan triangles
|
||||
for (var i = 0; i < segments; i++) {
|
||||
for (i = 0; i < segments; i++) {
|
||||
push(indices, base_idx)
|
||||
push(indices, base_idx + 1 + i)
|
||||
push(indices, base_idx + 2 + i)
|
||||
}
|
||||
}
|
||||
|
||||
function add_square_cap(verts, indices, p, n, width, u, v_offset, v_scale, is_start, adjacent) {
|
||||
var w = width * 0.5
|
||||
function add_square_cap(opts) {
|
||||
var verts = opts.verts
|
||||
var indices = opts.indices
|
||||
var p = opts.p
|
||||
var n = opts.n
|
||||
var sc_width = opts.width
|
||||
var u = opts.u
|
||||
var v_offset = opts.v_offset
|
||||
var v_scale = opts.v_scale
|
||||
var is_start = opts.is_start
|
||||
var adjacent = opts.adjacent
|
||||
|
||||
var w = sc_width * 0.5
|
||||
var base_idx = length(verts)
|
||||
|
||||
|
||||
// Direction along the line (away from adjacent point)
|
||||
var dx = p.x - adjacent.x
|
||||
var dy = p.y - adjacent.y
|
||||
var len = math.sqrt(dx*dx + dy*dy)
|
||||
if (len > 0.0001) { dx /= len; dy /= len }
|
||||
|
||||
|
||||
// Extend by half width
|
||||
var ext = w
|
||||
var ex = p.x + dx * ext
|
||||
var ey = p.y + dy * ext
|
||||
|
||||
|
||||
// Four corners of the cap
|
||||
push(verts, {x: p.x + n.x * w, y: p.y + n.y * w, u: u, v: v_offset, r: 1, g: 1, b: 1, a: 1})
|
||||
push(verts, {x: p.x - n.x * w, y: p.y - n.y * w, u: u, v: v_scale + v_offset, r: 1, g: 1, b: 1, a: 1})
|
||||
@@ -388,9 +445,9 @@ var line2d = {
|
||||
return make_line(props)
|
||||
},
|
||||
|
||||
line: function(x1, y1, x2, y2, props) {
|
||||
line: function(from, to, props) {
|
||||
var p = props || {}
|
||||
p.points = [{x: x1, y: y1}, {x: x2, y: y2}]
|
||||
p.points = [{x: from.x, y: from.y}, {x: to.x, y: to.y}]
|
||||
return make_line(p)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user