From 7f83d0d65acba1c1a5b65a8258b75d1f318c22f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Schmelczer?= Date: Sat, 29 Jan 2022 21:11:32 +0100 Subject: [PATCH] Add hexagons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: AndrĂ¡s Schmelczer --- src/drawables/shapes/hexagon-factory.ts | 69 +++++++++++++++++++++++++ src/main.ts | 1 + 2 files changed, 70 insertions(+) create mode 100644 src/drawables/shapes/hexagon-factory.ts diff --git a/src/drawables/shapes/hexagon-factory.ts b/src/drawables/shapes/hexagon-factory.ts new file mode 100644 index 0000000..19d0df1 --- /dev/null +++ b/src/drawables/shapes/hexagon-factory.ts @@ -0,0 +1,69 @@ +import { mat2d, vec2, vec3, vec4 } from 'gl-matrix'; +import { codeForColorAccess } from '../../helper/code-for-color-access'; +import { DrawableDescriptor } from '../drawable-descriptor'; +import { EmptyDrawable } from '../empty-drawable'; + +/** + * @category Drawable + */ +class HexagonBase extends EmptyDrawable { + constructor(public center: vec2, public radius: number) { + super(); + } +} + +/** + * @category Drawable + */ +export const HexagonFactory = (color: vec3 | vec4 | number): typeof HexagonBase => { + class Hexagon extends HexagonBase { + public static descriptor: DrawableDescriptor = { + sdf: { + shader: ` + uniform vec2 circleCenters[CIRCLE_COUNT]; + uniform float circleRadii[CIRCLE_COUNT]; + + float circleMinDistance(vec2 target, out vec4 color) { + color = ${codeForColorAccess(color)}; + float minDistance = 1000.0; + for (int i = 0; i < CIRCLE_COUNT; i++) { + const vec3 k = vec3(-0.866025404,0.5,0.577350269); + float r = circleRadii[i]; + vec2 p = abs(target - circleCenters[i]); + float cosa = 0.8660; + float sina = 0.5; + p = vec2(cosa * p.x - sina * p.y, sina * p.x + cosa * p.y); + p -= 2.0*min(dot(k.xy,p),0.0)*k.xy; + p -= vec2(clamp(p.x, -k.z*r, k.z*r), r); + float dist = length(p)*sign(p.y); + minDistance = min(minDistance, dist); + } + + return minDistance; + } + `, + distanceFunctionName: 'circleMinDistance', + }, + propertyUniformMapping: { + center: 'circleCenters', + radius: 'circleRadii', + }, + uniformCountMacroName: 'CIRCLE_COUNT', + shaderCombinationSteps: [0, 1, 2, 3, 8, 16], + empty: new Hexagon(vec2.create(), 0), + }; + + public minDistance(target: vec2): number { + return vec2.dist(this.center, target) - this.radius; + } + + protected getObjectToSerialize(transform2d: mat2d, transform1d: number): any { + return { + center: vec2.transformMat2d(vec2.create(), this.center, transform2d), + radius: this.radius * transform1d, + }; + } + } + + return Hexagon; +}; diff --git a/src/main.ts b/src/main.ts index 2dbdd0f..c98086c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,6 +33,7 @@ export * from './drawables/drawable-descriptor'; export * from './drawables/lights/circle-light'; export * from './drawables/lights/flashlight'; export * from './drawables/shapes/circle-factory'; +export * from './drawables/shapes/hexagon-factory'; export * from './drawables/shapes/colorful-circle'; export * from './drawables/shapes/droplet-factory'; export * from './drawables/shapes/inverted-tunnel-factory';