Skip to content

Commit

Permalink
Allow inline hex values to set vec3 params in shader projects
Browse files Browse the repository at this point in the history
  • Loading branch information
flatpickles committed Oct 19, 2023
1 parent 4b9da60 commit 4dc9358
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
19 changes: 12 additions & 7 deletions src/lib/base/ProjectLoading/ParamInference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { NumberParamStyle } from '../ConfigModels/ParamConfigs/NumberParamConfig
import { NumericArrayParamStyle } from '../ConfigModels/ParamConfigs/NumericArrayParamConfig';
import { StringParamStyle } from '../ConfigModels/ParamConfigs/StringParamConfig';
import { ParamGuards } from '../ConfigModels/ParamTypes';
import ColorConversions from '../Util/ColorConversions';

export enum InferenceMode {
ProjectFile,
Expand Down Expand Up @@ -109,12 +110,16 @@ export default class ParamInference {
newConfig.default = intentions.booleanValues[0];
}

// Assign numeric array value tokens
if (
ParamGuards.isNumericArrayParamConfig(newConfig) &&
intentions?.numericArrayValues?.length
) {
newConfig.default = intentions.numericArrayValues[0];
// Assign numeric array value tokens via numeric array or hex string
const hexMetaString = intentions?.metaStrings?.find((meta) =>
meta.match(/^#([0-9a-f]{6})$/)
);
if (ParamGuards.isNumericArrayParamConfig(newConfig)) {
if (intentions?.numericArrayValues?.length) {
newConfig.default = intentions.numericArrayValues[0];
} else if (hexMetaString) {
newConfig.default = ColorConversions.hexToRgb(hexMetaString, true);
}
}
}

Expand Down Expand Up @@ -203,7 +208,7 @@ export default class ParamInference {
token.match(/^\[(\s*-?\d*\.{0,1}\d+\s*,\s*)+(\s*-?\d*\.{0,1}\d+\s*)\]$/)
);
const potentialMetaTokens = stringTokens.filter(
(token) => token.match(/^[a-zA-Z]+$/) && !token.match(/true|false/)
(token) => token.match(/(^[a-zA-Z]+$)|(^#([0-9a-f]{6})$)/) && !token.match(/true|false/)
);

// Return an object with adapted tokens, if any
Expand Down
6 changes: 4 additions & 2 deletions src/lib/base/Util/ColorConversions.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
export default class ColorConversions {
public static hexToRgb(hex: string): number[] {
public static hexToRgb(hex: string, unit = false): number[] {
const hexComponents = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (!hexComponents) throw new Error('rgbToHex: invalid hex string');
if (hexComponents.length !== 4)
throw new Error('rgbToHex: hex value must be in the format #rrggbb');
return [
const value255 = [
parseInt(hexComponents[1], 16),
parseInt(hexComponents[2], 16),
parseInt(hexComponents[3], 16)
];
if (unit) return value255.map((x) => x / 255);
else return value255;
}

public static rgbToHex(rgb: number[]): string {
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/ColorConversions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ describe('ColorConversions', () => {
expect(ColorConversions.hexToRgb('#000000')).toEqual([0, 0, 0]);
});

it('converts hex to rgb unit', () => {
expect(ColorConversions.hexToRgb('#ff00ff', true)).toEqual([1, 0, 1]);
expect(ColorConversions.hexToRgb('#00ff00', true)).toEqual([0, 1, 0]);
expect(ColorConversions.hexToRgb('#0000ff', true)).toEqual([0, 0, 1]);
expect(ColorConversions.hexToRgb('#ffffff', true)).toEqual([1, 1, 1]);
expect(ColorConversions.hexToRgb('#000000', true)).toEqual([0, 0, 0]);
});

it('converts rgb to hex', () => {
expect(ColorConversions.rgbToHex([255, 0, 255])).toBe('#ff00ff');
expect(ColorConversions.rgbToHex([0, 255, 0])).toBe('#00ff00');
Expand Down
38 changes: 38 additions & 0 deletions tests/unit/ParamInference.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,22 @@ describe('ParamInference.paramWithInference', () => {
expect(inference4.default).toEqual([74, 0.1, -3]);
});

it('assigns numeric array value from hex string', () => {
const inference1 = ParamInference.paramWithInference(
NumericArrayParamConfigDefaults,
InferenceMode.ShaderFile,
'23, origin, true, -4, #ff00ff'
) as NumericArrayParamConfig;
expect(inference1.default).toEqual([1, 0, 1]);

const inference2 = ParamInference.paramWithInference(
NumericArrayParamConfigDefaults,
InferenceMode.ShaderFile,
'23, origin, true, -4, #9933cc'
) as NumericArrayParamConfig;
expect(inference2.default).toEqual([0.6, 0.2, 0.8]);
});

it('assigns metadata (styles, etc)', () => {
const inference1 = ParamInference.paramWithInference(
NumberParamConfigDefaults,
Expand Down Expand Up @@ -591,4 +607,26 @@ describe('ParamInference.intentionsFrom', () => {
expect(intentions2.numericArrayValues.length).toBe(0);
expect(intentions2.metaStrings).toEqual(['test', 'step', 'testDeux']);
});

it('includes hex strings in metaStrings', () => {
const intentions1 = ParamInference.intentionsFrom('#dd00ff');
expect(intentions1.name).toBeUndefined();
expect(intentions1.range).toBeUndefined();
expect(intentions1.step).toBeUndefined();
expect(intentions1.numberValues.length).toBe(0);
expect(intentions1.booleanValues.length).toBe(0);
expect(intentions1.numericArrayValues.length).toBe(0);
expect(intentions1.metaStrings).toEqual(['#dd00ff']);

const intentions2 = ParamInference.intentionsFrom(
'#ff00ff, step, step 01, true, testDeux, false, 100.3 to 3'
);
expect(intentions2.name).toBeUndefined();
expect(intentions2.range).toEqual([100.3, 3]);
expect(intentions2.step).toEqual(1);
expect(intentions2.numberValues.length).toBe(0);
expect(intentions2.booleanValues).toEqual([true, false]);
expect(intentions2.numericArrayValues.length).toBe(0);
expect(intentions2.metaStrings).toEqual(['#ff00ff', 'step', 'testDeux']);
});
});

0 comments on commit 4dc9358

Please sign in to comment.