|
@@ -7,12 +7,19 @@ import { UtilityLayerRenderer } from "../Rendering/utilityLayerRenderer";
|
|
|
|
|
|
import { StandardMaterial } from '../Materials/standardMaterial';
|
|
|
import { Light } from '../Lights/light';
|
|
|
+import { Scene } from '../scene';
|
|
|
+import { HemisphericLight } from '../Lights/hemisphericLight';
|
|
|
+import { DirectionalLight } from '../Lights/directionalLight';
|
|
|
+import { SphereBuilder } from '../Meshes/Builders/sphereBuilder';
|
|
|
+import { HemisphereBuilder } from '../Meshes/Builders/hemisphereBuilder';
|
|
|
+import { SpotLight } from '../Lights/spotLight';
|
|
|
|
|
|
/**
|
|
|
* Gizmo that enables viewing a light
|
|
|
*/
|
|
|
export class LightGizmo extends Gizmo {
|
|
|
- private _box: Mesh;
|
|
|
+ private _lightMesh: Mesh;
|
|
|
+ private _material: StandardMaterial;
|
|
|
|
|
|
/**
|
|
|
* Creates a LightGizmo
|
|
@@ -20,13 +27,10 @@ export class LightGizmo extends Gizmo {
|
|
|
*/
|
|
|
constructor(gizmoLayer?: UtilityLayerRenderer) {
|
|
|
super(gizmoLayer);
|
|
|
- this._box = Mesh.CreateCylinder("light", 0.02, 0, 0.02, 16, 1, this.gizmoLayer.utilityLayerScene);
|
|
|
- this._box.rotation.x = -Math.PI / 2;
|
|
|
- this._box.bakeCurrentTransformIntoVertices();
|
|
|
- this._box.material = new StandardMaterial("", this.gizmoLayer.utilityLayerScene);
|
|
|
- (this._box.material as StandardMaterial).emissiveColor = Color3.Yellow();
|
|
|
- this._rootMesh.addChild(this._box);
|
|
|
this.attachedMesh = new AbstractMesh("", this.gizmoLayer.utilityLayerScene);
|
|
|
+ this._material = new StandardMaterial("light", this.gizmoLayer.originalScene);
|
|
|
+ this._material.diffuseColor = new Color3(0.5, 0.5, 0.5);
|
|
|
+ this._material.specularColor = new Color3(0.1, 0.1, 0.1);
|
|
|
}
|
|
|
private _light: Nullable<Light> = null;
|
|
|
|
|
@@ -35,11 +39,37 @@ export class LightGizmo extends Gizmo {
|
|
|
*/
|
|
|
public set light(light: Nullable<Light>) {
|
|
|
this._light = light;
|
|
|
- if ((light as any).position) {
|
|
|
- this.attachedMesh!.position.copyFrom((light as any).position);
|
|
|
- }
|
|
|
- if ((light as any).direction) {
|
|
|
- this._box.setDirection((light as any).direction);
|
|
|
+ if (light) {
|
|
|
+ // Create the mesh for the given light type
|
|
|
+ if (this._lightMesh) {
|
|
|
+ this._lightMesh.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (light instanceof HemisphericLight) {
|
|
|
+ this._lightMesh = LightGizmo._CreateHemisphericLightMesh(this.gizmoLayer.utilityLayerScene);
|
|
|
+ }else if (light instanceof DirectionalLight) {
|
|
|
+ this._lightMesh = LightGizmo._CreateDirectionalLightMesh(this.gizmoLayer.utilityLayerScene);
|
|
|
+ }else if (light instanceof SpotLight) {
|
|
|
+ this._lightMesh = LightGizmo._CreateSpotLightMesh(this.gizmoLayer.utilityLayerScene);
|
|
|
+ }else {
|
|
|
+ this._lightMesh = LightGizmo._CreatePointLightMesh(this.gizmoLayer.utilityLayerScene);
|
|
|
+ }
|
|
|
+ this._lightMesh.getChildMeshes(false).forEach((m) => {
|
|
|
+ m.material = this._material;
|
|
|
+ });
|
|
|
+ this._lightMesh.parent = this._rootMesh;
|
|
|
+
|
|
|
+ // Add lighting to the light gizmo
|
|
|
+ var gizmoLight = this.gizmoLayer._getSharedGizmoLight();
|
|
|
+ gizmoLight.includedOnlyMeshes = gizmoLight.includedOnlyMeshes.concat(this._lightMesh.getChildMeshes(false));
|
|
|
+
|
|
|
+ // Get update position and direction if the light has it
|
|
|
+ if ((light as any).position) {
|
|
|
+ this.attachedMesh!.position.copyFrom((light as any).position);
|
|
|
+ }
|
|
|
+ if ((light as any).direction) {
|
|
|
+ this._lightMesh.setDirection((light as any).direction);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
public get light() {
|
|
@@ -59,12 +89,160 @@ export class LightGizmo extends Gizmo {
|
|
|
(this._light as any).position.copyFrom(this.attachedMesh!.position);
|
|
|
}
|
|
|
if ((this._light as any).direction) {
|
|
|
- (this._light as any).direction.copyFrom(this._box.forward);
|
|
|
+ (this._light as any).direction.copyFrom(this._lightMesh.forward);
|
|
|
}
|
|
|
if (!this._light.isEnabled()) {
|
|
|
- (this._box.material as StandardMaterial).emissiveColor.set(0, 0, 0);
|
|
|
+ this._material.diffuseColor.set(0, 0, 0);
|
|
|
} else {
|
|
|
- (this._box.material as StandardMaterial).emissiveColor.set(1, 1, 1);
|
|
|
+ this._material.diffuseColor.set(this._light.diffuse.r / 3, this._light.diffuse.g / 3, this._light.diffuse.b / 3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Static helper methods
|
|
|
+ private static _Scale = 0.007;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates the lines for a light mesh
|
|
|
+ */
|
|
|
+ private static _createLightLines = (levels: number, scene: Scene) => {
|
|
|
+ var distFromSphere = 1.2;
|
|
|
+
|
|
|
+ var root = new Mesh("root", scene);
|
|
|
+ root.rotation.x = Math.PI / 2;
|
|
|
+
|
|
|
+ // Create the top line, this will be cloned for all other lines
|
|
|
+ var linePivot = new Mesh("linePivot", scene);
|
|
|
+ linePivot.parent = root;
|
|
|
+ var line = Mesh.CreateCylinder("line", 2, 0.2, 0.3, 6, 1, scene);
|
|
|
+ line.position.y = line.scaling.y / 2 + distFromSphere;
|
|
|
+ line.parent = linePivot;
|
|
|
+
|
|
|
+ if (levels < 2) {
|
|
|
+ return linePivot;
|
|
|
}
|
|
|
+ for (var i = 0; i < 4; i++) {
|
|
|
+ var l = linePivot.clone("lineParentClone");
|
|
|
+ l.rotation.z = Math.PI / 4;
|
|
|
+ l.rotation.y = (Math.PI / 2) + (Math.PI / 2 * i);
|
|
|
+
|
|
|
+ l.getChildMeshes()[0].scaling.y = 0.5;
|
|
|
+ l.getChildMeshes()[0].scaling.x = l.getChildMeshes()[0].scaling.z = 0.8;
|
|
|
+ l.getChildMeshes()[0].position.y = l.getChildMeshes()[0].scaling.y / 2 + distFromSphere;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (levels < 3) {
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+ for (var i = 0; i < 4; i++) {
|
|
|
+ var l = linePivot.clone("linePivotClone");
|
|
|
+ l.rotation.z = Math.PI / 2;
|
|
|
+ l.rotation.y = (Math.PI / 2 * i);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (levels < 4) {
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+ for (var i = 0; i < 4; i++) {
|
|
|
+ var l = linePivot.clone("linePivotClone");
|
|
|
+ l.rotation.z = Math.PI + (Math.PI / 4);
|
|
|
+ l.rotation.y = (Math.PI / 2) + (Math.PI / 2 * i);
|
|
|
+
|
|
|
+ l.getChildMeshes()[0].scaling.y = 0.5;
|
|
|
+ l.getChildMeshes()[0].scaling.x = l.getChildMeshes()[0].scaling.z = 0.8;
|
|
|
+ l.getChildMeshes()[0].position.y = l.getChildMeshes()[0].scaling.y / 2 + distFromSphere;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (levels < 5) {
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+ var l = linePivot.clone("linePivotClone");
|
|
|
+ l.rotation.z = Math.PI;
|
|
|
+
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static _CreateHemisphericLightMesh(scene: Scene) {
|
|
|
+ var root = new Mesh("hemisphereLight", scene);
|
|
|
+ var hemisphere = HemisphereBuilder.CreateHemisphere(root.name, {segments: 10, diameter: 1}, scene);
|
|
|
+ hemisphere.position.z = -0.15;
|
|
|
+ hemisphere.rotation.x = Math.PI / 2;
|
|
|
+ hemisphere.parent = root;
|
|
|
+
|
|
|
+ var lines = this._createLightLines(3, scene);
|
|
|
+ lines.parent = root;
|
|
|
+ lines.position.z - 0.15;
|
|
|
+
|
|
|
+ root.scaling.scaleInPlace(LightGizmo._Scale);
|
|
|
+ root.rotation.x = Math.PI / 2;
|
|
|
+
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static _CreatePointLightMesh(scene: Scene) {
|
|
|
+ var root = new Mesh("pointLight", scene);
|
|
|
+ var sphere = SphereBuilder.CreateSphere(root.name, {segments: 10, diameter: 1}, scene);
|
|
|
+ sphere.rotation.x = Math.PI / 2;
|
|
|
+ sphere.parent = root;
|
|
|
+
|
|
|
+ var lines = this._createLightLines(5, scene);
|
|
|
+ lines.parent = root;
|
|
|
+ root.scaling.scaleInPlace(LightGizmo._Scale);
|
|
|
+ root.rotation.x = Math.PI / 2;
|
|
|
+
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static _CreateSpotLightMesh(scene: Scene) {
|
|
|
+ var root = new Mesh("spotLight", scene);
|
|
|
+ var sphere = SphereBuilder.CreateSphere(root.name, {segments: 10, diameter: 1}, scene);
|
|
|
+ sphere.parent = root;
|
|
|
+
|
|
|
+ var hemisphere = HemisphereBuilder.CreateHemisphere(root.name, {segments: 10, diameter: 2}, scene);
|
|
|
+ hemisphere.parent = root;
|
|
|
+ hemisphere.rotation.x = -Math.PI / 2;
|
|
|
+
|
|
|
+ var lines = this._createLightLines(2, scene);
|
|
|
+ lines.parent = root;
|
|
|
+ root.scaling.scaleInPlace(LightGizmo._Scale);
|
|
|
+ root.rotation.x = Math.PI / 2;
|
|
|
+
|
|
|
+ return root;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static _CreateDirectionalLightMesh(scene: Scene) {
|
|
|
+ var root = new Mesh("directionalLight", scene);
|
|
|
+
|
|
|
+ var mesh = new Mesh(root.name, scene);
|
|
|
+ mesh.parent = root;
|
|
|
+ var sphere = SphereBuilder.CreateSphere(root.name, {diameter: 1.2, segments: 10}, scene);
|
|
|
+ sphere.parent = mesh;
|
|
|
+
|
|
|
+ var line = Mesh.CreateCylinder(root.name, 6, 0.3, 0.3, 6, 1, scene);
|
|
|
+ line.parent = mesh;
|
|
|
+
|
|
|
+ var left = line.clone(root.name);
|
|
|
+ left.scaling.y = 0.5;
|
|
|
+ left.position.x += 1.25;
|
|
|
+
|
|
|
+ var right = line.clone(root.name);
|
|
|
+ right.scaling.y = 0.5;
|
|
|
+ right.position.x += -1.25;
|
|
|
+
|
|
|
+ var arrowHead = Mesh.CreateCylinder(root.name, 1, 0, 0.6, 6, 1, scene);
|
|
|
+ arrowHead.position.y += 3;
|
|
|
+ arrowHead.parent = mesh;
|
|
|
+
|
|
|
+ var left = arrowHead.clone(root.name);
|
|
|
+ left.position.y = 1.5;
|
|
|
+ left.position.x += 1.25;
|
|
|
+
|
|
|
+ var right = arrowHead.clone(root.name);
|
|
|
+ right.position.y = 1.5;
|
|
|
+ right.position.x += -1.25;
|
|
|
+
|
|
|
+ mesh.scaling.scaleInPlace(LightGizmo._Scale);
|
|
|
+ mesh.rotation.z = Math.PI / 2;
|
|
|
+ mesh.rotation.y = Math.PI / 2;
|
|
|
+ return root;
|
|
|
}
|
|
|
}
|