Skip to content

Commit

Permalink
Merge pull request #17 from shopware/feature/show-hide-objects
Browse files Browse the repository at this point in the history
Feature: Show and Hide objects
  • Loading branch information
ffrank913 authored Jun 17, 2024
2 parents 0bb605c + 6a1e8f6 commit 50778c4
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 64 deletions.
1 change: 1 addition & 0 deletions src/com/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type COMBaseEntity = {
id: string;
name: string;
entityType: 'pov' | 'light' | 'model';
visible: boolean;
}
export type COMPov = COMBaseEntity & {
position: Vector3Like;
Expand Down
21 changes: 14 additions & 7 deletions src/light/AmbientLight.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AmbientLight, Color } from 'three';
import { AmbientLight, Color, Object3D } from 'three';
import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';

/**
Expand All @@ -9,21 +9,28 @@ import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
* @module
*/

export default class DIVEAmbientLight extends AmbientLight {
export default class DIVEAmbientLight extends Object3D {
private _light: AmbientLight;

constructor() {
super(0xffffff, 1);
this.layers.mask = PRODUCT_LAYER_MASK;
super();

this.name = 'DIVEAmbientLight';

this._light = new AmbientLight(0xffffff, 1);
this._light.layers.mask = PRODUCT_LAYER_MASK;
this.add(this._light);
}

public SetColor(color: Color): void {
this.color = color;
this._light.color = color;
}

public SetIntensity(intensity: number): void {
this.intensity = intensity;
this._light.intensity = intensity;
}

public SetEnabled(enabled: boolean): void {
this.visible = enabled;
this._light.visible = enabled;
}
}
40 changes: 24 additions & 16 deletions src/light/PointLight.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PointLight, Color, SphereGeometry, MeshBasicMaterial, Mesh, FrontSide } from 'three';
import { PointLight, Color, SphereGeometry, MeshBasicMaterial, Mesh, FrontSide, Object3D } from 'three';
import DIVECommunication from '../com/Communication';
import { HELPER_LAYER_MASK, PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
import { DIVEMoveable } from '../interface/Moveable';
Expand All @@ -15,46 +15,54 @@ import type { TransformControls } from 'three/examples/jsm/Addons.js';
* @module
*/

export default class DIVEPointLight extends PointLight implements DIVESelectable, DIVEMoveable {
export default class DIVEPointLight extends Object3D implements DIVESelectable, DIVEMoveable {
public isMoveable: true = true;
public isSelectable: true = true;
public gizmo: TransformControls | null = null;

private light: PointLight;
private mesh: Mesh;

constructor() {
super(0xffffff, 1);
super();

this.name = 'DIVEPointLight';

this.light = new PointLight(0xffffff, 1);

this.layers.mask = PRODUCT_LAYER_MASK;
this.light.layers.mask = PRODUCT_LAYER_MASK;

this.castShadow = true;
this.shadow.mapSize.width = 512;
this.shadow.mapSize.height = 512;
this.light.castShadow = true;
this.light.shadow.mapSize.width = 512;
this.light.shadow.mapSize.height = 512;
this.add(this.light);

const geoSize = 0.1;

const geometry = new SphereGeometry(geoSize, geoSize * 320, geoSize * 320);

const material = new MeshBasicMaterial({ color: this.color, transparent: true, opacity: 0.8, side: FrontSide });
const material = new MeshBasicMaterial({ color: this.light.color, transparent: true, opacity: 0.8, side: FrontSide });

const mesh = new Mesh(geometry, material);
mesh.layers.mask = HELPER_LAYER_MASK;
this.mesh = new Mesh(geometry, material);
this.mesh.layers.mask = HELPER_LAYER_MASK;

this.add(mesh);
this.add(this.mesh);
}

public SetColor(color: Color): void {
this.color = color;
this.light.color = color;

((this.children[0] as Mesh).material as MeshBasicMaterial).color = color;
(this.mesh.material as MeshBasicMaterial).color = color;
}

public SetIntensity(intensity: number): void {
this.intensity = intensity;
this.light.intensity = intensity;

((this.children[0] as Mesh).material as MeshBasicMaterial).opacity = intensity > 0.8 ? 0.8 : intensity * 0.8;
(this.mesh.material as MeshBasicMaterial).opacity = intensity > 0.8 ? 0.8 : intensity * 0.8;
}

public SetEnabled(enabled: boolean): void {
this.visible = enabled;
this.light.visible = enabled;
}

public onMove(): void {
Expand Down
51 changes: 26 additions & 25 deletions src/light/SceneLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,51 @@ import { Color, DirectionalLight, HemisphereLight, Object3D } from "three";

export default class DIVESceneLight extends Object3D {

private hemiLight: HemisphereLight;
private dirLight: DirectionalLight;
private _hemiLight: HemisphereLight;
private _dirLight: DirectionalLight;

constructor() {
super();

this.name = "SceneLight";
this.name = 'DIVESceneLight';

this.hemiLight = new HemisphereLight(0xffffff, 0xffffff, 2);
this.hemiLight.layers.mask = PRODUCT_LAYER_MASK;
this.hemiLight.position.set(0, 50, 0);
this.add(this.hemiLight);
this._hemiLight = new HemisphereLight(0xffffff, 0xffffff, 2);
this._hemiLight.layers.mask = PRODUCT_LAYER_MASK;
this._hemiLight.position.set(0, 50, 0);
this.add(this._hemiLight);

this.dirLight = new DirectionalLight(0xffffff, 3);
this.dirLight.layers.mask = PRODUCT_LAYER_MASK;
this.dirLight.position.set(1, 1.75, 1);
this.dirLight.position.multiplyScalar(30);
this.dirLight.castShadow = true;
this._dirLight = new DirectionalLight(0xffffff, 3);
this._dirLight.layers.mask = PRODUCT_LAYER_MASK;
this._dirLight.position.set(1, 1.75, 1);
this._dirLight.position.multiplyScalar(30);
this._dirLight.castShadow = true;

this.dirLight.shadow.mapSize.width = 2048;
this.dirLight.shadow.mapSize.height = 2048;
this._dirLight.shadow.mapSize.width = 2048;
this._dirLight.shadow.mapSize.height = 2048;

const d = 5;

this.dirLight.shadow.camera.left = - d;
this.dirLight.shadow.camera.right = d;
this.dirLight.shadow.camera.top = d;
this.dirLight.shadow.camera.bottom = - d;
this._dirLight.shadow.camera.left = - d;
this._dirLight.shadow.camera.right = d;
this._dirLight.shadow.camera.top = d;
this._dirLight.shadow.camera.bottom = - d;

this.dirLight.shadow.camera.far = 3500;
this.add(this.dirLight);
this._dirLight.shadow.camera.far = 3500;
this.add(this._dirLight);
}

public SetColor(color: Color): void {
this.hemiLight.color = color;
this.dirLight.color = color;
this._hemiLight.color = color;
this._dirLight.color = color;
}

public SetIntensity(intensity: number): void {
this.hemiLight.intensity = intensity * 2;
this.dirLight.intensity = intensity * 3;
this._hemiLight.intensity = intensity * 2;
this._dirLight.intensity = intensity * 3;
}

public SetEnabled(enabled: boolean): void {
this.visible = enabled;
this._hemiLight.visible = enabled;
this._dirLight.visible = enabled;
}
}
16 changes: 12 additions & 4 deletions src/light/__test__/AmbientLight.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Color } from 'three';
import { AmbientLight, Color, Object3D } from 'three';
import DIVEAmbientLight from '../AmbientLight';

jest.mock('three', () => {
Expand All @@ -12,6 +12,14 @@ jest.mock('three', () => {
this.layers = {
mask: 0,
};
this.removeFromParent = jest.fn();
return this;
}),
Object3D: jest.fn(function () {
this.children = [];
this.add = (obj: Object3D) => {
this.children.push(obj);
};
return this;
}),
}
Expand All @@ -27,18 +35,18 @@ describe('dive/light/DIVEAmbientLight', () => {
it('should set intensity', () => {
const testLight = new DIVEAmbientLight();
testLight.SetIntensity(1.0);
expect(testLight.intensity).toBe(1.0);
expect((testLight.children[0] as AmbientLight).intensity).toBe(1.0);
});

it('should set color', () => {
const testLight = new DIVEAmbientLight();
testLight.SetColor({ test: true } as unknown as Color);
expect(testLight.color).toEqual({ test: true });
expect((testLight.children[0] as AmbientLight).color).toEqual({ test: true });
});

it('should set enabled', () => {
const testLight = new DIVEAmbientLight();
testLight.SetEnabled(false);
expect(testLight.visible).toBe(false);
expect(testLight.children[0].visible).toBe(false);
});
});
27 changes: 20 additions & 7 deletions src/light/__test__/PointLight.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import DIVEPointLight from '../PointLight.ts';
import DIVECommunication from '../../com/Communication.ts';
import { Color } from 'three';
import { Color, MeshBasicMaterial, Object3D, PointLight } from 'three';

const mockAdd = jest.fn();

Expand All @@ -10,6 +10,7 @@ jest.mock('three', () => {
return {};
}),
PointLight: jest.fn(function () {
this.visible = true;
this.color = {};
this.intensity = 0;
this.layers = {
Expand All @@ -31,19 +32,30 @@ jest.mock('three', () => {
color: {},
},
}];
this.userData = {};
return this;
}),
SphereGeometry: jest.fn(function () {
return this;
}),
MeshBasicMaterial: jest.fn(function () {
this.opacity = 1.0;
this.color = new Color();
return this;
}),
Mesh: jest.fn(function () {
this.layers = {
mask: 0,
};
this.visible = true;
this.material = new MeshBasicMaterial();
return this;
}),
Object3D: jest.fn(function () {
this.children = [];
this.add = (obj: Object3D) => {
this.children.push(obj);
};
this.userData = {};
return this;
}),
}
Expand All @@ -64,27 +76,28 @@ describe('dive/light/DIVEPointLight', () => {
const testLight = new DIVEPointLight();
testLight.userData.id = 'something';
expect(testLight).toBeDefined();
expect(mockAdd).toHaveBeenCalledTimes(1);
expect(testLight.userData.id).toBe('something');
expect(testLight.children).toHaveLength(2);
});

it('should set intensity', () => {
const testLight = new DIVEPointLight();
testLight.SetIntensity(1.0);
expect(testLight.intensity).toBe(1.0);
expect((testLight.children[0] as PointLight).intensity).toBe(1.0);
testLight.SetIntensity(0.6);
expect(testLight.intensity).toBe(0.6);
expect((testLight.children[0] as PointLight).intensity).toBe(0.6);
});

it('should set color', () => {
const testLight = new DIVEPointLight();
testLight.SetColor({ test: true } as unknown as Color);
expect(testLight.color).toEqual({ test: true });
expect((testLight.children[0] as PointLight).color).toEqual({ test: true });
});

it('should set enabled', () => {
const testLight = new DIVEPointLight();
testLight.SetEnabled(false);
expect(testLight.visible).toBe(false);
expect(testLight.children[0].visible).toBe(false);
});

it('should onMove', () => {
Expand Down
14 changes: 10 additions & 4 deletions src/light/__test__/SceneLight.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import DIVESceneLight from '../SceneLight';
import DIVECommunication from '../../com/Communication';
import { Color } from 'three';
import { Color, HemisphereLight as THREEHemisphereLight, DirectionalLight as THREEDirectionalLight, Object3D } from 'three';

jest.mock('../../com/Communication.ts', () => {
return {
Expand Down Expand Up @@ -57,10 +57,14 @@ jest.mock('three', () => {
return this;
}),
Object3D: jest.fn(function () {
this.add = mockAdd;
this.children = [];
this.add = (obj: Object3D) => {
this.children.push(obj);
};
return this;
}),
HemisphereLight: jest.fn(function () {
this.visible = true;
this.layers = {
mask: 0,
};
Expand All @@ -71,6 +75,7 @@ jest.mock('three', () => {
return this;
}),
DirectionalLight: jest.fn(function () {
this.visible = true;
this.layers = {
mask: 0,
};
Expand Down Expand Up @@ -100,7 +105,7 @@ describe('dive/light/DIVESceneLight', () => {
it('should instantiate', () => {
const testLight = new DIVESceneLight();
expect(testLight).toBeDefined();
expect(mockAdd).toHaveBeenCalledTimes(2);
expect(testLight.children).toHaveLength(2);
});

it('should set intensity', () => {
Expand All @@ -117,6 +122,7 @@ describe('dive/light/DIVESceneLight', () => {
it('should set enabled', () => {
const testLight = new DIVESceneLight();
testLight.SetEnabled(false);
expect(testLight.visible).toBe(false);
expect(testLight.children[0].visible).toBe(false);
expect(testLight.children[1].visible).toBe(false);
});
});
1 change: 1 addition & 0 deletions src/scene/root/lightroot/LightRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default class DIVELightRoot extends Object3D {
if (light.intensity !== undefined && light.intensity !== null) (sceneObject as (DIVEAmbientLight | DIVEPointLight)).SetIntensity(light.intensity);
if (light.enabled !== undefined && light.enabled !== null) (sceneObject as (DIVEAmbientLight | DIVEPointLight)).SetEnabled(light.enabled);
if (light.color !== undefined && light.color !== null) (sceneObject as (DIVEAmbientLight | DIVEPointLight)).SetColor(new Color(light.color));
if (light.visible !== undefined && light.visible !== null) (sceneObject as (DIVEAmbientLight | DIVEPointLight)).visible = light.visible;
}

public DeleteLight(light: Partial<COMLight>): void {
Expand Down
2 changes: 1 addition & 1 deletion src/scene/root/lightroot/__test__/LightRoot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('dive/scene/root/lightroot/DIVELightRoot', () => {

it('should update basic scene light', () => {
const lightRoot = new DIVELightRoot();
lightRoot.UpdateLight({ id: 'test_id', type: 'scene', name: 'test', position: undefined, enabled: true });
lightRoot.UpdateLight({ id: 'test_id', type: 'scene', name: 'test', position: undefined, enabled: true, visible: false });
expect(lightRoot.children).toHaveLength(1);
expect(lightRoot.children[0].userData.id).toBe('test_id');
});
Expand Down
Loading

0 comments on commit 50778c4

Please sign in to comment.