diff --git a/asset/clamped_sprite.material_basis.lx b/asset/clamped_sprite.material_basis.lx new file mode 100644 index 0000000..f592671 --- /dev/null +++ b/asset/clamped_sprite.material_basis.lx @@ -0,0 +1,52 @@ +material_basis = { + vertex_format = "luxe.textured" + shaders = { + vertex = { library="luxe: shaders" function="vert_color_uv" } + fragment = { library="luxe: shaders" function="textured_uv_color" } + } + depth_test = true + depth_write = true + depth_compare = "less_equal" + stencil_test = false + write_mask = { red=true green=true blue=true alpha=true } + blending = true + alpha_blend = "add" + rgb_blend = "add" + src_alpha = "source_alpha" + src_rgb = "source_alpha" + dest_alpha = "one_minus_source_alpha" + dest_rgb = "one_minus_source_alpha" + blend_color = [0 0 0 0] + cull = "none" + winding = "counter_clockwise" + layers = ["default"] + inputs = { + sprite.image = { + type = "image" + value = { + type = "image2D" + sampler_state = "linear_clamp" + } + } + sprite.uv = { + type = "float4" + value = [0 0 1 1] + } + sprite.uv_flip = { + type = "bool2" + value = [false false] + } + sprite.color = { + type = "float4" + value = [1 1 1 1] + } + sprite.skew = { + type = "float2" + value = [0 0] + } + } +} +preview = { + hint = "sprite" + image = "sprite.image" +} \ No newline at end of file diff --git a/asset/flag.material.lx b/asset/flag.material.lx index 47e838e..23bcbbb 100644 --- a/asset/flag.material.lx +++ b/asset/flag.material.lx @@ -1,5 +1,5 @@ material = { - basis = "luxe: material_basis/sprite" + basis = "asset/clamped_sprite" inputs = { sprite.image = "asset/flag" sprite.color = [1 1 1 1] diff --git a/game.wren b/game.wren index b35c7bd..2b7cefa 100644 --- a/game.wren +++ b/game.wren @@ -29,7 +29,7 @@ class Game is Ready { tick(delta) { var pos = Camera.screen_point_to_world(app.camera, Input.mouse_x(), Input.mouse_y()) - var t = delta * 30 + var t = delta * 10 pos = [Math.lerp(_prev_pos.x, pos.x, t), Math.lerp(_prev_pos.y, pos.y, t)] if(Math.dist2D(pos, _prev_pos) > 0.1){ var angle = Math.angle2D(_prev_pos, pos) @@ -45,6 +45,11 @@ class Game is Ready { Trail.reset(_blade) } + if(Input.key_state_released(Key.key_1)) { + var subs = Trail.get_subdivisions_length(_blade) + 1 + Trail.set_subdivisions_length(_blade, subs) + } + //app.color.r = app.color.g = app.color.b = (IO.timestamp()/20 % 1) //System.print(1/delta) } //tick diff --git a/modifiers/trail/trail.wren b/modifiers/trail/trail.wren index a81e106..00b4864 100644 --- a/modifiers/trail/trail.wren +++ b/modifiers/trail/trail.wren @@ -15,14 +15,82 @@ import "luxe: math" for Math //This is what the user of your modifier will interact with class Trail { - static create(entity) { Modifiers.create(This, entity) } - static destroy(entity) { Modifiers.destroy(This, entity) } - static has(entity) { Modifiers.has(This, entity) } + static create(entity: Entity): None { + Modifiers.create(This, entity) + } - static reset(entity){ + static destroy(entity: Entity): None { + Modifiers.destroy(This, entity) + + } + static has(entity: Entity): None { + Modifiers.has(This, entity) + } + + static reset(entity: Entity): None { Modifiers.get_system(This, entity).reset(entity ) } + static set_width(entity: Entity, width: Num): None { + Modifiers.get(This, entity).edge_length = width + } + + static get_width(entity: Entity): Num { + return Modifiers.get(This, entity).edge_length + } + + static set_length(entity: Entity, length: Num): None { + Modifiers.get(This, entity).length = length + //todo: recalculate transient data? + } + + static get_length(entity: Entity): Num { + return Modifiers.get(This, entity).length + } + + static set_time_based(entity: Entity, time_based: Num): None { + Modifiers.get(This, entity).time_based = time_based + } + + static get_time_based(entity: Entity): Num { + return Modifiers.get(This, entity).time_based + } + + static set_normalize_uvs(entity: Entity, normalize_uvs: Num): None { + Modifiers.get(This, entity).normalize_uvs = normalize_uvs + } + + static get_normalize_uvs(entity: Entity): Num { + return Modifiers.get(This, entity).normalize_uvs + } + + static set_material_id(entity: Entity, material_id: String): None { + Strings.add(material_id) + Modifiers.get(This, entity).material = material_id + Modifiers.get_system(This, entity).set_material(entity, material_id) + } + + static get_material_id(entity: Entity): String { + return Strings.get(Modifiers.get(This, entity).material) + } + + static set_subdivisions_length(entity: Entity, subdivisions: Num){ + Modifiers.get(This, entity).subdivisions_length = subdivisions + Modifiers.get_system(This, entity).recreate_buffers(entity) + } + + static get_subdivisions_length(entity: Entity): Num{ + return Modifiers.get(This, entity).subdivisions_length + } + + static set_subdivisions_width(entity: Entity, subdivisions: Num){ + Modifiers.get(This, entity).subdivisions_width = subdivisions + Modifiers.get_system(This, entity).recreate_buffers(entity) + } + + static get_subdivisions_width(entity: Entity): Num{ + return Modifiers.get(This, entity).subdivisions_width + } } //Trail #hidden @@ -106,6 +174,34 @@ class TrailSystem is ModifierSystem { _instance_data[entity].points.clear() } + set_material(entity: Entity, material_id: String){ + var material = Assets.material(material_id) + var data = _instance_data[entity] + if(!data || !material) return + Geometry.set_material(entity, material) + } + + recreate_buffers(entity: Entity){ + var data = get(entity) + var inst_data: TrailData = _instance_data[entity] + + if(!data || !inst_data) return + + inst_data.points.clear() + + var index_data = create_index_buffer(data.subdivisions_length, data.subdivisions_width) + Render.index_buffer_replace(inst_data.index_buffer, index_data, index_data.length) + + var pos_data = create_position_buffer(data.subdivisions_length, data.subdivisions_width) + Render.vertex_buffer_replace(inst_data.position_buffer, pos_data, pos_data.length) + + var uv_data = create_uv_buffer(data.subdivisions_length, data.subdivisions_width) + Render.vertex_buffer_replace(inst_data.uv_buffer, uv_data, uv_data.length) + + var color_data = create_color_buffer(data.subdivisions_length, data.subdivisions_width) + Render.vertex_buffer_replace(inst_data.color_buffer, color_data, color_data.length) + } + destroy() { Draw.destroy(_draw) } @@ -115,15 +211,19 @@ class TrailSystem is ModifierSystem { var material = Assets.material(material_id) var index_buffer = create_index_buffer(data.subdivisions_length, data.subdivisions_width) + index_buffer = Render.create_index_buffer(index_buffer, index_buffer.length) var geo = Geometry.create(Primitive.triangle, material, (data.subdivisions_length - 1) * 6, IndexType.u16, index_buffer) - var pos_buffer = create_position_buffer(data.edge_length, data.length, data.subdivisions_length, data.subdivisions_width) + var pos_buffer = create_position_buffer(data.subdivisions_length, data.subdivisions_width) + pos_buffer = Render.create_vertex_buffer(pos_buffer, pos_buffer.length) Geometry.set_vertex_buffer(geo, 0, pos_buffer) var color_buffer = create_color_buffer(data.subdivisions_length, data.subdivisions_width) + color_buffer = Render.create_vertex_buffer(color_buffer, color_buffer.length) Geometry.set_vertex_buffer(geo, 1, color_buffer) var uv_buffer = create_uv_buffer(data.subdivisions_length, data.subdivisions_width) + uv_buffer = Render.create_vertex_buffer(uv_buffer, uv_buffer.length) Geometry.set_vertex_buffer(geo, 2, uv_buffer) World.render_set_add(_world, geo, entity) @@ -131,12 +231,12 @@ class TrailSystem is ModifierSystem { _instance_data[entity] = TrailData.new(geo, index_buffer, pos_buffer, color_buffer, uv_buffer) } - create_position_buffer(height: Num, length: Num, subdivs_len: Num, subdivs_width: Num): VertexBuffer{ + create_position_buffer(subdivs_len: Num, subdivs_width: Num): Floats{ var raw = Floats.new(4 * subdivs_width * subdivs_len) - return Render.create_vertex_buffer(raw, raw.length) + return raw } - create_color_buffer(subdivs_len: Num, subdivs_width: Num): VertexBuffer{ + create_color_buffer(subdivs_len: Num, subdivs_width: Num): Floats{ var raw = Floats.new(4 * subdivs_width * subdivs_len) for(i in 0...subdivs_len){ for(ii in 0...subdivs_width){ @@ -148,10 +248,10 @@ class TrailSystem is ModifierSystem { } //var arr = (0...(raw.size/4)).map{|i|"[%(raw[i*4]), %(raw[i*4+1]), %(raw[i*4+2])]"}.join("\n") //System.print(arr) - return Render.create_vertex_buffer(raw, raw.length) + return raw } - create_uv_buffer(subdivs_len: Num, subdivs_width: Num): VertexBuffer{ + create_uv_buffer(subdivs_len: Num, subdivs_width: Num): Floats{ var raw = Floats.new(2 * subdivs_width * subdivs_len) for(i in 0...subdivs_len){ var x = i / (subdivs_len - 1) @@ -163,10 +263,10 @@ class TrailSystem is ModifierSystem { } //var arr = (0...(raw.size/2)).map{|i|"[%(raw[i*2]), %(raw[i*2+1])]"}.join("\n") //System.print(arr) - return Render.create_vertex_buffer(raw, raw.length) + return raw } - create_index_buffer(subdivs_len: Num, subdivs_width: Num): IndexBuffer{ + create_index_buffer(subdivs_len: Num, subdivs_width: Num): Uint16{ var rows = subdivs_len - 1 var cols = subdivs_width-1 var index_count = rows * cols * 6 @@ -191,7 +291,7 @@ class TrailSystem is ModifierSystem { } //var arr = (0...(raw.length/(3*4))).map{|i|"[%(raw[i*3]), %(raw[i*3+1]), %(raw[i*3+2])]"}.join("\n") //System.print(arr) - return Render.create_index_buffer(raw, raw.length) + return raw } detach(entity, data: ModifierData) { @@ -277,8 +377,18 @@ class TrailSystem is ModifierSystem { if(!Transform.has(entity)) return var instance_data: TrailData = _instance_data[entity] + var points = instance_data.points + + var pos = Transform.get_pos_world(entity) + var positions = Floats.new(Render.vertex_buffer_get_size(instance_data.position_buffer) / 4) Render.vertex_buffer_get_data(instance_data.position_buffer, positions, positions.size * 4, 0) + + var uvs: Floats + if(data.normalize_uvs){ + uvs = Floats.new(Render.vertex_buffer_get_size(instance_data.uv_buffer) / 4) + Render.vertex_buffer_get_data(instance_data.uv_buffer, uvs, uvs.size * 4, 0) + } //System.print("positions(%(Render.vertex_buffer_get_size(instance_data.position_buffer))):") //System.print((0...(positions.size/4)).map{|i|"[%(positions[i*4]), %(positions[i*4+1]), %(positions[i*4+2])]"}.join("\n")) var i = -1 @@ -299,16 +409,33 @@ class TrailSystem is ModifierSystem { } } - var step = data.length / data.subdivisions_length + var length = 0 + var current_len = 0 + if(data.normalize_uvs){ + for(i in 0...points.count){ + var from = i<(points.count-1)? points[i+1].pos : pos + var to = points[i].pos + var dist = Math.dist(from, to) + length = length + (i != (points.count-1) ? dist : dist * (1 - instance_data.progress_since_last_point / (data.length / data.subdivisions_length))) + } - var point_index = instance_data.points.count - 1 + current_len = points.count > 1 ? Math.dist(points[points.count-1].pos, pos) : 0 + } + + var step = data.length / data.subdivisions_length + var t = 1 - instance_data.progress_since_last_point / step + + var point_index = points.count - 1 while(true){ + if(point_index < 0) break + + var p:Point + var next:Point + point_index = point_index - 1 if(point_index < 0) break - i = i + 1 - - var p:Point = instance_data.points[point_index] - var next:Point = instance_data.points[point_index + 1] + p = points[point_index] + next = points[point_index + 1] var to = p.pos var to_up = p.up @@ -316,8 +443,7 @@ class TrailSystem is ModifierSystem { var from = next.pos var from_up = next.up - var t = 1 - instance_data.progress_since_last_point / step - + var pos = [ Math.lerp(from.x, to.x, t), Math.lerp(from.y, to.y, t), @@ -332,14 +458,7 @@ class TrailSystem is ModifierSystem { Math.normalize(up) - //pos_x = to.x - //pos_y = to.y - //pos_z = to.z - - //up_x = to_up.x - //up_y = to_up.y - //up_z = to_up.z - + i = i + 1 for(y in 0...data.subdivisions_width){ var t = y / (data.subdivisions_width-1) var offset_x = Math.lerp(-up.x, up.x, t) @@ -349,9 +468,24 @@ class TrailSystem is ModifierSystem { positions[i*4*data.subdivisions_width + y*4 + 1] = pos.y + offset_y * data.edge_length * 0.5 positions[i*4*data.subdivisions_width + y*4 + 2] = pos.z + offset_z * data.edge_length * 0.5 } + + if(data.normalize_uvs){ + var segment_len = Math.dist(from, to) + current_len = current_len + segment_len * t + var x = current_len / length + for(ii in 0...data.subdivisions_width){ + var y = ii / (data.subdivisions_width - 1) + uvs[i*2*data.subdivisions_width + ii*2 + 0] = x + uvs[i*2*data.subdivisions_width + ii*2 + 1] = y + } + current_len = current_len + segment_len * (1-t) + } } Render.vertex_buffer_replace(instance_data.position_buffer, positions, positions.length) + if(data.normalize_uvs){ + Render.vertex_buffer_replace(instance_data.uv_buffer, uvs, uvs.length) + } Geometry.set_vert_count(instance_data.geometry, i.max(0) * 6 * (data.subdivisions_width-1)) } } @@ -369,12 +503,13 @@ class TrailSystem is ModifierSystem { Draw.line(_draw, start.x, start.y, end.x, end.y, depth, _debug_edge_style) var instance_data: TrailData = _instance_data[entity] + var points = instance_data.points - if(instance_data.points.count > 1){ - Draw.path3D(_draw, instance_data.points.map{|p:Point|p.pos}.toList, _debug_path_style, false) + if(points.count > 1){ + Draw.path3D(_draw, points.map{|p:Point|p.pos}.toList, _debug_path_style, false) } - instance_data.points.each{|point: Point| + points.each{|point: Point| var from_x = point.pos.x + point.up.x * data.edge_length * 0.5 var from_y = point.pos.y + point.up.y * data.edge_length * 0.5 var from_z = point.pos.x + point.up.x * data.edge_length * 0.5