Skip to content

Commit 2c1948c

Browse files
authored
Merge branch 'main' into chore/unplugin-dep-upgrade
2 parents 530761f + 2d1d95a commit 2c1948c

File tree

3 files changed

+44
-66
lines changed

3 files changed

+44
-66
lines changed

packages/typegpu/src/data/vectorOps.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -746,23 +746,6 @@ export const VectorOps = {
746746
vec4u: binaryComponentWise4u(divInteger),
747747
} as Record<VecKind, <T extends vBase>(a: T, b: T) => T>,
748748

749-
divMixed: {
750-
vec2f: (a: wgsl.v2f, b: number) => unary2f((e) => e / b)(a),
751-
vec2h: (a: wgsl.v2h, b: number) => unary2h((e) => e / b)(a),
752-
vec2i: (a: wgsl.v2i, b: number) => unary2i((e) => divInteger(e, b))(a),
753-
vec2u: (a: wgsl.v2u, b: number) => unary2u((e) => divInteger(e, b))(a),
754-
755-
vec3f: (a: wgsl.v3f, b: number) => unary3f((e) => e / b)(a),
756-
vec3h: (a: wgsl.v3h, b: number) => unary3h((e) => e / b)(a),
757-
vec3i: (a: wgsl.v3i, b: number) => unary3i((e) => divInteger(e, b))(a),
758-
vec3u: (a: wgsl.v3u, b: number) => unary3u((e) => divInteger(e, b))(a),
759-
760-
vec4f: (a: wgsl.v4f, b: number) => unary4f((e) => e / b)(a),
761-
vec4h: (a: wgsl.v4h, b: number) => unary4h((e) => e / b)(a),
762-
vec4i: (a: wgsl.v4i, b: number) => unary4i((e) => divInteger(e, b))(a),
763-
vec4u: (a: wgsl.v4u, b: number) => unary4u((e) => divInteger(e, b))(a),
764-
} as Record<VecKind, <T extends vBase>(lhs: T, rhs: number) => T>,
765-
766749
dot: {
767750
vec2f: dotVec2,
768751
vec2h: dotVec2,

packages/typegpu/src/std/numeric.ts

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { vecTypeToConstructor } from '../data/vector.ts';
2-
import { type AnyData, snip, type Snippet } from '../data/dataTypes.ts';
2+
import {
3+
type AnyData,
4+
snip,
5+
type Snippet,
6+
type TgpuDualFn,
7+
} from '../data/dataTypes.ts';
38
import { smoothstepScalar } from '../data/numberOps.ts';
49
import { f32 } from '../data/numeric.ts';
510
import { VectorOps } from '../data/vectorOps.ts';
@@ -195,37 +200,32 @@ export const mul = createDualImpl(
195200
'mul',
196201
);
197202

198-
function cpuDiv(lhs: number, rhs: number): number; // default js division
199-
function cpuDiv<MV extends NumVec>(lhs: number, rhs: MV): MV; // scale
200-
function cpuDiv<MV extends NumVec>(lhs: MV, rhs: number): MV; // scale
201-
function cpuDiv<V extends NumVec>(lhs: V, rhs: V): V; // component-wise division
202-
function cpuDiv<
203-
// union overload
204-
Lhs extends number | NumVec,
205-
Rhs extends (Lhs extends number ? number | NumVec
206-
: Lhs extends NumVec ? number | Lhs
207-
: never),
208-
>(lhs: Lhs, rhs: Rhs): Lhs | Rhs;
209-
function cpuDiv(lhs: number | NumVec, rhs: number | NumVec) {
210-
if (typeof lhs === 'number' && typeof rhs === 'number') {
211-
return (lhs / rhs);
212-
}
213-
if (typeof lhs === 'number' && isVecInstance(rhs)) {
214-
return VectorOps.divMixed[rhs.kind](rhs, lhs);
215-
}
216-
if (isVecInstance(lhs) && typeof rhs === 'number') {
217-
return VectorOps.divMixed[lhs.kind](lhs, rhs);
218-
}
219-
if (isVecInstance(lhs) && isVecInstance(rhs)) {
220-
return VectorOps.div[lhs.kind](lhs, rhs);
221-
}
222-
223-
throw new Error('Div called with invalid arguments.');
224-
}
203+
type DivOverload = {
204+
(lhs: number, rhs: number): number; // default js division
205+
<T extends NumVec | number>(lhs: T, rhs: T): T; // component-wise division
206+
<T extends NumVec | number>(lhs: number, rhs: T): T; // mixed division
207+
<T extends NumVec | number>(lhs: T, rhs: number): T; // mixed division
208+
};
225209

226-
export const div = createDualImpl(
210+
export const div: TgpuDualFn<DivOverload> = createDualImpl(
227211
// CPU implementation
228-
cpuDiv,
212+
<T extends NumVec | number>(lhs: T, rhs: T): T => {
213+
if (typeof lhs === 'number' && typeof rhs === 'number') {
214+
return (lhs / rhs) as T;
215+
}
216+
if (typeof lhs === 'number' && isVecInstance(rhs)) {
217+
const schema = vecTypeToConstructor[rhs.kind];
218+
return VectorOps.div[rhs.kind](schema(lhs), rhs) as T;
219+
}
220+
if (isVecInstance(lhs) && typeof rhs === 'number') {
221+
const schema = vecTypeToConstructor[lhs.kind];
222+
return VectorOps.div[lhs.kind](lhs, schema(rhs)) as T;
223+
}
224+
if (isVecInstance(lhs) && isVecInstance(rhs)) {
225+
return VectorOps.div[lhs.kind](lhs, rhs) as T;
226+
}
227+
throw new Error('Div called with invalid arguments.');
228+
},
229229
// GPU implementation
230230
(lhs, rhs) => {
231231
if (isSnippetNumeric(lhs) && isSnippetNumeric(rhs)) {

packages/typegpu/tests/std/numeric/div.test.ts

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ describe('div', () => {
2929
expect(isCloseTo(div(vec3f(1, 2, 3), 3), vec3f(0.333, 0.666, 1))).toBe(
3030
true,
3131
);
32-
expect(isCloseTo(div(vec4f(1, 2, 3, 4), 4), vec4f(0.25, 0.5, 0.75, 1)))
33-
.toBe(true);
32+
expect(
33+
isCloseTo(div(vec4f(1, 2, 3, 4), 4), vec4f(0.25, 0.5, 0.75, 1)),
34+
).toBe(true);
3435
});
3536

3637
it('computes quotient of vecNi and a number', () => {
@@ -40,41 +41,35 @@ describe('div', () => {
4041
});
4142

4243
it('computes quotient of a number and vecNf', () => {
43-
expect(isCloseTo(div(2, vec2f(1, 2)), vec2f(0.5, 1))).toBe(true);
44-
expect(isCloseTo(div(3, vec3f(1, 2, 3)), vec3f(0.333, 0.666, 1))).toBe(
44+
expect(isCloseTo(div(2, vec2f(1, 2)), vec2f(2, 1))).toBe(true);
45+
expect(isCloseTo(div(3, vec3f(1, 2, 3)), vec3f(3, 1.5, 1))).toBe(
4546
true,
4647
);
47-
expect(isCloseTo(div(4, vec4f(1, 2, 3, 4)), vec4f(0.25, 0.5, 0.75, 1)))
48-
.toBe(true);
48+
expect(
49+
isCloseTo(div(4, vec4f(1, 2, 3, 4)), vec4f(4, 2, 1.33, 1)),
50+
).toBe(true);
4951
});
5052

5153
it('computes quotient of a number and vecNi', () => {
52-
expect(div(1, vec2i(1, 2))).toStrictEqual(vec2i(1, 2));
53-
expect(div(2, vec3i(1, 2, 3))).toStrictEqual(vec3i(0, 1, 1));
54-
expect(div(3, vec4i(5, 6, 7, 8))).toStrictEqual(vec4i(1, 2, 2, 2));
54+
expect(div(1, vec2i(1, 2))).toStrictEqual(vec2i(1, 0));
55+
expect(div(2, vec3i(1, 2, 3))).toStrictEqual(vec3i(2, 1, 0));
56+
expect(div(3, vec4i(5, 6, 7, 8))).toStrictEqual(vec4i());
5557
});
5658

5759
it('computes quotient of vecNh and vecNh', () => {
58-
expect(isCloseTo(div(vec2h(1, 2), vec2h(4)), vec2h(0.25, 0.5))).toBe(
59-
true,
60-
);
60+
expect(isCloseTo(div(vec2h(1, 2), vec2h(4)), vec2h(0.25, 0.5))).toBe(true);
6161
expect(
6262
isCloseTo(div(vec3h(1, 2, 3), vec3h(3)), vec3h(0.333, 0.666, 1)),
6363
).toBe(true);
6464
expect(
65-
isCloseTo(
66-
div(vec4h(1.5, 2, 3, 4), vec4h(2)),
67-
vec4h(0.75, 1, 1.5, 2),
68-
),
65+
isCloseTo(div(vec4h(1.5, 2, 3, 4), vec4h(2)), vec4h(0.75, 1, 1.5, 2)),
6966
).toBe(true);
7067
});
7168

7269
it('computes quotient of vecNu and vecNu', () => {
7370
expect(div(vec2u(1, 2), vec2u(2))).toStrictEqual(vec2u(0, 1));
7471
expect(div(vec3u(5, 6, 7), vec3u(3))).toStrictEqual(vec3u(1, 2, 2));
75-
expect(div(vec4u(1, 2, 8, 9), vec4u(4))).toStrictEqual(
76-
vec4u(0, 0, 2, 2),
77-
);
72+
expect(div(vec4u(1, 2, 8, 9), vec4u(4))).toStrictEqual(vec4u(0, 0, 2, 2));
7873
});
7974

8075
it('handles division by 0', () => {

0 commit comments

Comments
 (0)