Skip to content

Commit c81584c

Browse files
implemented generic materials and textures that map to specific game engine implementations.
1 parent 2aa4a54 commit c81584c

17 files changed

Lines changed: 3375 additions & 847 deletions

File tree

packages/dev/babylonjs/lib/api/__mocks__/babylonjs.mock.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export class MockColor3 {
107107
clone() {
108108
return new MockColor3(this.r, this.g, this.b);
109109
}
110+
111+
scale(scale: number) {
112+
return new MockColor3(this.r * scale, this.g * scale, this.b * scale);
113+
}
110114
}
111115

112116
export class MockColor4 {
@@ -226,10 +230,58 @@ export class MockMaterial {
226230
}
227231
}
228232

233+
export class MockTexture {
234+
name: string;
235+
url: string;
236+
wrapU = 1; // WRAP_ADDRESSMODE
237+
wrapV = 1; // WRAP_ADDRESSMODE
238+
uScale = 1;
239+
vScale = 1;
240+
uOffset = 0;
241+
vOffset = 0;
242+
uAng = 0;
243+
vAng = 0;
244+
wAng = 0;
245+
hasAlpha = false;
246+
getAlphaFromRGB = false;
247+
level = 1;
248+
coordinatesIndex = 0;
249+
isBlocking = true;
250+
251+
static NEAREST_SAMPLINGMODE = 1;
252+
static BILINEAR_SAMPLINGMODE = 2;
253+
static TRILINEAR_SAMPLINGMODE = 3;
254+
static WRAP_ADDRESSMODE = 1;
255+
static CLAMP_ADDRESSMODE = 0;
256+
static MIRROR_ADDRESSMODE = 2;
257+
258+
constructor(url: string, scene?: MockScene, noMipmap?: boolean, invertY?: boolean, samplingMode?: number) {
259+
this.url = url;
260+
this.name = url;
261+
}
262+
263+
dispose() {
264+
// Mock dispose
265+
}
266+
}
267+
229268
export class MockPBRMetallicRoughnessMaterial extends MockMaterial {
230269
baseColor: MockColor3 = new MockColor3(1, 1, 1);
231270
metallic = 1.0;
232271
roughness = 0.6;
272+
emissiveColor: MockColor3 = new MockColor3(0, 0, 0);
273+
baseTexture: any = null;
274+
metallicRoughnessTexture: any = null;
275+
normalTexture: any = null;
276+
emissiveTexture: any = null;
277+
occlusionTexture: any = null;
278+
alphaCutOff = 0.5;
279+
transparencyMode: number | null = null;
280+
disableLighting = false;
281+
282+
static PBRMATERIAL_OPAQUE = 0;
283+
static PBRMATERIAL_ALPHATEST = 1;
284+
static PBRMATERIAL_ALPHABLEND = 2;
233285
}
234286

235287
export class MockStandardMaterial extends MockMaterial {
@@ -451,7 +503,9 @@ export function createBabylonJSMock() {
451503
Matrix: MockMatrix,
452504
VertexData: MockVertexData,
453505
Material: MockMaterial,
506+
Texture: MockTexture,
454507
PBRMetallicRoughnessMaterial: MockPBRMetallicRoughnessMaterial,
508+
PBRMaterial: MockPBRMetallicRoughnessMaterial,
455509
StandardMaterial: MockStandardMaterial,
456510
Mesh: MockMesh,
457511
InstancedMesh: MockInstancedMesh,
@@ -468,11 +522,6 @@ export function createBabylonJSMock() {
468522
COLOR_MODE_SET: 0,
469523
COLOR_MODE_ADD: 1,
470524
COLOR_MODE_MULTIPLY: 2
471-
},
472-
Texture: {
473-
NEAREST_SAMPLINGMODE: 1,
474-
BILINEAR_SAMPLINGMODE: 2,
475-
TRILINEAR_SAMPLINGMODE: 3
476525
}
477526
};
478527
}

packages/dev/babylonjs/lib/api/bitbybit/draw.test.ts

