Files
armorpaint/base/Sources/LineDraw.ts
T
2024-01-29 17:32:13 +01:00

197 lines
6.6 KiB
TypeScript

class LineDraw {
static color: Color = 0xffff0000;
static strength = 0.005;
static mat: Mat4 = null;
static dim: Vec4 = null;
static vertexBuffer: VertexBuffer;
static indexBuffer: IndexBuffer;
static pipeline: PipelineState = null;
static vp: Mat4;
static vpID: ConstantLocation;
static vbData: DataView;
static ibData: Uint32Array;
static maxLines = 300;
static maxVertices = LineDraw.maxLines * 4;
static maxIndices = LineDraw.maxLines * 6;
static lines = 0;
static g: Graphics4;
static render = (g4: Graphics4, matrix: Mat4) => {
LineDraw.g = g4;
LineDraw.mat = matrix;
LineDraw.dim = matrix.getScale();
if (LineDraw.pipeline == null) {
let structure = new VertexStructure();
structure.add("pos", VertexData.F32_3X);
structure.add("col", VertexData.F32_3X);
LineDraw.pipeline = new PipelineState();
LineDraw.pipeline.inputLayout = [structure];
LineDraw.pipeline.fragmentShader = System.getShader("line.frag");
LineDraw.pipeline.vertexShader = System.getShader("line.vert");
LineDraw.pipeline.depthWrite = true;
LineDraw.pipeline.depthMode = CompareMode.Less;
LineDraw.pipeline.cullMode = CullMode.None;
LineDraw.pipeline.colorAttachmentCount = 3;
LineDraw.pipeline.colorAttachments[0] = TextureFormat.RGBA64;
LineDraw.pipeline.colorAttachments[1] = TextureFormat.RGBA64;
LineDraw.pipeline.colorAttachments[2] = TextureFormat.RGBA64;
LineDraw.pipeline.depthStencilAttachment = DepthStencilFormat.DepthOnly;
LineDraw.pipeline.compile();
LineDraw.vpID = LineDraw.pipeline.getConstantLocation("VP");
LineDraw.vp = Mat4.identity();
LineDraw.vertexBuffer = new VertexBuffer(LineDraw.maxVertices, structure, Usage.DynamicUsage);
LineDraw.indexBuffer = new IndexBuffer(LineDraw.maxIndices, Usage.DynamicUsage);
}
LineDraw.begin();
LineDraw.bounds(LineDraw.mat, LineDraw.dim);
LineDraw.end();
}
static wpos: Vec4;
static vx = new Vec4();
static vy = new Vec4();
static vz = new Vec4();
static bounds = (mat: Mat4, dim: Vec4) => {
LineDraw.wpos = mat.getLoc();
let dx = dim.x / 2;
let dy = dim.y / 2;
let dz = dim.z / 2;
let up = mat.up();
let look = mat.look();
let right = mat.right();
up.normalize();
look.normalize();
right.normalize();
LineDraw.vx.setFrom(right);
LineDraw.vx.mult(dx);
LineDraw.vy.setFrom(look);
LineDraw.vy.mult(dy);
LineDraw.vz.setFrom(up);
LineDraw.vz.mult(dz);
LineDraw.lineb(-1, -1, -1, 1, -1, -1);
LineDraw.lineb(-1, 1, -1, 1, 1, -1);
LineDraw.lineb(-1, -1, 1, 1, -1, 1);
LineDraw.lineb(-1, 1, 1, 1, 1, 1);
LineDraw.lineb(-1, -1, -1, -1, 1, -1);
LineDraw.lineb(-1, -1, 1, -1, 1, 1);
LineDraw.lineb( 1, -1, -1, 1, 1, -1);
LineDraw.lineb( 1, -1, 1, 1, 1, 1);
LineDraw.lineb(-1, -1, -1, -1, -1, 1);
LineDraw.lineb(-1, 1, -1, -1, 1, 1);
LineDraw.lineb( 1, -1, -1, 1, -1, 1);
LineDraw.lineb( 1, 1, -1, 1, 1, 1);
}
static v1 = new Vec4();
static v2 = new Vec4();
static t = new Vec4();
static lineb = (a: i32, b: i32, c: i32, d: i32, e: i32, f: i32) => {
LineDraw.v1.setFrom(LineDraw.wpos);
LineDraw.t.setFrom(LineDraw.vx); LineDraw.t.mult(a); LineDraw.v1.add(LineDraw.t);
LineDraw.t.setFrom(LineDraw.vy); LineDraw.t.mult(b); LineDraw.v1.add(LineDraw.t);
LineDraw.t.setFrom(LineDraw.vz); LineDraw.t.mult(c); LineDraw.v1.add(LineDraw.t);
LineDraw.v2.setFrom(LineDraw.wpos);
LineDraw.t.setFrom(LineDraw.vx); LineDraw.t.mult(d); LineDraw.v2.add(LineDraw.t);
LineDraw.t.setFrom(LineDraw.vy); LineDraw.t.mult(e); LineDraw.v2.add(LineDraw.t);
LineDraw.t.setFrom(LineDraw.vz); LineDraw.t.mult(f); LineDraw.v2.add(LineDraw.t);
LineDraw.line(LineDraw.v1.x, LineDraw.v1.y, LineDraw.v1.z, LineDraw.v2.x, LineDraw.v2.y, LineDraw.v2.z);
}
static midPoint = new Vec4();
static midLine = new Vec4();
static corner1 = new Vec4();
static corner2 = new Vec4();
static corner3 = new Vec4();
static corner4 = new Vec4();
static cameraLook = new Vec4();
static line = (x1: f32, y1: f32, z1: f32, x2: f32, y2: f32, z2: f32) => {
if (LineDraw.lines >= LineDraw.maxLines) {
LineDraw.end();
LineDraw.begin();
}
LineDraw.midPoint.set(x1 + x2, y1 + y2, z1 + z2);
LineDraw.midPoint.mult(0.5);
LineDraw.midLine.set(x1, y1, z1);
LineDraw.midLine.sub(LineDraw.midPoint);
let camera = Scene.camera;
LineDraw.cameraLook = camera.transform.world.getLoc();
LineDraw.cameraLook.sub(LineDraw.midPoint);
let lineWidth = LineDraw.cameraLook.cross(LineDraw.midLine);
lineWidth.normalize();
lineWidth.mult(LineDraw.strength);
LineDraw.corner1.set(x1, y1, z1).add(lineWidth);
LineDraw.corner2.set(x1, y1, z1).sub(lineWidth);
LineDraw.corner3.set(x2, y2, z2).sub(lineWidth);
LineDraw.corner4.set(x2, y2, z2).add(lineWidth);
let i = LineDraw.lines * 24; // 4 * 6 (structure len)
LineDraw.addVbData(i, [LineDraw.corner1.x, LineDraw.corner1.y, LineDraw.corner1.z, color_get_rb(LineDraw.color) / 255, color_get_gb(LineDraw.color) / 255, color_get_ab(LineDraw.color) / 255]);
i += 6;
LineDraw.addVbData(i, [LineDraw.corner2.x, LineDraw.corner2.y, LineDraw.corner2.z, color_get_rb(LineDraw.color) / 255, color_get_gb(LineDraw.color) / 255, color_get_ab(LineDraw.color) / 255]);
i += 6;
LineDraw.addVbData(i, [LineDraw.corner3.x, LineDraw.corner3.y, LineDraw.corner3.z, color_get_rb(LineDraw.color) / 255, color_get_gb(LineDraw.color) / 255, color_get_ab(LineDraw.color) / 255]);
i += 6;
LineDraw.addVbData(i, [LineDraw.corner4.x, LineDraw.corner4.y, LineDraw.corner4.z, color_get_rb(LineDraw.color) / 255, color_get_gb(LineDraw.color) / 255, color_get_ab(LineDraw.color) / 255]);
i = LineDraw.lines * 6;
LineDraw.ibData[i ] = LineDraw.lines * 4;
LineDraw.ibData[i + 1] = LineDraw.lines * 4 + 1;
LineDraw.ibData[i + 2] = LineDraw.lines * 4 + 2;
LineDraw.ibData[i + 3] = LineDraw.lines * 4 + 2;
LineDraw.ibData[i + 4] = LineDraw.lines * 4 + 3;
LineDraw.ibData[i + 5] = LineDraw.lines * 4;
LineDraw.lines++;
}
static begin = () => {
LineDraw.lines = 0;
LineDraw.vbData = LineDraw.vertexBuffer.lock();
LineDraw.ibData = LineDraw.indexBuffer.lock();
}
static end = () => {
LineDraw.vertexBuffer.unlock();
LineDraw.indexBuffer.unlock();
LineDraw.g.setVertexBuffer(LineDraw.vertexBuffer);
LineDraw.g.setIndexBuffer(LineDraw.indexBuffer);
LineDraw.g.setPipeline(LineDraw.pipeline);
let camera = Scene.camera;
LineDraw.vp.setFrom(camera.V);
LineDraw.vp.multmat(camera.P);
LineDraw.g.setMatrix(LineDraw.vpID, LineDraw.vp);
LineDraw.g.drawIndexedVertices(0, LineDraw.lines * 6);
}
static addVbData = (i: i32, data: f32[]) => {
for (let offset = 0; offset < 6; ++offset) {
LineDraw.vbData.setFloat32((i + offset) * 4, data[offset], true);
}
}
}