Lines changed: 177 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
jest.mock("@babylonjs/core", () => {
3+
const { createBabylonJSMock } = jest.requireActual("../__mocks__/babylonjs.mock");
4+
return createBabylonJSMock();
5+
});
6+
7+
jest.mock("@babylonjs/materials");
8+
29
import * as BABYLON from "@babylonjs/core";
310
import { GridMaterial } from "@babylonjs/materials";
411
import { Draw } from "./draw";
@@ -9,9 +16,6 @@ import { Context } from "../context";
916
import * as Inputs from "../inputs";
1017
import { MockScene, MockMesh } from "../__mocks__/babylonjs.mock";
1118

12-
jest.mock("@babylonjs/core");
13-
jest.mock("@babylonjs/materials");
14-
1519
// Type definitions for Draw private methods (for type-safe testing)
1620
type DrawPrivateMethods = {
1721
// Detector methods
@@ -2459,4 +2463,174 @@ describe("Draw unit tests", () => {
24592463
}));
24602464
});
24612465
});
2466+
2467+
describe("createTexture", () => {
2468+
it("should create texture with default properties", () => {
2469+
// Arrange
2470+
const inputs = new Inputs.Draw.GenericTextureDto();
2471+
inputs.url = "test.png";
2472+
2473+
// Act
2474+
const result = draw.createTexture(inputs);
2475+
2476+
// Assert
2477+
expect(result).toBeInstanceOf(BABYLON.Texture);
2478+
expect(result.name).toBe(inputs.name);
2479+
expect(result.uOffset).toBe(0);
2480+
expect(result.vOffset).toBe(0);
2481+
expect(result.uScale).toBe(1);
2482+
expect(result.vScale).toBe(1);
2483+
expect(result.uAng).toBe(0);
2484+
expect(result.vAng).toBe(0);
2485+
expect(result.wAng).toBe(0);
2486+
expect(result.level).toBe(1);
2487+
});
2488+
2489+
it("should create texture with custom properties", () => {
2490+
// Arrange
2491+
const inputs = new Inputs.Draw.GenericTextureDto();
2492+
inputs.url = "custom.jpg";
2493+
inputs.name = "CustomTexture";
2494+
inputs.uOffset = 0.5;
2495+
inputs.vOffset = 0.25;
2496+
inputs.uScale = 2;
2497+
inputs.vScale = 3;
2498+
inputs.wAng = 180;
2499+
2500+
// Act
2501+
const result = draw.createTexture(inputs);
2502+
2503+
// Assert
2504+
expect(result).toBeInstanceOf(BABYLON.Texture);
2505+
expect(result.name).toBe("CustomTexture");
2506+
expect(result.uOffset).toBe(0.5);
2507+
expect(result.vOffset).toBe(0.25);
2508+
expect(result.uScale).toBe(2);
2509+
expect(result.vScale).toBe(3);
2510+
expect(result.wAng).toBe(180);
2511+
});
2512+
});
2513+
2514+
describe("createPBRMaterial", () => {
2515+
it("should create PBR material with default properties", () => {
2516+
// Arrange
2517+
const inputs = new Inputs.Draw.GenericPBRMaterialDto();
2518+
2519+
// Act
2520+
const result = draw.createPBRMaterial(inputs);
2521+
2522+
// Assert
2523+
expect(result).toBeInstanceOf(BABYLON.PBRMetallicRoughnessMaterial);
2524+
expect(result.name).toBe(inputs.name);
2525+
expect(result.metallic).toBe(0.5);
2526+
expect(result.roughness).toBe(0.5);
2527+
});
2528+
2529+
it("should create PBR material with custom properties", () => {
2530+
// Arrange
2531+
const inputs = new Inputs.Draw.GenericPBRMaterialDto();
2532+
inputs.name = "CustomMaterial";
2533+
inputs.baseColor = "#ff0000";
2534+
inputs.metallic = 0.5;
2535+
inputs.roughness = 0.3;
2536+
inputs.alpha = 0.8;
2537+
inputs.emissiveColor = "#00ff00";
2538+
inputs.emissiveIntensity = 2;
2539+
inputs.alphaCutoff = 0.5;
2540+
inputs.doubleSided = true;
2541+
inputs.unlit = true;
2542+
2543+
// Act
2544+
const result = draw.createPBRMaterial(inputs);
2545+
2546+
// Assert
2547+
expect(result).toBeInstanceOf(BABYLON.PBRMetallicRoughnessMaterial);
2548+
expect(result.name).toBe("CustomMaterial");
2549+
expect(result.metallic).toBe(0.5);
2550+
expect(result.roughness).toBe(0.3);
2551+
expect(result.alpha).toBe(0.8);
2552+
expect(result.alphaCutOff).toBe(0.5);
2553+
expect(result.doubleSided).toBe(true);
2554+
expect(result.disableLighting).toBe(true);
2555+
});
2556+
2557+
it("should apply alpha modes correctly", () => {
2558+
// Arrange & Act & Assert - opaque
2559+
const opaqueInputs = new Inputs.Draw.GenericPBRMaterialDto();
2560+
opaqueInputs.alphaMode = Inputs.Draw.alphaModeEnum.opaque;
2561+
const opaqueMat = draw.createPBRMaterial(opaqueInputs);
2562+
expect(opaqueMat.transparencyMode).toBe(BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE);
2563+
2564+
// Arrange & Act & Assert - mask
2565+
const maskInputs = new Inputs.Draw.GenericPBRMaterialDto();
2566+
maskInputs.alphaMode = Inputs.Draw.alphaModeEnum.mask;
2567+
const maskMat = draw.createPBRMaterial(maskInputs);
2568+
expect(maskMat.transparencyMode).toBe(BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST);
2569+
2570+
// Arrange & Act & Assert - blend
2571+
const blendInputs = new Inputs.Draw.GenericPBRMaterialDto();
2572+
blendInputs.alphaMode = Inputs.Draw.alphaModeEnum.blend;
2573+
const blendMat = draw.createPBRMaterial(blendInputs);
2574+
expect(blendMat.transparencyMode).toBe(BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND);
2575+
});
2576+
2577+
it("should apply textures when provided", () => {
2578+
// Arrange
2579+
const mockTexture = {} as BABYLON.BaseTexture;
2580+
const inputs = new Inputs.Draw.GenericPBRMaterialDto();
2581+
inputs.baseColorTexture = mockTexture;
2582+
inputs.metallicRoughnessTexture = mockTexture;
2583+
inputs.normalTexture = mockTexture;
2584+
inputs.emissiveTexture = mockTexture;
2585+
inputs.occlusionTexture = mockTexture;
2586+
2587+
// Act
2588+
const result = draw.createPBRMaterial(inputs);
2589+
2590+
// Assert
2591+
expect(result.baseTexture).toBe(mockTexture);
2592+
expect(result.metallicRoughnessTexture).toBe(mockTexture);
2593+
expect(result.normalTexture).toBe(mockTexture);
2594+
expect(result.emissiveTexture).toBe(mockTexture);
2595+
expect(result.occlusionTexture).toBe(mockTexture);
2596+
});
2597+
});
2598+
2599+
describe("getSamplingMode", () => {
2600+
it("should return NEAREST_SAMPLINGMODE for nearestSamplingMode", () => {
2601+
// Arrange
2602+
const mode = Inputs.Draw.samplingModeEnum.nearest;
2603+
2604+
// Act
2605+
const result = (draw as any).getSamplingMode(mode);
2606+
2607+
// Assert
2608+
expect(result).toBe(BABYLON.Texture.NEAREST_SAMPLINGMODE);
2609+
});
2610+
2611+
it("should return BILINEAR_SAMPLINGMODE for bilinearSamplingMode", () => {
2612+
// Arrange
2613+
const mode = Inputs.Draw.samplingModeEnum.bilinear;
2614+
2615+
// Act
2616+
const result = (draw as any).getSamplingMode(mode);
2617+
2618+
// Assert
2619+
expect(result).toBe(BABYLON.Texture.BILINEAR_SAMPLINGMODE);
2620+
});
2621+
2622+
it("should return TRILINEAR_SAMPLINGMODE for trilinearSamplingMode", () => {
2623+
// Arrange
2624+
const mode = Inputs.Draw.samplingModeEnum.trilinear;
2625+
2626+
// Act
2627+
const result = (draw as any).getSamplingMode(mode);
2628+
2629+
// Assert
2630+
expect(result).toBe(BABYLON.Texture.TRILINEAR_SAMPLINGMODE);
2631+
});
2632+
2633+
2634+
});
2635+
24622636
});

0 commit comments

Comments
 (0)