mage-engine 3.24.1 → 3.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/mage.js +1446 -541
  2. package/package.json +1 -1
package/dist/mage.js CHANGED
@@ -54722,7 +54722,9 @@ let Keyboard = /*#__PURE__*/function (_EventDispatcher) {
54722
54722
  SUBTYPES: {
54723
54723
  DEFAULT: "SCENERY.SUBTYPE.DEFAULT",
54724
54724
  SKY: "SCENERY.SUBTYPE.SKY",
54725
- SKYBOX: "SCENERY.SUBTYPE.SKYBOX"
54725
+ SKYBOX: "SCENERY.SUBTYPE.SKYBOX",
54726
+ WATER: "SCENERY.SUBTYPE.WATER",
54727
+ MIRROR: "SCENERY.SUBTYPE.MIRROR"
54726
54728
  }
54727
54729
  },
54728
54730
  HELPER: {
@@ -54738,7 +54740,7 @@ let Keyboard = /*#__PURE__*/function (_EventDispatcher) {
54738
54740
  UNKNOWN: "UNKNOWN"
54739
54741
  };
54740
54742
  const FLAT_ENTITY_TYPES = [ENTITY_TYPES.SCENE.TYPE, ENTITY_TYPES.CAMERA.TYPE, ENTITY_TYPES.MESH.TYPE, ENTITY_TYPES.LABEL.TYPE, ENTITY_TYPES.LIGHT.TYPE, ENTITY_TYPES.AUDIO.TYPE, ENTITY_TYPES.MODEL.TYPE, ENTITY_TYPES.SPRITE.TYPE, ENTITY_TYPES.PARTICLE.TYPE, ENTITY_TYPES.SCENERY.TYPE, ENTITY_TYPES.HELPER.TYPE, ENTITY_TYPES.UNKNOWN];
54741
- const FLAT_ENTITY_SUBTYPES = [ENTITY_TYPES.SCENE.SUBTYPES.DEFAULT, ENTITY_TYPES.CAMERA.SUBTYPES.DEFAULT, ENTITY_TYPES.CAMERA.SUBTYPES.MAIN, ENTITY_TYPES.CAMERA.SUBTYPES.GAME, ENTITY_TYPES.MESH.SUBTYPES.DEFAULT, ENTITY_TYPES.MESH.SUBTYPES.BOX, ENTITY_TYPES.MESH.SUBTYPES.SPHERE, ENTITY_TYPES.MESH.SUBTYPES.PLANE, ENTITY_TYPES.MESH.SUBTYPES.CYLINDER, ENTITY_TYPES.MESH.SUBTYPES.CONE, ENTITY_TYPES.MESH.SUBTYPES.CUBE, ENTITY_TYPES.MESH.SUBTYPES.LINE, ENTITY_TYPES.MESH.SUBTYPES.CURVE_LINE, ENTITY_TYPES.MESH.SUBTYPES.AXES, ENTITY_TYPES.MESH.SUBTYPES.GRID, ENTITY_TYPES.MESH.SUBTYPES.TARGET, ENTITY_TYPES.LABEL.SUBTYPES.DEFAULT, ENTITY_TYPES.LIGHT.SUBTYPES.DEFAULT, ENTITY_TYPES.LIGHT.SUBTYPES.AMBIENT, ENTITY_TYPES.LIGHT.SUBTYPES.SUN, ENTITY_TYPES.LIGHT.SUBTYPES.HEMISPHERE, ENTITY_TYPES.LIGHT.SUBTYPES.POINT, ENTITY_TYPES.LIGHT.SUBTYPES.SPOT, ENTITY_TYPES.AUDIO.SUBTYPES.DEFAULT, ENTITY_TYPES.AUDIO.SUBTYPES.DIRECTIONAL, ENTITY_TYPES.AUDIO.SUBTYPES.AMBIENT, ENTITY_TYPES.MODEL.SUBTYPES.DEFAULT, ENTITY_TYPES.SPRITE.SUBTYPES.DEFAULT, ENTITY_TYPES.SPRITE.SUBTYPES.ANIMATED_SPRITE, ENTITY_TYPES.PARTICLE.SUBTYPES.DEFAULT, ENTITY_TYPES.PARTICLE.SUBTYPES.EMITTER, ENTITY_TYPES.PARTICLE.SUBTYPES.SYSTEM, ENTITY_TYPES.PARTICLE.SUBTYPES.EMITTER_GROUP, ENTITY_TYPES.PARTICLE.SUBTYPES.PROTON_EMITTER, ENTITY_TYPES.PARTICLE.SUBTYPES.FIRE, ENTITY_TYPES.PARTICLE.SUBTYPES.EXPLOSION, ENTITY_TYPES.PARTICLE.SUBTYPES.TRAIL, ENTITY_TYPES.PARTICLE.SUBTYPES.RAIN, ENTITY_TYPES.PARTICLE.SUBTYPES.SNOW, ENTITY_TYPES.PARTICLE.SUBTYPES.FOUNTAIN, ENTITY_TYPES.SCENERY.SUBTYPES.DEFAULT, ENTITY_TYPES.SCENERY.SUBTYPES.SKY, ENTITY_TYPES.SCENERY.SUBTYPES.SKYBOX, ENTITY_TYPES.HELPER.SUBTYPES.GRID, ENTITY_TYPES.HELPER.SUBTYPES.AXES, ENTITY_TYPES.HELPER.SUBTYPES.HELPER_SPRITE];
54743
+ const FLAT_ENTITY_SUBTYPES = [ENTITY_TYPES.SCENE.SUBTYPES.DEFAULT, ENTITY_TYPES.CAMERA.SUBTYPES.DEFAULT, ENTITY_TYPES.CAMERA.SUBTYPES.MAIN, ENTITY_TYPES.CAMERA.SUBTYPES.GAME, ENTITY_TYPES.MESH.SUBTYPES.DEFAULT, ENTITY_TYPES.MESH.SUBTYPES.BOX, ENTITY_TYPES.MESH.SUBTYPES.SPHERE, ENTITY_TYPES.MESH.SUBTYPES.PLANE, ENTITY_TYPES.MESH.SUBTYPES.CYLINDER, ENTITY_TYPES.MESH.SUBTYPES.CONE, ENTITY_TYPES.MESH.SUBTYPES.CUBE, ENTITY_TYPES.MESH.SUBTYPES.LINE, ENTITY_TYPES.MESH.SUBTYPES.CURVE_LINE, ENTITY_TYPES.MESH.SUBTYPES.AXES, ENTITY_TYPES.MESH.SUBTYPES.GRID, ENTITY_TYPES.MESH.SUBTYPES.TARGET, ENTITY_TYPES.LABEL.SUBTYPES.DEFAULT, ENTITY_TYPES.LIGHT.SUBTYPES.DEFAULT, ENTITY_TYPES.LIGHT.SUBTYPES.AMBIENT, ENTITY_TYPES.LIGHT.SUBTYPES.SUN, ENTITY_TYPES.LIGHT.SUBTYPES.HEMISPHERE, ENTITY_TYPES.LIGHT.SUBTYPES.POINT, ENTITY_TYPES.LIGHT.SUBTYPES.SPOT, ENTITY_TYPES.AUDIO.SUBTYPES.DEFAULT, ENTITY_TYPES.AUDIO.SUBTYPES.DIRECTIONAL, ENTITY_TYPES.AUDIO.SUBTYPES.AMBIENT, ENTITY_TYPES.MODEL.SUBTYPES.DEFAULT, ENTITY_TYPES.SPRITE.SUBTYPES.DEFAULT, ENTITY_TYPES.SPRITE.SUBTYPES.ANIMATED_SPRITE, ENTITY_TYPES.PARTICLE.SUBTYPES.DEFAULT, ENTITY_TYPES.PARTICLE.SUBTYPES.EMITTER, ENTITY_TYPES.PARTICLE.SUBTYPES.SYSTEM, ENTITY_TYPES.PARTICLE.SUBTYPES.EMITTER_GROUP, ENTITY_TYPES.PARTICLE.SUBTYPES.PROTON_EMITTER, ENTITY_TYPES.PARTICLE.SUBTYPES.FIRE, ENTITY_TYPES.PARTICLE.SUBTYPES.EXPLOSION, ENTITY_TYPES.PARTICLE.SUBTYPES.TRAIL, ENTITY_TYPES.PARTICLE.SUBTYPES.RAIN, ENTITY_TYPES.PARTICLE.SUBTYPES.SNOW, ENTITY_TYPES.PARTICLE.SUBTYPES.FOUNTAIN, ENTITY_TYPES.SCENERY.SUBTYPES.DEFAULT, ENTITY_TYPES.SCENERY.SUBTYPES.SKY, ENTITY_TYPES.SCENERY.SUBTYPES.SKYBOX, ENTITY_TYPES.SCENERY.SUBTYPES.WATER, ENTITY_TYPES.SCENERY.SUBTYPES.MIRROR, ENTITY_TYPES.HELPER.SUBTYPES.GRID, ENTITY_TYPES.HELPER.SUBTYPES.AXES, ENTITY_TYPES.HELPER.SUBTYPES.HELPER_SPRITE];
54742
54744
  const ENTITY_EVENTS = {
54743
54745
  DISPOSE: "DISPOSE",
54744
54746
  STATE_MACHINE: {
@@ -54788,9 +54790,9 @@ const createElementFromSelector = function (selector) {
54788
54790
  } catch (e) {
54789
54791
  return null;
54790
54792
  }
54791
- };const DEFAULT_HEIGHT$2 = 600;
54792
- const DEFAULT_WIDTH = 800;
54793
- const DEFAULT_RATIO = DEFAULT_WIDTH / DEFAULT_HEIGHT$2;
54793
+ };const DEFAULT_HEIGHT$3 = 600;
54794
+ const DEFAULT_WIDTH$1 = 800;
54795
+ const DEFAULT_RATIO = DEFAULT_WIDTH$1 / DEFAULT_HEIGHT$3;
54794
54796
  const DEFAULT_CONFIG = {
54795
54797
  tests: [],
54796
54798
  scripts: {// [scriptId]: Script
@@ -54825,7 +54827,7 @@ const DEFAULT_CONFIG = {
54825
54827
  //handling useful informations about our camera.
54826
54828
  fov: 75,
54827
54829
  near: 0.1,
54828
- far: 100
54830
+ far: 10000
54829
54831
  },
54830
54832
  ui: {
54831
54833
  enabled: true
@@ -54918,8 +54920,8 @@ let Config = /*#__PURE__*/function () {
54918
54920
  key: "getScreenDefaults",
54919
54921
  value: function getScreenDefaults() {
54920
54922
  return {
54921
- h: DEFAULT_HEIGHT$2,
54922
- w: DEFAULT_WIDTH,
54923
+ h: DEFAULT_HEIGHT$3,
54924
+ w: DEFAULT_WIDTH$1,
54923
54925
  ratio: DEFAULT_RATIO
54924
54926
  };
54925
54927
  }
@@ -55052,14 +55054,36 @@ var Config$1 = new Config();let Universe = /*#__PURE__*/function () {
55052
55054
  }, {
55053
55055
  key: "find",
55054
55056
  value: function find(element) {
55055
- if (!element) return;
55056
- let found;
55057
+ if (!element) return; // Traverse up the THREE.js parent chain to find the closest Mage entity.
55058
+ // This ensures that when clicking on a child mesh that's nested inside
55059
+ // a parent entity's body, we find the child entity (not the parent).
55060
+
55061
+ let current = element;
55062
+
55063
+ while (current) {
55064
+ // Check if any entity's body IS this object directly
55065
+ let found;
55066
+ this.forEach(el => {
55067
+ if (!found && el.hasBody() && el.getBody() === current) {
55068
+ found = el;
55069
+ }
55070
+ });
55071
+
55072
+ if (found) {
55073
+ return found;
55074
+ }
55075
+
55076
+ current = current.parent;
55077
+ } // Fallback: use the original has() check for edge cases
55078
+
55079
+
55080
+ let fallback;
55057
55081
  this.forEach(el => {
55058
- if (el.has(element) && !found) {
55059
- found = el;
55082
+ if (el.has(element) && !fallback) {
55083
+ fallback = el;
55060
55084
  }
55061
55085
  });
55062
- return found;
55086
+ return fallback;
55063
55087
  }
55064
55088
  }, {
55065
55089
  key: "getByTag",
@@ -56959,7 +56983,12 @@ var Physics$1 = new Physics();let Scene = /*#__PURE__*/function () {
56959
56983
  }, {
56960
56984
  key: "createCamera",
56961
56985
  value: function createCamera(camera) {
56962
- this.camera = camera;
56986
+ this.camera = camera; // Enable layer 1 so camera can see editor-only objects (helpers, grid, gizmos)
56987
+ // Mirror cameras only use layer 0, so they won't render these
56988
+
56989
+ if (this.camera && this.camera.getBody()) {
56990
+ this.camera.getBody().layers.enable(1);
56991
+ }
56963
56992
  }
56964
56993
  }, {
56965
56994
  key: "getDOMElement",
@@ -57248,7 +57277,9 @@ let Mouse = /*#__PURE__*/function (_EventDispatcher) {
57248
57277
  key: "createRayCaster",
57249
57278
  value: function createRayCaster() {
57250
57279
  if (!this.hasRaycaster()) {
57251
- this.raycaster = new Raycaster();
57280
+ this.raycaster = new Raycaster(); // Enable layer 1 so raycaster can pick editor-only objects (mirrors, etc.)
57281
+
57282
+ this.raycaster.layers.enable(1);
57252
57283
  this.raycaster.setFromCamera(this.mouse, Scene$1.getCameraBody());
57253
57284
  }
57254
57285
  }
@@ -58219,7 +58250,7 @@ function applyMiddleware() {
58219
58250
 
58220
58251
  var thunk = createThunkMiddleware();
58221
58252
  thunk.withExtraArgument = createThunkMiddleware;var name = "mage-engine";
58222
- var version$1 = "3.24.1";
58253
+ var version$1 = "3.24.3";
58223
58254
  var description = "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.";
58224
58255
  var main = "dist/mage.js";
58225
58256
  var author$1 = {
@@ -59558,7 +59589,7 @@ if (!self.fetch) {
59558
59589
 
59559
59590
  return BaseCar;
59560
59591
  }(BaseScript);const DEFAULT_DISTANCE$2 = 5.0;
59561
- const DEFAULT_HEIGHT$1 = 3.0;
59592
+ const DEFAULT_HEIGHT$2 = 3.0;
59562
59593
  const DEFAULT_HEIGHT_DAMPING = 2.0;
59563
59594
  const DEFAULT_LOOK_AT_HEIGHT = 1;
59564
59595
  const DEFAULT_ROTATION_SNAP_TIME = 0.3;
@@ -59581,7 +59612,7 @@ let SmoothCarFollow = /*#__PURE__*/function (_BaseScript) {
59581
59612
  value: function start(camera, options) {
59582
59613
  const {
59583
59614
  target,
59584
- height = DEFAULT_HEIGHT$1,
59615
+ height = DEFAULT_HEIGHT$2,
59585
59616
  heightDamping = DEFAULT_HEIGHT_DAMPING,
59586
59617
  lookAtHeight = DEFAULT_LOOK_AT_HEIGHT,
59587
59618
  distance = DEFAULT_DISTANCE$2,
@@ -61085,6 +61116,67 @@ const tweenTo = function (origin, target) {
61085
61116
  value: function hasChildren() {
61086
61117
  return this.children.length > 0;
61087
61118
  }
61119
+ /**
61120
+ * Checks if the given ancestor is in this entity's parent chain.
61121
+ * Used to prevent circular references when reparenting.
61122
+ * @param {Entity} ancestor - The potential ancestor entity
61123
+ * @returns {boolean} True if ancestor is in the parent chain
61124
+ */
61125
+
61126
+ }, {
61127
+ key: "isDescendantOf",
61128
+ value: function isDescendantOf(ancestor) {
61129
+ if (!ancestor) return false;
61130
+ let current = this.getParent();
61131
+
61132
+ while (current) {
61133
+ if (current === ancestor || current.uuid && ancestor.uuid && current.uuid() === ancestor.uuid()) {
61134
+ return true;
61135
+ }
61136
+
61137
+ current = current.getParent ? current.getParent() : null;
61138
+ }
61139
+
61140
+ return false;
61141
+ }
61142
+ /**
61143
+ * Reparents this entity to a new parent while preserving world position.
61144
+ * Uses THREE.js attach() to maintain the entity's world transform.
61145
+ * @param {Entity|null} newParent - The new parent entity, or null to move to scene root
61146
+ * @returns {Entity} This entity for chaining
61147
+ */
61148
+
61149
+ }, {
61150
+ key: "reparent",
61151
+ value: function reparent(newParent) {
61152
+ if (!this.hasBody()) return this;
61153
+ const oldParent = this.getParent(); // Detach from old parent's Entity children array
61154
+
61155
+ if (oldParent && oldParent.children) {
61156
+ const index = oldParent.children.findIndex(c => c === this || c.uuid && this.uuid && c.uuid() === this.uuid());
61157
+ if (index !== -1) oldParent.children.splice(index, 1);
61158
+ } // Detach from old THREE.js parent
61159
+
61160
+
61161
+ const body = this.getBody();
61162
+
61163
+ if (body.parent) {
61164
+ body.parent.remove(body);
61165
+ }
61166
+
61167
+ if (newParent && newParent.hasBody()) {
61168
+ // Attach to new parent (preserves world position)
61169
+ newParent.children.push(this);
61170
+ this.setParent(newParent);
61171
+ newParent.getBody().attach(body);
61172
+ } else {
61173
+ // Move to scene root
61174
+ this.setParent(false);
61175
+ Scene$1.getScene().attach(body);
61176
+ }
61177
+
61178
+ return this;
61179
+ }
61088
61180
  }, {
61089
61181
  key: "getHierarchy",
61090
61182
  value: function getHierarchy() {
@@ -63273,7 +63365,13 @@ let Sprite = /*#__PURE__*/function (_Element) {
63273
63365
 
63274
63366
  _this.setEntityType(ENTITY_TYPES.HELPER.TYPE);
63275
63367
 
63276
- _this.setEntitySubtype(ENTITY_TYPES.HELPER.SUBTYPES.HELPER_SPRITE);
63368
+ _this.setEntitySubtype(ENTITY_TYPES.HELPER.SUBTYPES.HELPER_SPRITE); // Set to layer 1 ONLY so mirrors don't render helper sprites
63369
+ // Main camera must enable layer 1 to see these
63370
+
63371
+
63372
+ if (_this.hasBody()) {
63373
+ _this.getBody().layers.set(1);
63374
+ }
63277
63375
 
63278
63376
  return _this;
63279
63377
  }
@@ -63381,7 +63479,30 @@ let Sprite = /*#__PURE__*/function (_Element) {
63381
63479
  holderSize = 0.05
63382
63480
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
63383
63481
  // Add THREE.js CameraHelper for visual feedback
63384
- this.helper = new CameraHelper(this.getBody());
63482
+ this.helper = new CameraHelper(this.getBody()); // Set to layer 1 ONLY so mirrors don't render camera helper
63483
+
63484
+ this.helper.layers.set(1); // Disable depth test so helper always renders on top of sky/water
63485
+
63486
+ this.helper.renderOrder = 999; // Helper function to set depth properties on materials
63487
+
63488
+ const setMaterialDepth = material => {
63489
+ if (!material) return;
63490
+ const mats = Array.isArray(material) ? material : [material];
63491
+ mats.forEach(mat => {
63492
+ mat.depthTest = false;
63493
+ mat.depthWrite = false;
63494
+ mat.transparent = true;
63495
+ mat.needsUpdate = true;
63496
+ });
63497
+ };
63498
+
63499
+ setMaterialDepth(this.helper.material); // Also apply to all children
63500
+
63501
+ this.helper.traverse(child => {
63502
+ child.layers.set(1);
63503
+ child.renderOrder = 999;
63504
+ setMaterialDepth(child.material);
63505
+ });
63385
63506
  Scene$1.add(this.helper, null, false); // Add holder sprite for selection
63386
63507
 
63387
63508
  this.addHolder(holderName, holderSize);
@@ -63605,7 +63726,10 @@ let Sprite = /*#__PURE__*/function (_Element) {
63605
63726
  name: generateRandomName("GridHelper")
63606
63727
  };
63607
63728
  _this = _super.call(this, options);
63608
- const body = new GridHelper(size, division, color1, color2);
63729
+ const body = new GridHelper(size, division, color1, color2); // Set to layer 1 ONLY so mirrors don't render the grid
63730
+ // Main camera must enable layer 1 to see the grid
63731
+
63732
+ body.layers.set(1);
63609
63733
 
63610
63734
  _this.setBody({
63611
63735
  body
@@ -86717,7 +86841,7 @@ let PixelEffect = /*#__PURE__*/function (_ShaderPass) {
86717
86841
  */
86718
86842
 
86719
86843
  const DEFAULT_THICKNESS = 0.003;
86720
- const DEFAULT_COLOR = 0x000000;
86844
+ const DEFAULT_COLOR$1 = 0x000000;
86721
86845
  const DEFAULT_ALPHA = 1.0;
86722
86846
  const DEFAULT_KEEPALIVE = false;
86723
86847
 
@@ -86725,7 +86849,7 @@ let OutlineEffect = /*#__PURE__*/function () {
86725
86849
  function OutlineEffect(_ref) {
86726
86850
  let {
86727
86851
  defaultThickness = DEFAULT_THICKNESS,
86728
- defaultColor = DEFAULT_COLOR,
86852
+ defaultColor = DEFAULT_COLOR$1,
86729
86853
  defaultAlpha = DEFAULT_ALPHA,
86730
86854
  defaultKeepAlive = DEFAULT_KEEPALIVE
86731
86855
  } = _ref;
@@ -90911,7 +91035,38 @@ var Particles$1 = new Particles();let Orbit = /*#__PURE__*/function (_EventDispa
90911
91035
  _this.domElement = domElement !== undefined ? domElement : document;
90912
91036
  _this.visible = false;
90913
91037
  _this.gizmo = new Gizmo();
90914
- _this.plane = new TransformControlsPlane();
91038
+ _this.plane = new TransformControlsPlane(); // Set gizmo and plane to layer 1 ONLY so mirrors don't render them
91039
+ // Main camera must enable layer 1 to see these
91040
+
91041
+ _this.gizmo.layers.set(1);
91042
+
91043
+ _this.plane.layers.set(1); // Helper function to set depth properties on materials
91044
+
91045
+
91046
+ const setMaterialDepth = material => {
91047
+ if (!material) return;
91048
+ const mats = Array.isArray(material) ? material : [material];
91049
+ mats.forEach(mat => {
91050
+ mat.depthTest = false;
91051
+ mat.depthWrite = false;
91052
+ mat.transparent = true;
91053
+ mat.needsUpdate = true;
91054
+ });
91055
+ }; // Also set layer 1 on all children recursively
91056
+ // Set high renderOrder and disable depthTest so gizmos render on top of sky/water
91057
+
91058
+
91059
+ _this.gizmo.traverse(child => {
91060
+ child.layers.set(1);
91061
+ child.renderOrder = 999;
91062
+ setMaterialDepth(child.material);
91063
+ });
91064
+
91065
+ _this.plane.traverse(child => {
91066
+ child.layers.set(1);
91067
+ child.renderOrder = 999;
91068
+ setMaterialDepth(child.material);
91069
+ });
90915
91070
 
90916
91071
  _this.add(_this.gizmo);
90917
91072
 
@@ -90965,7 +91120,10 @@ var Particles$1 = new Particles();let Orbit = /*#__PURE__*/function (_EventDispa
90965
91120
 
90966
91121
  _this.setAndDispatch("showZ", true);
90967
91122
 
90968
- _this.ray = new Raycaster();
91123
+ _this.ray = new Raycaster(); // Enable layer 1 so raycaster can pick gizmo objects (which are on layer 1)
91124
+
91125
+ _this.ray.layers.enable(1);
91126
+
90969
91127
  _this._tempVector = new Vector3$1();
90970
91128
  _this._tempVector2 = new Vector3$1();
90971
91129
  _this._tempQuaternion = new Quaternion();
@@ -92932,7 +93090,30 @@ let PointLight$1 = /*#__PURE__*/function (_Light) {
92932
93090
  holderSize = 0.05
92933
93091
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
92934
93092
  this.helper = new PointLightHelper(this.getBody(), 2, GREEN$5);
92935
- this.shadowHelper = new CameraHelper(this.getBody().shadow.camera);
93093
+ this.shadowHelper = new CameraHelper(this.getBody().shadow.camera); // Set to layer 1 ONLY so mirrors don't render light helpers
93094
+ // Disable depth test so helpers always render on top of sky/water
93095
+
93096
+ const setMaterialDepth = material => {
93097
+ if (!material) return;
93098
+ const mats = Array.isArray(material) ? material : [material];
93099
+ mats.forEach(mat => {
93100
+ mat.depthTest = false;
93101
+ mat.depthWrite = false;
93102
+ mat.transparent = true;
93103
+ mat.needsUpdate = true;
93104
+ });
93105
+ };
93106
+
93107
+ [this.helper, this.shadowHelper].forEach(helper => {
93108
+ helper.layers.set(1);
93109
+ helper.renderOrder = 999;
93110
+ setMaterialDepth(helper.material);
93111
+ helper.traverse(child => {
93112
+ child.layers.set(1);
93113
+ child.renderOrder = 999;
93114
+ setMaterialDepth(child.material);
93115
+ });
93116
+ });
92936
93117
  Scene$1.add(this.helper, null, false);
92937
93118
  Scene$1.add(this.shadowHelper, null, false);
92938
93119
  this.addHolder(holderName, holderSize);
@@ -93368,7 +93549,30 @@ let SpotLight$1 = /*#__PURE__*/function (_Light) {
93368
93549
  targetHolderSize = 0.05
93369
93550
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
93370
93551
  this.helper = new SpotLightHelper(this.getBody(), GREEN$4);
93371
- this.shadowHelper = new CameraHelper(this.getBody().shadow.camera);
93552
+ this.shadowHelper = new CameraHelper(this.getBody().shadow.camera); // Set to layer 1 ONLY so mirrors don't render light helpers
93553
+ // Disable depth test so helpers always render on top of sky/water
93554
+
93555
+ const setMaterialDepth = material => {
93556
+ if (!material) return;
93557
+ const mats = Array.isArray(material) ? material : [material];
93558
+ mats.forEach(mat => {
93559
+ mat.depthTest = false;
93560
+ mat.depthWrite = false;
93561
+ mat.transparent = true;
93562
+ mat.needsUpdate = true;
93563
+ });
93564
+ };
93565
+
93566
+ [this.helper, this.shadowHelper].forEach(helper => {
93567
+ helper.layers.set(1);
93568
+ helper.renderOrder = 999;
93569
+ setMaterialDepth(helper.material);
93570
+ helper.traverse(child => {
93571
+ child.layers.set(1);
93572
+ child.renderOrder = 999;
93573
+ setMaterialDepth(child.material);
93574
+ });
93575
+ });
93372
93576
  Scene$1.add(this.helper, null, false);
93373
93577
  Scene$1.add(this.shadowHelper, null, false);
93374
93578
  this.addHolder(holderName, holderSize);
@@ -93816,7 +94020,28 @@ let HemisphereLight$1 = /*#__PURE__*/function (_Light) {
93816
94020
  holderName = "hemispherelightholder",
93817
94021
  holderSize = 0.05
93818
94022
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
93819
- this.helper = new HemisphereLightHelper(this.getBody(), 2, GREEN$3);
94023
+ this.helper = new HemisphereLightHelper(this.getBody(), 2, GREEN$3); // Set to layer 1 ONLY so mirrors don't render light helpers
94024
+ // Disable depth test so helpers always render on top of sky/water
94025
+
94026
+ const setMaterialDepth = material => {
94027
+ if (!material) return;
94028
+ const mats = Array.isArray(material) ? material : [material];
94029
+ mats.forEach(mat => {
94030
+ mat.depthTest = false;
94031
+ mat.depthWrite = false;
94032
+ mat.transparent = true;
94033
+ mat.needsUpdate = true;
94034
+ });
94035
+ };
94036
+
94037
+ this.helper.layers.set(1);
94038
+ this.helper.renderOrder = 999;
94039
+ setMaterialDepth(this.helper.material);
94040
+ this.helper.traverse(child => {
94041
+ child.layers.set(1);
94042
+ child.renderOrder = 999;
94043
+ setMaterialDepth(child.material);
94044
+ });
93820
94045
  this.addHolder(holderName, holderSize);
93821
94046
  this.isUsingHelper = true;
93822
94047
  Scene$1.add(this.helper, null, false);
@@ -94062,7 +94287,30 @@ let SunLight$1 = /*#__PURE__*/function (_Light) {
94062
94287
  targetHolderSize = 0.05
94063
94288
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
94064
94289
  this.helper = new DirectionalLightHelper(this.getBody(), 5);
94065
- this.shadowHelper = new CameraHelper(this.getBody().shadow.camera);
94290
+ this.shadowHelper = new CameraHelper(this.getBody().shadow.camera); // Set to layer 1 ONLY so mirrors don't render light helpers
94291
+ // Disable depth test so helpers always render on top of sky/water
94292
+
94293
+ const setMaterialDepth = material => {
94294
+ if (!material) return;
94295
+ const mats = Array.isArray(material) ? material : [material];
94296
+ mats.forEach(mat => {
94297
+ mat.depthTest = false;
94298
+ mat.depthWrite = false;
94299
+ mat.transparent = true;
94300
+ mat.needsUpdate = true;
94301
+ });
94302
+ };
94303
+
94304
+ [this.helper, this.shadowHelper].forEach(helper => {
94305
+ helper.layers.set(1);
94306
+ helper.renderOrder = 999;
94307
+ setMaterialDepth(helper.material);
94308
+ helper.traverse(child => {
94309
+ child.layers.set(1);
94310
+ child.renderOrder = 999;
94311
+ setMaterialDepth(child.material);
94312
+ });
94313
+ });
94066
94314
  Scene$1.add(this.helper, null, false);
94067
94315
  Scene$1.add(this.shadowHelper, null, false);
94068
94316
  this.addHolder(holderName, holderSize);
@@ -94882,9 +95130,11 @@ let Sky = /*#__PURE__*/function (_Element) {
94882
95130
  fragmentShader: SkyShader.fragmentShader(),
94883
95131
  vertexShader: SkyShader.vertexShader(),
94884
95132
  uniforms: UniformsUtils.clone(SkyShader.uniforms()),
94885
- side: BackSide
95133
+ side: BackSide,
95134
+ depthWrite: false
94886
95135
  });
94887
95136
  const body = new Mesh(new BoxGeometry(1, 1, 1), material);
95137
+ body.renderOrder = -1000;
94888
95138
 
94889
95139
  _this.setBody({
94890
95140
  body
@@ -94943,6 +95193,20 @@ let Sky = /*#__PURE__*/function (_Element) {
94943
95193
  this.setData("mieDirectionalG", value);
94944
95194
  this.getBody().material.uniforms.mieDirectionalG.value = value;
94945
95195
  }
95196
+ }, {
95197
+ key: "setSunInclination",
95198
+ value: function setSunInclination(value) {
95199
+ const azimuth = this.getData("sunAzimuth") || 0.1;
95200
+ const distance = this.getData("sunDistance") || 100;
95201
+ this.setSun(value, azimuth, distance);
95202
+ }
95203
+ }, {
95204
+ key: "setSunAzimuth",
95205
+ value: function setSunAzimuth(value) {
95206
+ const inclination = this.getData("sunInclination") || 0.21;
95207
+ const distance = this.getData("sunDistance") || 100;
95208
+ this.setSun(inclination, value, distance);
95209
+ }
94946
95210
  }, {
94947
95211
  key: "setSun",
94948
95212
  value: function setSun(inclination, azimuth, distance) {
@@ -94966,6 +95230,731 @@ let Sky = /*#__PURE__*/function (_Element) {
94966
95230
  }]);
94967
95231
 
94968
95232
  return Sky;
95233
+ }(Element$1);let Skybox = /*#__PURE__*/function (_Element) {
95234
+ _inherits(Skybox, _Element);
95235
+
95236
+ var _super = _createSuper(Skybox);
95237
+
95238
+ function Skybox(options) {
95239
+ var _this;
95240
+
95241
+ _classCallCheck(this, Skybox);
95242
+
95243
+ const {
95244
+ name = generateRandomName("Skybox"),
95245
+ texture = "skybox",
95246
+ ...rest
95247
+ } = options;
95248
+ _this = _super.call(this, {
95249
+ name,
95250
+ texture,
95251
+ ...rest
95252
+ });
95253
+ _this.cubeMap = typeof texture === "string" ? Images$1.get(texture) : texture;
95254
+ const material = new MeshBasicMaterial({
95255
+ envMap: _this.cubeMap,
95256
+ side: BackSide
95257
+ });
95258
+ const geometry = new BoxGeometry(1000000, 1000000, 1000000);
95259
+
95260
+ _this.setBody({
95261
+ material,
95262
+ geometry
95263
+ });
95264
+
95265
+ _this.setEntityType(ENTITY_TYPES.SCENERY.TYPE);
95266
+
95267
+ _this.setEntitySubtype(ENTITY_TYPES.SCENERY.SUBTYPES.SKYBOX);
95268
+
95269
+ return _this;
95270
+ }
95271
+
95272
+ _createClass(Skybox, null, [{
95273
+ key: "create",
95274
+ value: function create(data) {
95275
+ return new Skybox(data.options || data);
95276
+ }
95277
+ }]);
95278
+
95279
+ return Skybox;
95280
+ }(Element$1);var WaterMesh = function (geometry, options) {
95281
+ Mesh.call(this, geometry);
95282
+ var scope = this;
95283
+ options = options || {};
95284
+ var textureWidth = options.textureWidth !== undefined ? options.textureWidth : 512;
95285
+ var textureHeight = options.textureHeight !== undefined ? options.textureHeight : 512;
95286
+ var clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
95287
+ var alpha = options.alpha !== undefined ? options.alpha : 1.0;
95288
+ var time = options.time !== undefined ? options.time : 0.0;
95289
+ var normalSampler = options.waterNormals !== undefined ? options.waterNormals : null;
95290
+ var sunDirection = options.sunDirection !== undefined ? options.sunDirection : new Vector3$1(0.70707, 0.70707, 0.0);
95291
+ var sunColor = new Color$1(options.sunColor !== undefined ? options.sunColor : 0xffffff);
95292
+ var waterColor = new Color$1(options.waterColor !== undefined ? options.waterColor : 0x7F7F7F);
95293
+ var eye = options.eye !== undefined ? options.eye : new Vector3$1(0, 0, 0);
95294
+ var distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0;
95295
+ var side = options.side !== undefined ? options.side : FrontSide;
95296
+ var fog = options.fog !== undefined ? options.fog : false; //
95297
+
95298
+ var mirrorPlane = new Plane$1();
95299
+ var normal = new Vector3$1();
95300
+ var mirrorWorldPosition = new Vector3$1();
95301
+ var cameraWorldPosition = new Vector3$1();
95302
+ var rotationMatrix = new Matrix4();
95303
+ var lookAtPosition = new Vector3$1(0, 0, -1);
95304
+ var clipPlane = new Vector4();
95305
+ var view = new Vector3$1();
95306
+ var target = new Vector3$1();
95307
+ var q = new Vector4();
95308
+ var textureMatrix = new Matrix4();
95309
+ var mirrorCamera = new PerspectiveCamera();
95310
+ var parameters = {
95311
+ minFilter: LinearFilter,
95312
+ magFilter: LinearFilter,
95313
+ format: RGBFormat
95314
+ };
95315
+ var renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, parameters);
95316
+
95317
+ if (!MathUtils.isPowerOfTwo(textureWidth) || !MathUtils.isPowerOfTwo(textureHeight)) {
95318
+ renderTarget.texture.generateMipmaps = false;
95319
+ }
95320
+
95321
+ var mirrorShader = {
95322
+ uniforms: UniformsUtils.merge([UniformsLib['fog'], UniformsLib['lights'], {
95323
+ 'normalSampler': {
95324
+ value: null
95325
+ },
95326
+ 'mirrorSampler': {
95327
+ value: null
95328
+ },
95329
+ 'alpha': {
95330
+ value: 1.0
95331
+ },
95332
+ 'time': {
95333
+ value: 0.0
95334
+ },
95335
+ 'size': {
95336
+ value: 1.0
95337
+ },
95338
+ 'distortionScale': {
95339
+ value: 20.0
95340
+ },
95341
+ 'textureMatrix': {
95342
+ value: new Matrix4()
95343
+ },
95344
+ 'sunColor': {
95345
+ value: new Color$1(0x7F7F7F)
95346
+ },
95347
+ 'sunDirection': {
95348
+ value: new Vector3$1(0.70707, 0.70707, 0)
95349
+ },
95350
+ 'eye': {
95351
+ value: new Vector3$1()
95352
+ },
95353
+ 'waterColor': {
95354
+ value: new Color$1(0x555555)
95355
+ }
95356
+ }]),
95357
+ vertexShader: ['uniform mat4 textureMatrix;', 'uniform float time;', 'varying vec4 mirrorCoord;', 'varying vec4 worldPosition;', '#include <common>', '#include <fog_pars_vertex>', '#include <shadowmap_pars_vertex>', '#include <logdepthbuf_pars_vertex>', 'void main() {', ' mirrorCoord = modelMatrix * vec4( position, 1.0 );', ' worldPosition = mirrorCoord.xyzw;', ' mirrorCoord = textureMatrix * mirrorCoord;', ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', ' gl_Position = projectionMatrix * mvPosition;', '#include <beginnormal_vertex>', '#include <defaultnormal_vertex>', '#include <logdepthbuf_vertex>', '#include <fog_vertex>', '#include <shadowmap_vertex>', '}'].join('\n'),
95358
+ fragmentShader: ['uniform sampler2D mirrorSampler;', 'uniform float alpha;', 'uniform float time;', 'uniform float size;', 'uniform float distortionScale;', 'uniform sampler2D normalSampler;', 'uniform vec3 sunColor;', 'uniform vec3 sunDirection;', 'uniform vec3 eye;', 'uniform vec3 waterColor;', 'varying vec4 mirrorCoord;', 'varying vec4 worldPosition;', 'vec4 getNoise( vec2 uv ) {', ' vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);', ' vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );', ' vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );', ' vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );', ' vec4 noise = texture2D( normalSampler, uv0 ) +', ' texture2D( normalSampler, uv1 ) +', ' texture2D( normalSampler, uv2 ) +', ' texture2D( normalSampler, uv3 );', ' return noise * 0.5 - 1.0;', '}', 'void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {', ' vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );', ' float direction = max( 0.0, dot( eyeDirection, reflection ) );', ' specularColor += pow( direction, shiny ) * sunColor * spec;', ' diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;', '}', '#include <common>', '#include <packing>', '#include <bsdfs>', '#include <fog_pars_fragment>', '#include <logdepthbuf_pars_fragment>', '#include <lights_pars_begin>', '#include <shadowmap_pars_fragment>', '#include <shadowmask_pars_fragment>', 'void main() {', '#include <logdepthbuf_fragment>', ' vec4 noise = getNoise( worldPosition.xz * size );', ' vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );', ' vec3 diffuseLight = vec3(0.0);', ' vec3 specularLight = vec3(0.0);', ' vec3 worldToEye = eye-worldPosition.xyz;', ' vec3 eyeDirection = normalize( worldToEye );', ' sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );', ' float distance = length(worldToEye);', ' vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;', ' vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.w + distortion ) );', ' float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );', ' float rf0 = 0.3;', ' float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );', ' vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;', ' vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);', ' vec3 outgoingLight = albedo;', ' gl_FragColor = vec4( outgoingLight, alpha );', '#include <tonemapping_fragment>', '#include <fog_fragment>', '}'].join('\n')
95359
+ };
95360
+ var material = new ShaderMaterial({
95361
+ fragmentShader: mirrorShader.fragmentShader,
95362
+ vertexShader: mirrorShader.vertexShader,
95363
+ uniforms: UniformsUtils.clone(mirrorShader.uniforms),
95364
+ lights: true,
95365
+ side: side,
95366
+ fog: fog,
95367
+ depthWrite: false // Water should not write to depth buffer so gizmos render on top
95368
+
95369
+ });
95370
+ material.uniforms['mirrorSampler'].value = renderTarget.texture;
95371
+ material.uniforms['textureMatrix'].value = textureMatrix;
95372
+ material.uniforms['alpha'].value = alpha;
95373
+ material.uniforms['time'].value = time;
95374
+ material.uniforms['normalSampler'].value = normalSampler;
95375
+ material.uniforms['sunColor'].value = sunColor;
95376
+ material.uniforms['waterColor'].value = waterColor;
95377
+ material.uniforms['sunDirection'].value = sunDirection;
95378
+ material.uniforms['distortionScale'].value = distortionScale;
95379
+ material.uniforms['eye'].value = eye;
95380
+ scope.material = material;
95381
+
95382
+ scope.onBeforeRender = function (renderer, scene, camera) {
95383
+ mirrorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
95384
+ cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
95385
+ rotationMatrix.extractRotation(scope.matrixWorld);
95386
+ normal.set(0, 0, 1);
95387
+ normal.applyMatrix4(rotationMatrix);
95388
+ view.subVectors(mirrorWorldPosition, cameraWorldPosition); // Avoid rendering when mirror is facing away
95389
+
95390
+ if (view.dot(normal) > 0) return;
95391
+ view.reflect(normal).negate();
95392
+ view.add(mirrorWorldPosition);
95393
+ rotationMatrix.extractRotation(camera.matrixWorld);
95394
+ lookAtPosition.set(0, 0, -1);
95395
+ lookAtPosition.applyMatrix4(rotationMatrix);
95396
+ lookAtPosition.add(cameraWorldPosition);
95397
+ target.subVectors(mirrorWorldPosition, lookAtPosition);
95398
+ target.reflect(normal).negate();
95399
+ target.add(mirrorWorldPosition);
95400
+ mirrorCamera.position.copy(view);
95401
+ mirrorCamera.up.set(0, 1, 0);
95402
+ mirrorCamera.up.applyMatrix4(rotationMatrix);
95403
+ mirrorCamera.up.reflect(normal);
95404
+ mirrorCamera.lookAt(target);
95405
+ mirrorCamera.far = camera.far; // Used in WebGLBackground
95406
+
95407
+ mirrorCamera.updateMatrixWorld();
95408
+ mirrorCamera.projectionMatrix.copy(camera.projectionMatrix); // Update the texture matrix
95409
+
95410
+ textureMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
95411
+ textureMatrix.multiply(mirrorCamera.projectionMatrix);
95412
+ textureMatrix.multiply(mirrorCamera.matrixWorldInverse); // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
95413
+ // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
95414
+
95415
+ mirrorPlane.setFromNormalAndCoplanarPoint(normal, mirrorWorldPosition);
95416
+ mirrorPlane.applyMatrix4(mirrorCamera.matrixWorldInverse);
95417
+ clipPlane.set(mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant);
95418
+ var projectionMatrix = mirrorCamera.projectionMatrix;
95419
+ q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
95420
+ q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
95421
+ q.z = -1.0;
95422
+ q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]; // Calculate the scaled plane vector
95423
+
95424
+ clipPlane.multiplyScalar(2.0 / clipPlane.dot(q)); // Replacing the third row of the projection matrix
95425
+
95426
+ projectionMatrix.elements[2] = clipPlane.x;
95427
+ projectionMatrix.elements[6] = clipPlane.y;
95428
+ projectionMatrix.elements[10] = clipPlane.z + 1.0 - clipBias;
95429
+ projectionMatrix.elements[14] = clipPlane.w;
95430
+ eye.setFromMatrixPosition(camera.matrixWorld); // Render
95431
+
95432
+ if (renderer.outputEncoding !== LinearEncoding) {
95433
+ console.warn('THREE.WaterMesh: WebGLRenderer must use LinearEncoding as outputEncoding.');
95434
+
95435
+ scope.onBeforeRender = function () {};
95436
+
95437
+ return;
95438
+ }
95439
+
95440
+ if (renderer.toneMapping !== NoToneMapping) {
95441
+ console.warn('THREE.WaterMesh: WebGLRenderer must use NoToneMapping as toneMapping.');
95442
+
95443
+ scope.onBeforeRender = function () {};
95444
+
95445
+ return;
95446
+ }
95447
+
95448
+ var currentRenderTarget = renderer.getRenderTarget();
95449
+ var currentXrEnabled = renderer.xr.enabled;
95450
+ var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
95451
+ scope.visible = false;
95452
+ renderer.xr.enabled = false; // Avoid camera modification and recursion
95453
+
95454
+ renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
95455
+
95456
+ renderer.setRenderTarget(renderTarget);
95457
+ renderer.state.buffers.depth.setMask(true); // make sure the depth buffer is writable so it can be properly cleared, see #18897
95458
+
95459
+ if (renderer.autoClear === false) renderer.clear();
95460
+ renderer.render(scene, mirrorCamera);
95461
+ scope.visible = true;
95462
+ renderer.xr.enabled = currentXrEnabled;
95463
+ renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
95464
+ renderer.setRenderTarget(currentRenderTarget); // Restore viewport
95465
+
95466
+ var viewport = camera.viewport;
95467
+
95468
+ if (viewport !== undefined) {
95469
+ renderer.state.viewport(viewport);
95470
+ }
95471
+ };
95472
+ };
95473
+
95474
+ WaterMesh.prototype = Object.create(Mesh.prototype);
95475
+ WaterMesh.prototype.constructor = WaterMesh;
95476
+ const DEFAULT_WATER_HEIGHT = 512;
95477
+ const DEFAULT_WATER_WIDTH = 512;
95478
+ const DEFAULT_WATER_ALPHA = 1.0;
95479
+ const DEFAULT_WATER_DISTORTION_SCALE = 3.7; // Create a simple procedural normal map for water when no texture is available
95480
+
95481
+ const createDefaultWaterNormalTexture = () => {
95482
+ const size = 256;
95483
+ const data = new Uint8Array(size * size * 4);
95484
+
95485
+ for (let i = 0; i < size; i++) {
95486
+ for (let j = 0; j < size; j++) {
95487
+ const idx = (i * size + j) * 4; // Create a subtle wave pattern using sine waves
95488
+
95489
+ const wave1 = Math.sin(i * 0.1) * 0.5 + 0.5;
95490
+ const wave2 = Math.sin(j * 0.1) * 0.5 + 0.5;
95491
+ const wave3 = Math.sin((i + j) * 0.05) * 0.5 + 0.5; // Normal map colors (x, y, z mapped to r, g, b)
95492
+ // Flat normal pointing up is (0.5, 0.5, 1.0) in 0-1 range
95493
+
95494
+ data[idx] = 128 + (wave1 - 0.5) * 20; // R (X normal)
95495
+
95496
+ data[idx + 1] = 128 + (wave2 - 0.5) * 20; // G (Y normal)
95497
+
95498
+ data[idx + 2] = 255 * (0.9 + wave3 * 0.1); // B (Z normal - mostly up)
95499
+
95500
+ data[idx + 3] = 255; // A
95501
+ }
95502
+ }
95503
+
95504
+ const texture = new DataTexture(data, size, size, RGBAFormat, UnsignedByteType);
95505
+ texture.wrapS = texture.wrapT = RepeatWrapping$1;
95506
+ texture.needsUpdate = true;
95507
+ return texture;
95508
+ };
95509
+
95510
+ let Water = /*#__PURE__*/function (_Element) {
95511
+ _inherits(Water, _Element);
95512
+
95513
+ var _super = _createSuper(Water);
95514
+
95515
+ function Water() {
95516
+ var _thisSuper, _this;
95517
+
95518
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
95519
+
95520
+ _classCallCheck(this, Water);
95521
+
95522
+ _this = _super.call(this, options);
95523
+
95524
+ _defineProperty$1(_assertThisInitialized(_this), "update", dt => {
95525
+ _get((_thisSuper = _assertThisInitialized(_this), _getPrototypeOf(Water.prototype)), "update", _thisSuper).call(_thisSuper, dt);
95526
+
95527
+ _this.getBody().material.uniforms.time.value += dt;
95528
+ });
95529
+
95530
+ const {
95531
+ texture,
95532
+ textureNormalName,
95533
+ width = DEFAULT_WATER_WIDTH,
95534
+ height = DEFAULT_WATER_HEIGHT,
95535
+ textureWidth = DEFAULT_WATER_WIDTH,
95536
+ textureHeight = DEFAULT_WATER_HEIGHT,
95537
+ alpha = DEFAULT_WATER_ALPHA,
95538
+ distortionScale = DEFAULT_WATER_DISTORTION_SCALE
95539
+ } = options; // Get water normal texture, falling back to a procedural one if not available
95540
+
95541
+ let waterNormals = texture || Images$1.get(textureNormalName || 'waterNormal');
95542
+
95543
+ if (!waterNormals || waterNormals === false) {
95544
+ waterNormals = createDefaultWaterNormalTexture();
95545
+ } else {
95546
+ waterNormals.wrapS = waterNormals.wrapT = RepeatWrapping$1;
95547
+ }
95548
+
95549
+ const body = new WaterMesh(new PlaneGeometry(width * 500, height * 500), {
95550
+ textureWidth,
95551
+ textureHeight,
95552
+ waterNormals,
95553
+ alpha,
95554
+ sunDirection: new Vector3$1(-0.5773502691896258, 0.5773502691896258, -0.5773502691896258),
95555
+ sunColor: 0xffffff,
95556
+ waterColor: 0x001e0f,
95557
+ distortionScale,
95558
+ fog: Scene$1.getScene().fog !== undefined
95559
+ });
95560
+
95561
+ _this.setBody({
95562
+ body
95563
+ });
95564
+
95565
+ _this.setEntityType(ENTITY_TYPES.SCENERY.TYPE);
95566
+
95567
+ _this.setEntitySubtype(ENTITY_TYPES.SCENERY.SUBTYPES.WATER); // Store original dimensions for scaling calculations
95568
+
95569
+
95570
+ _this.setData("originalWidth", width);
95571
+
95572
+ _this.setData("originalHeight", height);
95573
+
95574
+ _this.setData("width", width);
95575
+
95576
+ _this.setData("height", height);
95577
+
95578
+ _this.setData("alpha", alpha);
95579
+
95580
+ _this.setData("distortionScale", distortionScale);
95581
+
95582
+ _this.setData("waterColor", 0x001e0f);
95583
+
95584
+ _this.setData("sunColor", 0xffffff);
95585
+
95586
+ _this.setData("sunDirection", {
95587
+ x: -0.577,
95588
+ y: 0.577,
95589
+ z: -0.577
95590
+ });
95591
+
95592
+ _this.setRotation({
95593
+ x: -Math.PI / 2
95594
+ });
95595
+
95596
+ return _this;
95597
+ }
95598
+
95599
+ _createClass(Water, [{
95600
+ key: "setSize",
95601
+ value: function setSize(size) {
95602
+ const clampedSize = clamp(size, 0.1, 100);
95603
+ this.setData("size", clampedSize);
95604
+ this.getBody().material.uniforms.size.value = clampedSize;
95605
+ }
95606
+ }, {
95607
+ key: "setAlpha",
95608
+ value: function setAlpha(alpha) {
95609
+ const clampedAlpha = clamp(alpha, 0, 1);
95610
+ this.setData("alpha", clampedAlpha);
95611
+ this.getBody().material.uniforms.alpha.value = clampedAlpha;
95612
+ }
95613
+ }, {
95614
+ key: "setDistortionScale",
95615
+ value: function setDistortionScale(scale) {
95616
+ const clampedScale = clamp(scale, 0, 100);
95617
+ this.setData("distortionScale", clampedScale);
95618
+ this.getBody().material.uniforms.distortionScale.value = clampedScale;
95619
+ }
95620
+ }, {
95621
+ key: "setWaterColor",
95622
+ value: function setWaterColor(color) {
95623
+ this.setData("waterColor", color);
95624
+ const colorValue = typeof color === 'object' && color.hex ? color.hex : color;
95625
+ this.getBody().material.uniforms.waterColor.value.set(colorValue);
95626
+ }
95627
+ }, {
95628
+ key: "setSunColor",
95629
+ value: function setSunColor(color) {
95630
+ this.setData("sunColor", color);
95631
+ const colorValue = typeof color === 'object' && color.hex ? color.hex : color;
95632
+ this.getBody().material.uniforms.sunColor.value.set(colorValue);
95633
+ }
95634
+ }, {
95635
+ key: "setSunDirection",
95636
+ value: function setSunDirection(x, y, z) {
95637
+ this.setData("sunDirection", {
95638
+ x,
95639
+ y,
95640
+ z
95641
+ });
95642
+ this.getBody().material.uniforms.sunDirection.value.set(x, y, z).normalize();
95643
+ }
95644
+ }, {
95645
+ key: "setWidth",
95646
+ value: function setWidth(width) {
95647
+ const clampedWidth = clamp(width, 1, 10000);
95648
+ this.setData("width", clampedWidth);
95649
+
95650
+ this._recreateGeometry();
95651
+ }
95652
+ }, {
95653
+ key: "setHeight",
95654
+ value: function setHeight(height) {
95655
+ const clampedHeight = clamp(height, 1, 10000);
95656
+ this.setData("height", clampedHeight);
95657
+
95658
+ this._recreateGeometry();
95659
+ }
95660
+ }, {
95661
+ key: "_recreateGeometry",
95662
+ value: function _recreateGeometry() {
95663
+ const width = this.getData("width") || 1000;
95664
+ const height = this.getData("height") || 1000; // Dispose old geometry
95665
+
95666
+ if (this.getBody().geometry) {
95667
+ this.getBody().geometry.dispose();
95668
+ } // Create new geometry with updated dimensions
95669
+
95670
+
95671
+ this.getBody().geometry = new PlaneGeometry(width * 500, height * 500);
95672
+ }
95673
+ }], [{
95674
+ key: "create",
95675
+ value: function create(data) {
95676
+ return new Water(data.options || data);
95677
+ }
95678
+ }]);
95679
+
95680
+ return Water;
95681
+ }(Element$1);const DEFAULT_TEXTURE_WIDTH = 512;
95682
+ const DEFAULT_TEXTURE_HEIGHT = 512;
95683
+ const DEFAULT_CLIP_BIAS = 0.003;
95684
+ const DEFAULT_COLOR = 0x7f7f7f;
95685
+ const DEFAULT_WIDTH = 100;
95686
+ const DEFAULT_HEIGHT$1 = 100; // Mirror shader uniforms
95687
+
95688
+ const mirrorUniforms = () => ({
95689
+ "mirrorColor": {
95690
+ type: "c",
95691
+ value: new Color$1(0x7F7F7F)
95692
+ },
95693
+ "mirrorSampler": {
95694
+ type: "t",
95695
+ value: null
95696
+ },
95697
+ "textureMatrix": {
95698
+ type: "m4",
95699
+ value: new Matrix4()
95700
+ }
95701
+ }); // Mirror vertex shader
95702
+
95703
+
95704
+ const mirrorVertexShader = `
95705
+ uniform mat4 textureMatrix;
95706
+ varying vec4 mirrorCoord;
95707
+ void main() {
95708
+ vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
95709
+ vec4 worldPosition = modelMatrix * vec4(position, 1.0);
95710
+ mirrorCoord = textureMatrix * worldPosition;
95711
+ gl_Position = projectionMatrix * mvPosition;
95712
+ }
95713
+ `; // Mirror fragment shader
95714
+
95715
+ const mirrorFragmentShader = `
95716
+ uniform vec3 mirrorColor;
95717
+ uniform sampler2D mirrorSampler;
95718
+ varying vec4 mirrorCoord;
95719
+ float blendOverlay(float base, float blend) {
95720
+ return(base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));
95721
+ }
95722
+ void main() {
95723
+ vec4 color = texture2DProj(mirrorSampler, mirrorCoord);
95724
+ color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b), 1.0);
95725
+ gl_FragColor = color;
95726
+ }
95727
+ `;
95728
+ /**
95729
+ * MirrorElement wraps mirror reflection rendering to fit the Entity system.
95730
+ * - Entity lifecycle management (serialization, deserialization)
95731
+ * - Integration with the editor's hierarchy and inspector
95732
+ * - Automatic render loop hook via onBeforeRender
95733
+ */
95734
+
95735
+ let MirrorElement = /*#__PURE__*/function (_Element) {
95736
+ _inherits(MirrorElement, _Element);
95737
+
95738
+ var _super = _createSuper(MirrorElement);
95739
+
95740
+ function MirrorElement() {
95741
+ var _this;
95742
+
95743
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
95744
+
95745
+ _classCallCheck(this, MirrorElement);
95746
+
95747
+ const {
95748
+ name = generateRandomName("Mirror"),
95749
+ textureWidth = DEFAULT_TEXTURE_WIDTH,
95750
+ textureHeight = DEFAULT_TEXTURE_HEIGHT,
95751
+ clipBias = DEFAULT_CLIP_BIAS,
95752
+ color = DEFAULT_COLOR,
95753
+ width = DEFAULT_WIDTH,
95754
+ height = DEFAULT_HEIGHT$1
95755
+ } = options;
95756
+ const cleanedOptions = {
95757
+ textureWidth,
95758
+ textureHeight,
95759
+ clipBias,
95760
+ color,
95761
+ width,
95762
+ height
95763
+ };
95764
+ _this = _super.call(this, {
95765
+ name,
95766
+ ...cleanedOptions
95767
+ }); // Store references
95768
+
95769
+ _this.renderer = Scene$1.getRenderer();
95770
+ _this.clipBias = clipBias;
95771
+ _this.textureWidth = textureWidth;
95772
+ _this.textureHeight = textureHeight; // Create render target for mirror reflection
95773
+
95774
+ const parameters = {
95775
+ minFilter: LinearFilter,
95776
+ magFilter: LinearFilter,
95777
+ format: RGBFormat,
95778
+ stencilBuffer: false
95779
+ };
95780
+ _this.renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, parameters); // Create mirror camera - only renders layer 0, excludes layer 1 (editor-only objects)
95781
+
95782
+ _this.mirrorCamera = new PerspectiveCamera();
95783
+ _this.mirrorCamera.matrixAutoUpdate = true;
95784
+
95785
+ _this.mirrorCamera.layers.set(0); // Only see layer 0
95786
+ // Create mirror material
95787
+
95788
+
95789
+ _this.mirrorMaterial = new ShaderMaterial({
95790
+ fragmentShader: mirrorFragmentShader,
95791
+ vertexShader: mirrorVertexShader,
95792
+ uniforms: UniformsUtils.clone(mirrorUniforms())
95793
+ });
95794
+ _this.mirrorMaterial.uniforms.mirrorSampler.value = _this.renderTarget.texture;
95795
+ _this.mirrorMaterial.uniforms.mirrorColor.value = new Color$1(color); // Reflection calculation helpers
95796
+
95797
+ _this.mirrorPlane = new Plane$1();
95798
+ _this.normal = new Vector3$1(0, 0, 1);
95799
+ _this.mirrorWorldPosition = new Vector3$1();
95800
+ _this.cameraWorldPosition = new Vector3$1();
95801
+ _this.rotationMatrix = new Matrix4();
95802
+ _this.lookAtPosition = new Vector3$1(0, 0, -1);
95803
+ _this.clipPlane = new Vector4();
95804
+ _this.textureMatrix = new Matrix4(); // Create a plane geometry for the mirror surface
95805
+
95806
+ const geometry = new PlaneGeometry(width, height);
95807
+ const body = new Mesh(geometry, _this.mirrorMaterial); // Set mirror to layer 1 ONLY so it doesn't reflect itself
95808
+ // The mirrorCamera only sees layer 0, so it won't render the mirror
95809
+ // Main camera has layer 1 enabled so it can see the mirror
95810
+
95811
+ body.layers.set(1); // Hook mirror rendering into THREE.js render loop
95812
+
95813
+ const self = _assertThisInitialized(_this);
95814
+
95815
+ body.onBeforeRender = function (renderer, scene, camera) {
95816
+ self.renderMirror(renderer, scene, camera, this);
95817
+ };
95818
+
95819
+ _this.setBody({
95820
+ body
95821
+ });
95822
+
95823
+ _this.setEntityType(ENTITY_TYPES.SCENERY.TYPE);
95824
+
95825
+ _this.setEntitySubtype(ENTITY_TYPES.SCENERY.SUBTYPES.MIRROR);
95826
+
95827
+ return _this;
95828
+ }
95829
+
95830
+ _createClass(MirrorElement, [{
95831
+ key: "renderMirror",
95832
+ value: function renderMirror(renderer, scene, camera, mesh) {
95833
+ // Update matrices
95834
+ mesh.updateMatrixWorld();
95835
+ camera.updateMatrixWorld();
95836
+ this.mirrorWorldPosition.setFromMatrixPosition(mesh.matrixWorld);
95837
+ this.cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
95838
+ this.rotationMatrix.extractRotation(mesh.matrixWorld);
95839
+ this.normal.set(0, 0, 1);
95840
+ this.normal.applyMatrix4(this.rotationMatrix);
95841
+ const view = this.mirrorWorldPosition.clone().sub(this.cameraWorldPosition);
95842
+ view.reflect(this.normal).negate();
95843
+ view.add(this.mirrorWorldPosition);
95844
+ this.rotationMatrix.extractRotation(camera.matrixWorld);
95845
+ this.lookAtPosition.set(0, 0, -1);
95846
+ this.lookAtPosition.applyMatrix4(this.rotationMatrix);
95847
+ this.lookAtPosition.add(this.cameraWorldPosition);
95848
+ const target = this.mirrorWorldPosition.clone().sub(this.lookAtPosition);
95849
+ target.reflect(this.normal).negate();
95850
+ target.add(this.mirrorWorldPosition);
95851
+ this.mirrorCamera.position.copy(view);
95852
+ this.mirrorCamera.up.set(0, -1, 0);
95853
+ this.mirrorCamera.up.applyMatrix4(this.rotationMatrix);
95854
+ this.mirrorCamera.up.reflect(this.normal).negate();
95855
+ this.mirrorCamera.lookAt(target);
95856
+ this.mirrorCamera.far = camera.far;
95857
+ this.mirrorCamera.updateProjectionMatrix();
95858
+ this.mirrorCamera.projectionMatrix.copy(camera.projectionMatrix);
95859
+ this.mirrorCamera.updateMatrixWorld();
95860
+ this.mirrorCamera.matrixWorldInverse.copy(this.mirrorCamera.matrixWorld).invert(); // Update the texture matrix
95861
+
95862
+ this.textureMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
95863
+ this.textureMatrix.multiply(this.mirrorCamera.projectionMatrix);
95864
+ this.textureMatrix.multiply(this.mirrorCamera.matrixWorldInverse); // Update clip plane
95865
+
95866
+ this.mirrorPlane.setFromNormalAndCoplanarPoint(this.normal, this.mirrorWorldPosition);
95867
+ this.mirrorPlane.applyMatrix4(this.mirrorCamera.matrixWorldInverse);
95868
+ this.clipPlane.set(this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant);
95869
+ const q = new Vector4();
95870
+ const projectionMatrix = this.mirrorCamera.projectionMatrix;
95871
+ q.x = (Math.sign(this.clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
95872
+ q.y = (Math.sign(this.clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
95873
+ q.z = -1.0;
95874
+ q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]; // Calculate the scaled plane vector
95875
+
95876
+ this.clipPlane.multiplyScalar(2.0 / this.clipPlane.dot(q)); // Replacing the third row of the projection matrix
95877
+
95878
+ projectionMatrix.elements[2] = this.clipPlane.x;
95879
+ projectionMatrix.elements[6] = this.clipPlane.y;
95880
+ projectionMatrix.elements[10] = this.clipPlane.z + 1.0 - this.clipBias;
95881
+ projectionMatrix.elements[14] = this.clipPlane.w;
95882
+ this.mirrorMaterial.uniforms.textureMatrix.value = this.textureMatrix; // Render the mirrored scene
95883
+
95884
+ mesh.visible = false;
95885
+ const currentRenderTarget = renderer.getRenderTarget(); // Save current clear color and set to scene background if available
95886
+
95887
+ const currentClearColor = renderer.getClearColor(new Color$1());
95888
+ const currentClearAlpha = renderer.getClearAlpha(); // Use scene background color for mirror clear if available
95889
+
95890
+ if (scene.background && scene.background.isColor) {
95891
+ renderer.setClearColor(scene.background, 1);
95892
+ }
95893
+
95894
+ renderer.setRenderTarget(this.renderTarget);
95895
+ renderer.clear();
95896
+ renderer.render(scene, this.mirrorCamera);
95897
+ renderer.setRenderTarget(currentRenderTarget); // Restore clear color
95898
+
95899
+ renderer.setClearColor(currentClearColor, currentClearAlpha);
95900
+ mesh.visible = true;
95901
+ }
95902
+ /**
95903
+ * Set the mirror color
95904
+ * @param {number|string} color - The color value (hex number or string)
95905
+ */
95906
+
95907
+ }, {
95908
+ key: "setColor",
95909
+ value: function setColor(color) {
95910
+ this.setData("color", color);
95911
+
95912
+ if (this.mirrorMaterial) {
95913
+ this.mirrorMaterial.uniforms.mirrorColor.value.set(color);
95914
+ }
95915
+ }
95916
+ /**
95917
+ * Set the clip bias for the mirror
95918
+ * @param {number} bias - The clip bias value
95919
+ */
95920
+
95921
+ }, {
95922
+ key: "setClipBias",
95923
+ value: function setClipBias(bias) {
95924
+ this.setData("clipBias", bias);
95925
+ this.clipBias = bias;
95926
+ }
95927
+ /**
95928
+ * Dispose the mirror and its resources
95929
+ */
95930
+
95931
+ }, {
95932
+ key: "dispose",
95933
+ value: function dispose() {
95934
+ if (this.renderTarget) {
95935
+ this.renderTarget.dispose();
95936
+ }
95937
+
95938
+ if (this.mirrorMaterial) {
95939
+ this.mirrorMaterial.dispose();
95940
+ }
95941
+
95942
+ _get(_getPrototypeOf(MirrorElement.prototype), "dispose", this).call(this);
95943
+ }
95944
+ /**
95945
+ * Factory method for deserialization
95946
+ * @param {object} data - The serialized data
95947
+ * @returns {MirrorElement} A new MirrorElement instance
95948
+ */
95949
+
95950
+ }], [{
95951
+ key: "create",
95952
+ value: function create(data) {
95953
+ return new MirrorElement(data.options || data);
95954
+ }
95955
+ }]);
95956
+
95957
+ return MirrorElement;
94969
95958
  }(Element$1);let Importer = /*#__PURE__*/function () {
94970
95959
  function Importer() {
94971
95960
  _classCallCheck(this, Importer);
@@ -95217,6 +96206,57 @@ let Sky = /*#__PURE__*/function (_Element) {
95217
96206
  sky.setSun(sunInclination, sunAzimuth, sunDistance);
95218
96207
  }
95219
96208
  }
96209
+ }, {
96210
+ key: "completeSkyboxCreation",
96211
+ value: function completeSkyboxCreation(skybox, skyboxData, options) {
96212
+ Importer.completeCommonCreationSteps(skybox, skyboxData, { ...options,
96213
+ skipScale: true
96214
+ }); // Skybox texture is set during construction via the texture option
96215
+ // No additional setup needed beyond common creation steps
96216
+ }
96217
+ }, {
96218
+ key: "completeWaterCreation",
96219
+ value: function completeWaterCreation(water, waterData, options) {
96220
+ Importer.completeCommonCreationSteps(water, waterData, { ...options,
96221
+ skipScale: true
96222
+ });
96223
+ const waterOptions = waterData.options || {};
96224
+ const {
96225
+ alpha,
96226
+ distortionScale,
96227
+ size
96228
+ } = waterOptions;
96229
+
96230
+ if (alpha !== undefined) {
96231
+ water.setAlpha(alpha);
96232
+ }
96233
+
96234
+ if (distortionScale !== undefined) {
96235
+ water.setDistortionScale(distortionScale);
96236
+ }
96237
+
96238
+ if (size !== undefined) {
96239
+ water.setSize(size);
96240
+ }
96241
+ }
96242
+ }, {
96243
+ key: "completeMirrorCreation",
96244
+ value: function completeMirrorCreation(mirror, mirrorData, options) {
96245
+ Importer.completeCommonCreationSteps(mirror, mirrorData, options);
96246
+ const mirrorOptions = mirrorData.options || {};
96247
+ const {
96248
+ color,
96249
+ clipBias
96250
+ } = mirrorOptions;
96251
+
96252
+ if (color !== undefined) {
96253
+ mirror.setColor(color);
96254
+ }
96255
+
96256
+ if (clipBias !== undefined) {
96257
+ mirror.setClipBias(clipBias);
96258
+ }
96259
+ }
95220
96260
  }, {
95221
96261
  key: "completeSpriteCreation",
95222
96262
  value: async function completeSpriteCreation(sprite, spriteData, options) {
@@ -95315,12 +96355,17 @@ let Sky = /*#__PURE__*/function (_Element) {
95315
96355
 
95316
96356
  for (const cameraData of cameras) {
95317
96357
  if (cameraData.entitySubType === ENTITY_TYPES.CAMERA.SUBTYPES.GAME) {
95318
- // Create a Camera entity that will appear in the hierarchy (for editor)
96358
+ // Use config defaults, but prefer saved values if they're reasonable
96359
+ // (old default was 100, which is too small for most scenes)
96360
+ const configFar = Config$1.camera().far;
96361
+ const savedFar = cameraData.far;
96362
+ const cameraFar = savedFar && savedFar > 100 ? savedFar : configFar; // Create a Camera entity that will appear in the hierarchy (for editor)
96363
+
95319
96364
  const gameCamera = new Camera({
95320
96365
  name: cameraData.name || "Game Camera",
95321
- fov: cameraData.fov || 75,
95322
- near: cameraData.near || 0.1,
95323
- far: cameraData.far || 3000000,
96366
+ fov: cameraData.fov || Config$1.camera().fov,
96367
+ near: cameraData.near || Config$1.camera().near,
96368
+ far: cameraFar,
95324
96369
  serializable: true
95325
96370
  });
95326
96371
  gameCamera.setEntitySubtype(ENTITY_TYPES.CAMERA.SUBTYPES.GAME); // Set position and rotation
@@ -95340,7 +96385,7 @@ let Sky = /*#__PURE__*/function (_Element) {
95340
96385
  if (cameraData.rotation) sceneCamera.setRotation(cameraData.rotation);
95341
96386
  if (cameraData.fov) sceneCamera.setFov(cameraData.fov);
95342
96387
  if (cameraData.near) sceneCamera.setNear(cameraData.near);
95343
- if (cameraData.far) sceneCamera.setFar(cameraData.far);
96388
+ sceneCamera.setFar(cameraFar);
95344
96389
  }
95345
96390
  } // Use for...of to properly await async completeElementCreation calls
95346
96391
 
@@ -95427,6 +96472,18 @@ let Sky = /*#__PURE__*/function (_Element) {
95427
96472
  Importer.completeSkyCreation(Sky.create(elementData), elementData, options);
95428
96473
  break;
95429
96474
 
96475
+ case ENTITY_TYPES.SCENERY.SUBTYPES.SKYBOX:
96476
+ Importer.completeSkyboxCreation(Skybox.create(elementData), elementData, options);
96477
+ break;
96478
+
96479
+ case ENTITY_TYPES.SCENERY.SUBTYPES.WATER:
96480
+ Importer.completeWaterCreation(Water.create(elementData), elementData, options);
96481
+ break;
96482
+
96483
+ case ENTITY_TYPES.SCENERY.SUBTYPES.MIRROR:
96484
+ Importer.completeMirrorCreation(MirrorElement.create(elementData), elementData, options);
96485
+ break;
96486
+
95430
96487
  default:
95431
96488
  console.warn(IMPORTER_ERROR_UNKNOWN_ELEMENT_SUBTYPE, elementData.entitySubType);
95432
96489
  }
@@ -95434,7 +96491,7 @@ let Sky = /*#__PURE__*/function (_Element) {
95434
96491
  } catch (error) {
95435
96492
  console.error(IMPORTER_ERROR_ELEMENT_CREATION, elementData.name, elementData.entitySubType, error);
95436
96493
  }
95437
- } // adding children to elements
96494
+ } // adding children to elements (legacy children array format)
95438
96495
 
95439
96496
 
95440
96497
  for (const elementData of elements) {
@@ -95452,6 +96509,21 @@ let Sky = /*#__PURE__*/function (_Element) {
95452
96509
  }
95453
96510
  }
95454
96511
  }
96512
+ } // Handle parentUUID relationships (new format from database parentId)
96513
+ // Use parent.add(child) instead of child.reparent(parent) to preserve
96514
+ // the saved local position. reparent() uses attach() which preserves
96515
+ // world position, but for import we want to keep the saved local position.
96516
+
96517
+
96518
+ for (const elementData of elements) {
96519
+ if (elementData.parentUUID) {
96520
+ const child = Universe$1.getByUUID(elementData.uuid);
96521
+ const parent = Universe$1.getByUUID(elementData.parentUUID);
96522
+
96523
+ if (child && parent && parent.add) {
96524
+ await parent.add(child);
96525
+ }
96526
+ }
95455
96527
  }
95456
96528
 
95457
96529
  lights.forEach(data => {
@@ -95530,7 +96602,54 @@ let Sky = /*#__PURE__*/function (_Element) {
95530
96602
  } catch (error) {
95531
96603
  console.error(IMPORTER_ERROR_PARTICLE_CREATION, data.name, data.preset, error.stack);
95532
96604
  }
95533
- });
96605
+ }); // Handle parentUUID for lights
96606
+
96607
+ for (const lightData of lights) {
96608
+ if (lightData.parentUUID) {
96609
+ const child = Universe$1.getByUUID(lightData.uuid);
96610
+ const parent = Universe$1.getByUUID(lightData.parentUUID);
96611
+
96612
+ if (child && parent && parent.add) {
96613
+ await parent.add(child);
96614
+ }
96615
+ }
96616
+ } // Handle parentUUID for sounds
96617
+
96618
+
96619
+ for (const soundData of allSounds) {
96620
+ if (soundData.parentUUID) {
96621
+ const child = Universe$1.getByUUID(soundData.uuid);
96622
+ const parent = Universe$1.getByUUID(soundData.parentUUID);
96623
+
96624
+ if (child && parent && parent.add) {
96625
+ await parent.add(child);
96626
+ }
96627
+ }
96628
+ } // Handle parentUUID for particles
96629
+
96630
+
96631
+ for (const particleData of particles) {
96632
+ if (particleData.parentUUID) {
96633
+ const child = Universe$1.getByUUID(particleData.uuid);
96634
+ const parent = Universe$1.getByUUID(particleData.parentUUID);
96635
+
96636
+ if (child && parent && parent.add) {
96637
+ await parent.add(child);
96638
+ }
96639
+ }
96640
+ } // Handle parentUUID for cameras
96641
+
96642
+
96643
+ for (const cameraData of cameras) {
96644
+ if (cameraData.parentUUID) {
96645
+ const child = Universe$1.getByUUID(cameraData.uuid);
96646
+ const parent = Universe$1.getByUUID(cameraData.parentUUID);
96647
+
96648
+ if (child && parent && parent.add) {
96649
+ await parent.add(child);
96650
+ }
96651
+ }
96652
+ }
95534
96653
  }
95535
96654
  }]);
95536
96655
 
@@ -97224,7 +98343,30 @@ let SunLight = /*#__PURE__*/function (_Light) {
97224
98343
  targetHolderSize = 0.05
97225
98344
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
97226
98345
  this.helper = new DirectionalLightHelper(this.getBody(), 5);
97227
- this.shadowHelper = new CameraHelper(this.getBody().shadow.camera);
98346
+ this.shadowHelper = new CameraHelper(this.getBody().shadow.camera); // Set to layer 1 ONLY so mirrors don't render light helpers
98347
+ // Disable depth test so helpers always render on top of sky/water
98348
+
98349
+ const setMaterialDepth = material => {
98350
+ if (!material) return;
98351
+ const mats = Array.isArray(material) ? material : [material];
98352
+ mats.forEach(mat => {
98353
+ mat.depthTest = false;
98354
+ mat.depthWrite = false;
98355
+ mat.transparent = true;
98356
+ mat.needsUpdate = true;
98357
+ });
98358
+ };
98359
+
98360
+ [this.helper, this.shadowHelper].forEach(helper => {
98361
+ helper.layers.set(1);
98362
+ helper.renderOrder = 999;
98363
+ setMaterialDepth(helper.material);
98364
+ helper.traverse(child => {
98365
+ child.layers.set(1);
98366
+ child.renderOrder = 999;
98367
+ setMaterialDepth(child.material);
98368
+ });
98369
+ });
97228
98370
  Scene$1.add(this.helper, null, false);
97229
98371
  Scene$1.add(this.shadowHelper, null, false);
97230
98372
  this.addHolder(holderName, holderSize);
@@ -97485,7 +98627,30 @@ let PointLight = /*#__PURE__*/function (_Light) {
97485
98627
  holderSize = 0.05
97486
98628
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
97487
98629
  this.helper = new PointLightHelper(this.getBody(), 2, GREEN$2);
97488
- this.shadowHelper = new CameraHelper(this.getBody().shadow.camera);
98630
+ this.shadowHelper = new CameraHelper(this.getBody().shadow.camera); // Set to layer 1 ONLY so mirrors don't render light helpers
98631
+ // Disable depth test so helpers always render on top of sky/water
98632
+
98633
+ const setMaterialDepth = material => {
98634
+ if (!material) return;
98635
+ const mats = Array.isArray(material) ? material : [material];
98636
+ mats.forEach(mat => {
98637
+ mat.depthTest = false;
98638
+ mat.depthWrite = false;
98639
+ mat.transparent = true;
98640
+ mat.needsUpdate = true;
98641
+ });
98642
+ };
98643
+
98644
+ [this.helper, this.shadowHelper].forEach(helper => {
98645
+ helper.layers.set(1);
98646
+ helper.renderOrder = 999;
98647
+ setMaterialDepth(helper.material);
98648
+ helper.traverse(child => {
98649
+ child.layers.set(1);
98650
+ child.renderOrder = 999;
98651
+ setMaterialDepth(child.material);
98652
+ });
98653
+ });
97489
98654
  Scene$1.add(this.helper, null, false);
97490
98655
  Scene$1.add(this.shadowHelper, null, false);
97491
98656
  this.addHolder(holderName, holderSize);
@@ -97802,7 +98967,30 @@ let SpotLight = /*#__PURE__*/function (_Light) {
97802
98967
  targetHolderSize = 0.05
97803
98968
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
97804
98969
  this.helper = new SpotLightHelper(this.getBody(), GREEN$1);
97805
- this.shadowHelper = new CameraHelper(this.getBody().shadow.camera);
98970
+ this.shadowHelper = new CameraHelper(this.getBody().shadow.camera); // Set to layer 1 ONLY so mirrors don't render light helpers
98971
+ // Disable depth test so helpers always render on top of sky/water
98972
+
98973
+ const setMaterialDepth = material => {
98974
+ if (!material) return;
98975
+ const mats = Array.isArray(material) ? material : [material];
98976
+ mats.forEach(mat => {
98977
+ mat.depthTest = false;
98978
+ mat.depthWrite = false;
98979
+ mat.transparent = true;
98980
+ mat.needsUpdate = true;
98981
+ });
98982
+ };
98983
+
98984
+ [this.helper, this.shadowHelper].forEach(helper => {
98985
+ helper.layers.set(1);
98986
+ helper.renderOrder = 999;
98987
+ setMaterialDepth(helper.material);
98988
+ helper.traverse(child => {
98989
+ child.layers.set(1);
98990
+ child.renderOrder = 999;
98991
+ setMaterialDepth(child.material);
98992
+ });
98993
+ });
97806
98994
  Scene$1.add(this.helper, null, false);
97807
98995
  Scene$1.add(this.shadowHelper, null, false);
97808
98996
  this.addHolder(holderName, holderSize);
@@ -97998,7 +99186,28 @@ let HemisphereLight = /*#__PURE__*/function (_Light) {
97998
99186
  holderName = "hemispherelightholder",
97999
99187
  holderSize = 0.05
98000
99188
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
98001
- this.helper = new HemisphereLightHelper(this.getBody(), 2, GREEN);
99189
+ this.helper = new HemisphereLightHelper(this.getBody(), 2, GREEN); // Set to layer 1 ONLY so mirrors don't render light helpers
99190
+ // Disable depth test so helpers always render on top of sky/water
99191
+
99192
+ const setMaterialDepth = material => {
99193
+ if (!material) return;
99194
+ const mats = Array.isArray(material) ? material : [material];
99195
+ mats.forEach(mat => {
99196
+ mat.depthTest = false;
99197
+ mat.depthWrite = false;
99198
+ mat.transparent = true;
99199
+ mat.needsUpdate = true;
99200
+ });
99201
+ };
99202
+
99203
+ this.helper.layers.set(1);
99204
+ this.helper.renderOrder = 999;
99205
+ setMaterialDepth(this.helper.material);
99206
+ this.helper.traverse(child => {
99207
+ child.layers.set(1);
99208
+ child.renderOrder = 999;
99209
+ setMaterialDepth(child.material);
99210
+ });
98002
99211
  this.addHolder(holderName, holderSize);
98003
99212
  this.isUsingHelper = true;
98004
99213
  Scene$1.add(this.helper, null, false);
@@ -98090,236 +99299,7 @@ let HemisphereLight = /*#__PURE__*/function (_Light) {
98090
99299
  }]);
98091
99300
 
98092
99301
  return Atmosphere;
98093
- }();let Mirror = /*#__PURE__*/function (_Object3D) {
98094
- _inherits(Mirror, _Object3D);
98095
-
98096
- var _super = _createSuper(Mirror);
98097
-
98098
- _createClass(Mirror, [{
98099
- key: "mirroruniforms",
98100
- value: function mirroruniforms() {
98101
- return {
98102
- "mirrorColor": {
98103
- type: "c",
98104
- value: new Color$1(0x7F7F7F)
98105
- },
98106
- "mirrorSampler": {
98107
- type: "t",
98108
- value: null
98109
- },
98110
- "textureMatrix": {
98111
- type: "m4",
98112
- value: new Matrix4()
98113
- }
98114
- };
98115
- }
98116
- }, {
98117
- key: "mirrorvertex",
98118
- value: function mirrorvertex() {
98119
- return ["uniform mat4 textureMatrix;", "varying vec4 mirrorCoord;", "void main() {", "vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);", "vec4 worldPosition = modelMatrix * vec4(position, 1.0);", "mirrorCoord = textureMatrix * worldPosition;", "gl_Position = projectionMatrix * mvPosition;", "}"].join("\n");
98120
- }
98121
- }, {
98122
- key: "mirrorfragment",
98123
- value: function mirrorfragment() {
98124
- return ["uniform vec3 mirrorColor;", "uniform sampler2D mirrorSampler;", "varying vec4 mirrorCoord;", "float blendOverlay(float base, float blend) {", "return(base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));", "}", "void main() {", "vec4 color = texture2DProj(mirrorSampler, mirrorCoord);", "color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b), 1.0);", "gl_FragColor = color;", "}"].join("\n");
98125
- }
98126
- }]);
98127
-
98128
- function Mirror(renderer, camera, scene, options) {
98129
- var _this;
98130
-
98131
- _classCallCheck(this, Mirror);
98132
-
98133
- _this = _super.call(this);
98134
- _this.name = 'mirror_' + _this.id;
98135
- options = options || {};
98136
- _this.matrixNeedsUpdate = true;
98137
- var width = options.textureWidth !== undefined ? options.textureWidth : 512;
98138
- var height = options.textureHeight !== undefined ? options.textureHeight : 512;
98139
- _this.clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
98140
- var mirrorColor = options.color !== undefined ? new Color$1(options.color) : new Color$1(0x7F7F7F);
98141
- _this.renderer = renderer;
98142
- _this.mirrorPlane = new Plane$1();
98143
- _this.normal = new Vector3$1(0, 0, 1);
98144
- _this.mirrorWorldPosition = new Vector3$1();
98145
- _this.cameraWorldPosition = new Vector3$1();
98146
- _this.rotationMatrix = new Matrix4();
98147
- _this.lookAtPosition = new Vector3$1(0, 0, -1);
98148
- _this.clipPlane = new Vector4(); // For debug only, show the normal and plane of the mirror
98149
-
98150
- var debugMode = options.debugMode !== undefined ? options.debugMode : false;
98151
-
98152
- if (debugMode) {
98153
- // var arrow = new ArrowHelper(new Vector3(0, 0, 1), new Vector3(0, 0, 0), 10, 0xffff80);
98154
- // var planeGeometry = new Geometry();
98155
- // planeGeometry.vertices.push(new Vector3(- 10, - 10, 0));
98156
- // planeGeometry.vertices.push(new Vector3(10, - 10, 0));
98157
- // planeGeometry.vertices.push(new Vector3(10, 10, 0));
98158
- // planeGeometry.vertices.push(new Vector3(- 10, 10, 0));
98159
- // planeGeometry.vertices.push(planeGeometry.vertices[ 0 ]);
98160
- // var plane = new Line(planeGeometry, new LineBasicMaterial({ color: 0xffff80 }));
98161
- // this.add(arrow);
98162
- // this.add(plane);
98163
- console.log('[Mage] Mirror is trying to use deprecated geometry.');
98164
- }
98165
-
98166
- if (camera instanceof PerspectiveCamera) {
98167
- _this.camera = camera;
98168
- } else {
98169
- _this.camera = new PerspectiveCamera();
98170
- }
98171
-
98172
- _this.textureMatrix = new Matrix4();
98173
- _this.mirrorCamera = _this.camera.clone();
98174
- _this.mirrorCamera.matrixAutoUpdate = true;
98175
- var parameters = {
98176
- minFilter: LinearFilter,
98177
- magFilter: LinearFilter,
98178
- format: RGBFormat,
98179
- stencilBuffer: false
98180
- };
98181
- _this.renderTarget = new WebGLRenderTarget(width, height, parameters);
98182
- _this.renderTarget2 = new WebGLRenderTarget(width, height, parameters);
98183
- _this.material = new ShaderMaterial({
98184
- fragmentShader: _this.mirrorfragment(),
98185
- vertexShader: _this.mirrorvertex(),
98186
- uniforms: UniformsUtils.clone(_this.mirroruniforms())
98187
- });
98188
- _this.material.uniforms.mirrorSampler.value = _this.renderTarget.texture;
98189
- _this.material.uniforms.mirrorColor.value = mirrorColor;
98190
- _this.material.uniforms.textureMatrix.value = _this.textureMatrix;
98191
-
98192
- if (!MathUtils.isPowerOfTwo(width) || !MathUtils.isPowerOfTwo(height)) {
98193
- _this.renderTarget.texture.generateMipmaps = false;
98194
- _this.renderTarget2.texture.generateMipmaps = false;
98195
- }
98196
-
98197
- _this.updateTextureMatrix();
98198
-
98199
- _this.render();
98200
-
98201
- return _this;
98202
- }
98203
-
98204
- _createClass(Mirror, [{
98205
- key: "renderWithMirror",
98206
- value: function renderWithMirror(otherMirror) {
98207
- // update the mirror matrix to mirror the current view
98208
- this.updateTextureMatrix();
98209
- this.matrixNeedsUpdate = false; // set the camera of the other mirror so the mirrored view is the reference view
98210
-
98211
- var tempCamera = otherMirror.camera;
98212
- otherMirror.camera = this.mirrorCamera; // render the other mirror in temp texture
98213
-
98214
- otherMirror.renderTemp();
98215
- otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture; // render the current mirror
98216
-
98217
- this.render();
98218
- this.matrixNeedsUpdate = true; // restore material and camera of other mirror
98219
-
98220
- otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture;
98221
- otherMirror.camera = tempCamera; // restore texture matrix of other mirror
98222
-
98223
- otherMirror.updateTextureMatrix();
98224
- }
98225
- }, {
98226
- key: "renderWithMirror",
98227
- value: function renderWithMirror(otherMirror) {
98228
- // update the mirror matrix to mirror the current view
98229
- this.updateTextureMatrix();
98230
- this.matrixNeedsUpdate = false; // set the camera of the other mirror so the mirrored view is the reference view
98231
-
98232
- const tempCamera = otherMirror.camera;
98233
- otherMirror.camera = this.mirrorCamera; // render the other mirror in temp texture
98234
-
98235
- otherMirror.renderTemp();
98236
- otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture; // render the current mirror
98237
-
98238
- this.render();
98239
- this.matrixNeedsUpdate = true; // restore material and camera of other mirror
98240
-
98241
- otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture;
98242
- otherMirror.camera = tempCamera; // restore texture matrix of other mirror
98243
-
98244
- otherMirror.updateTextureMatrix();
98245
- }
98246
- }, {
98247
- key: "updateTextureMatrix",
98248
- value: function updateTextureMatrix() {
98249
- this.updateMatrixWorld();
98250
- this.camera.updateMatrixWorld();
98251
- this.mirrorWorldPosition.setFromMatrixPosition(this.matrixWorld);
98252
- this.cameraWorldPosition.setFromMatrixPosition(this.camera.matrixWorld);
98253
- this.rotationMatrix.extractRotation(this.matrixWorld);
98254
- this.normal.set(0, 0, 1);
98255
- this.normal.applyMatrix4(this.rotationMatrix);
98256
- var view = this.mirrorWorldPosition.clone().sub(this.cameraWorldPosition);
98257
- view.reflect(this.normal).negate();
98258
- view.add(this.mirrorWorldPosition);
98259
- this.rotationMatrix.extractRotation(this.camera.matrixWorld);
98260
- this.lookAtPosition.set(0, 0, -1);
98261
- this.lookAtPosition.applyMatrix4(this.rotationMatrix);
98262
- this.lookAtPosition.add(this.cameraWorldPosition);
98263
- var target = this.mirrorWorldPosition.clone().sub(this.lookAtPosition);
98264
- target.reflect(this.normal).negate();
98265
- target.add(this.mirrorWorldPosition);
98266
- this.up.set(0, -1, 0);
98267
- this.up.applyMatrix4(this.rotationMatrix);
98268
- this.up.reflect(this.normal).negate();
98269
- this.mirrorCamera.position.copy(view);
98270
- this.mirrorCamera.up = this.up;
98271
- this.mirrorCamera.lookAt(target);
98272
- this.mirrorCamera.updateProjectionMatrix();
98273
- this.mirrorCamera.updateMatrixWorld();
98274
- this.mirrorCamera.matrixWorldInverse.getInverse(this.mirrorCamera.matrixWorld); // Update the texture matrix
98275
-
98276
- this.textureMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
98277
- this.textureMatrix.multiply(this.mirrorCamera.projectionMatrix);
98278
- this.textureMatrix.multiply(this.mirrorCamera.matrixWorldInverse); // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
98279
- // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
98280
-
98281
- this.mirrorPlane.setFromNormalAndCoplanarPoint(this.normal, this.mirrorWorldPosition);
98282
- this.mirrorPlane.applyMatrix4(this.mirrorCamera.matrixWorldInverse);
98283
- this.clipPlane.set(this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant);
98284
- var q = new Vector4();
98285
- var projectionMatrix = this.mirrorCamera.projectionMatrix;
98286
- q.x = (window.Math.sign(this.clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
98287
- q.y = (window.Math.sign(this.clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
98288
- q.z = -1.0;
98289
- q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]; // Calculate the scaled plane vector
98290
-
98291
- var c = new Vector4();
98292
- c = this.clipPlane.multiplyScalar(2.0 / this.clipPlane.dot(q)); // Replacing the third row of the projection matrix
98293
-
98294
- projectionMatrix.elements[2] = c.x;
98295
- projectionMatrix.elements[6] = c.y;
98296
- projectionMatrix.elements[10] = c.z + 1.0 - this.clipBias;
98297
- projectionMatrix.elements[14] = c.w;
98298
- }
98299
- }, {
98300
- key: "render",
98301
- value: function render() {
98302
- if (this.matrixNeedsUpdate) this.updateTextureMatrix();
98303
- this.matrixNeedsUpdate = true; // Render the mirrored view of the current scene into the target texture
98304
-
98305
- var scene = this;
98306
-
98307
- while (scene.parent !== null) {
98308
- scene = scene.parent;
98309
- }
98310
-
98311
- if (scene !== undefined && scene instanceof Scene$2) {
98312
- // We can't render ourself to ourself
98313
- var visible = this.material.visible;
98314
- this.material.visible = false;
98315
- this.renderer.render(scene, this.mirrorCamera, this.renderTarget, true);
98316
- this.material.visible = visible;
98317
- }
98318
- }
98319
- }]);
98320
-
98321
- return Mirror;
98322
- }(Object3D);let OceanMain = /*#__PURE__*/function () {
99302
+ }();let OceanMain = /*#__PURE__*/function () {
98323
99303
  function OceanMain() {
98324
99304
  _classCallCheck(this, OceanMain);
98325
99305
  }
@@ -99057,311 +100037,236 @@ let Ocean = /*#__PURE__*/function () {
99057
100037
  }]);
99058
100038
 
99059
100039
  return Ocean;
99060
- }();var WaterMesh = function (geometry, options) {
99061
- Mesh.call(this, geometry);
99062
- var scope = this;
99063
- options = options || {};
99064
- var textureWidth = options.textureWidth !== undefined ? options.textureWidth : 512;
99065
- var textureHeight = options.textureHeight !== undefined ? options.textureHeight : 512;
99066
- var clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
99067
- var alpha = options.alpha !== undefined ? options.alpha : 1.0;
99068
- var time = options.time !== undefined ? options.time : 0.0;
99069
- var normalSampler = options.waterNormals !== undefined ? options.waterNormals : null;
99070
- var sunDirection = options.sunDirection !== undefined ? options.sunDirection : new Vector3$1(0.70707, 0.70707, 0.0);
99071
- var sunColor = new Color$1(options.sunColor !== undefined ? options.sunColor : 0xffffff);
99072
- var waterColor = new Color$1(options.waterColor !== undefined ? options.waterColor : 0x7F7F7F);
99073
- var eye = options.eye !== undefined ? options.eye : new Vector3$1(0, 0, 0);
99074
- var distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0;
99075
- var side = options.side !== undefined ? options.side : FrontSide;
99076
- var fog = options.fog !== undefined ? options.fog : false; //
99077
-
99078
- var mirrorPlane = new Plane$1();
99079
- var normal = new Vector3$1();
99080
- var mirrorWorldPosition = new Vector3$1();
99081
- var cameraWorldPosition = new Vector3$1();
99082
- var rotationMatrix = new Matrix4();
99083
- var lookAtPosition = new Vector3$1(0, 0, -1);
99084
- var clipPlane = new Vector4();
99085
- var view = new Vector3$1();
99086
- var target = new Vector3$1();
99087
- var q = new Vector4();
99088
- var textureMatrix = new Matrix4();
99089
- var mirrorCamera = new PerspectiveCamera();
99090
- var parameters = {
99091
- minFilter: LinearFilter,
99092
- magFilter: LinearFilter,
99093
- format: RGBFormat
99094
- };
99095
- var renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, parameters);
99096
-
99097
- if (!MathUtils.isPowerOfTwo(textureWidth) || !MathUtils.isPowerOfTwo(textureHeight)) {
99098
- renderTarget.texture.generateMipmaps = false;
99099
- }
99100
-
99101
- var mirrorShader = {
99102
- uniforms: UniformsUtils.merge([UniformsLib['fog'], UniformsLib['lights'], {
99103
- 'normalSampler': {
99104
- value: null
99105
- },
99106
- 'mirrorSampler': {
99107
- value: null
99108
- },
99109
- 'alpha': {
99110
- value: 1.0
99111
- },
99112
- 'time': {
99113
- value: 0.0
99114
- },
99115
- 'size': {
99116
- value: 1.0
99117
- },
99118
- 'distortionScale': {
99119
- value: 20.0
99120
- },
99121
- 'textureMatrix': {
99122
- value: new Matrix4()
99123
- },
99124
- 'sunColor': {
99125
- value: new Color$1(0x7F7F7F)
99126
- },
99127
- 'sunDirection': {
99128
- value: new Vector3$1(0.70707, 0.70707, 0)
99129
- },
99130
- 'eye': {
99131
- value: new Vector3$1()
99132
- },
99133
- 'waterColor': {
99134
- value: new Color$1(0x555555)
99135
- }
99136
- }]),
99137
- vertexShader: ['uniform mat4 textureMatrix;', 'uniform float time;', 'varying vec4 mirrorCoord;', 'varying vec4 worldPosition;', '#include <common>', '#include <fog_pars_vertex>', '#include <shadowmap_pars_vertex>', '#include <logdepthbuf_pars_vertex>', 'void main() {', ' mirrorCoord = modelMatrix * vec4( position, 1.0 );', ' worldPosition = mirrorCoord.xyzw;', ' mirrorCoord = textureMatrix * mirrorCoord;', ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', ' gl_Position = projectionMatrix * mvPosition;', '#include <beginnormal_vertex>', '#include <defaultnormal_vertex>', '#include <logdepthbuf_vertex>', '#include <fog_vertex>', '#include <shadowmap_vertex>', '}'].join('\n'),
99138
- fragmentShader: ['uniform sampler2D mirrorSampler;', 'uniform float alpha;', 'uniform float time;', 'uniform float size;', 'uniform float distortionScale;', 'uniform sampler2D normalSampler;', 'uniform vec3 sunColor;', 'uniform vec3 sunDirection;', 'uniform vec3 eye;', 'uniform vec3 waterColor;', 'varying vec4 mirrorCoord;', 'varying vec4 worldPosition;', 'vec4 getNoise( vec2 uv ) {', ' vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);', ' vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );', ' vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );', ' vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );', ' vec4 noise = texture2D( normalSampler, uv0 ) +', ' texture2D( normalSampler, uv1 ) +', ' texture2D( normalSampler, uv2 ) +', ' texture2D( normalSampler, uv3 );', ' return noise * 0.5 - 1.0;', '}', 'void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {', ' vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );', ' float direction = max( 0.0, dot( eyeDirection, reflection ) );', ' specularColor += pow( direction, shiny ) * sunColor * spec;', ' diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;', '}', '#include <common>', '#include <packing>', '#include <bsdfs>', '#include <fog_pars_fragment>', '#include <logdepthbuf_pars_fragment>', '#include <lights_pars_begin>', '#include <shadowmap_pars_fragment>', '#include <shadowmask_pars_fragment>', 'void main() {', '#include <logdepthbuf_fragment>', ' vec4 noise = getNoise( worldPosition.xz * size );', ' vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );', ' vec3 diffuseLight = vec3(0.0);', ' vec3 specularLight = vec3(0.0);', ' vec3 worldToEye = eye-worldPosition.xyz;', ' vec3 eyeDirection = normalize( worldToEye );', ' sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );', ' float distance = length(worldToEye);', ' vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;', ' vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.w + distortion ) );', ' float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );', ' float rf0 = 0.3;', ' float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );', ' vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;', ' vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);', ' vec3 outgoingLight = albedo;', ' gl_FragColor = vec4( outgoingLight, alpha );', '#include <tonemapping_fragment>', '#include <fog_fragment>', '}'].join('\n')
99139
- };
99140
- var material = new ShaderMaterial({
99141
- fragmentShader: mirrorShader.fragmentShader,
99142
- vertexShader: mirrorShader.vertexShader,
99143
- uniforms: UniformsUtils.clone(mirrorShader.uniforms),
99144
- lights: true,
99145
- side: side,
99146
- fog: fog
99147
- });
99148
- material.uniforms['mirrorSampler'].value = renderTarget.texture;
99149
- material.uniforms['textureMatrix'].value = textureMatrix;
99150
- material.uniforms['alpha'].value = alpha;
99151
- material.uniforms['time'].value = time;
99152
- material.uniforms['normalSampler'].value = normalSampler;
99153
- material.uniforms['sunColor'].value = sunColor;
99154
- material.uniforms['waterColor'].value = waterColor;
99155
- material.uniforms['sunDirection'].value = sunDirection;
99156
- material.uniforms['distortionScale'].value = distortionScale;
99157
- material.uniforms['eye'].value = eye;
99158
- scope.material = material;
99159
-
99160
- scope.onBeforeRender = function (renderer, scene, camera) {
99161
- mirrorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
99162
- cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
99163
- rotationMatrix.extractRotation(scope.matrixWorld);
99164
- normal.set(0, 0, 1);
99165
- normal.applyMatrix4(rotationMatrix);
99166
- view.subVectors(mirrorWorldPosition, cameraWorldPosition); // Avoid rendering when mirror is facing away
99167
-
99168
- if (view.dot(normal) > 0) return;
99169
- view.reflect(normal).negate();
99170
- view.add(mirrorWorldPosition);
99171
- rotationMatrix.extractRotation(camera.matrixWorld);
99172
- lookAtPosition.set(0, 0, -1);
99173
- lookAtPosition.applyMatrix4(rotationMatrix);
99174
- lookAtPosition.add(cameraWorldPosition);
99175
- target.subVectors(mirrorWorldPosition, lookAtPosition);
99176
- target.reflect(normal).negate();
99177
- target.add(mirrorWorldPosition);
99178
- mirrorCamera.position.copy(view);
99179
- mirrorCamera.up.set(0, 1, 0);
99180
- mirrorCamera.up.applyMatrix4(rotationMatrix);
99181
- mirrorCamera.up.reflect(normal);
99182
- mirrorCamera.lookAt(target);
99183
- mirrorCamera.far = camera.far; // Used in WebGLBackground
99184
-
99185
- mirrorCamera.updateMatrixWorld();
99186
- mirrorCamera.projectionMatrix.copy(camera.projectionMatrix); // Update the texture matrix
100040
+ }();let Mirror = /*#__PURE__*/function (_Object3D) {
100041
+ _inherits(Mirror, _Object3D);
99187
100042
 
99188
- textureMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
99189
- textureMatrix.multiply(mirrorCamera.projectionMatrix);
99190
- textureMatrix.multiply(mirrorCamera.matrixWorldInverse); // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
99191
- // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
100043
+ var _super = _createSuper(Mirror);
99192
100044
 
99193
- mirrorPlane.setFromNormalAndCoplanarPoint(normal, mirrorWorldPosition);
99194
- mirrorPlane.applyMatrix4(mirrorCamera.matrixWorldInverse);
99195
- clipPlane.set(mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant);
99196
- var projectionMatrix = mirrorCamera.projectionMatrix;
99197
- q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
99198
- q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
99199
- q.z = -1.0;
99200
- q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]; // Calculate the scaled plane vector
100045
+ _createClass(Mirror, [{
100046
+ key: "mirroruniforms",
100047
+ value: function mirroruniforms() {
100048
+ return {
100049
+ "mirrorColor": {
100050
+ type: "c",
100051
+ value: new Color$1(0x7F7F7F)
100052
+ },
100053
+ "mirrorSampler": {
100054
+ type: "t",
100055
+ value: null
100056
+ },
100057
+ "textureMatrix": {
100058
+ type: "m4",
100059
+ value: new Matrix4()
100060
+ }
100061
+ };
100062
+ }
100063
+ }, {
100064
+ key: "mirrorvertex",
100065
+ value: function mirrorvertex() {
100066
+ return ["uniform mat4 textureMatrix;", "varying vec4 mirrorCoord;", "void main() {", "vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);", "vec4 worldPosition = modelMatrix * vec4(position, 1.0);", "mirrorCoord = textureMatrix * worldPosition;", "gl_Position = projectionMatrix * mvPosition;", "}"].join("\n");
100067
+ }
100068
+ }, {
100069
+ key: "mirrorfragment",
100070
+ value: function mirrorfragment() {
100071
+ return ["uniform vec3 mirrorColor;", "uniform sampler2D mirrorSampler;", "varying vec4 mirrorCoord;", "float blendOverlay(float base, float blend) {", "return(base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));", "}", "void main() {", "vec4 color = texture2DProj(mirrorSampler, mirrorCoord);", "color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b), 1.0);", "gl_FragColor = color;", "}"].join("\n");
100072
+ }
100073
+ }]);
99201
100074
 
99202
- clipPlane.multiplyScalar(2.0 / clipPlane.dot(q)); // Replacing the third row of the projection matrix
100075
+ function Mirror(renderer, camera, scene, options) {
100076
+ var _this;
99203
100077
 
99204
- projectionMatrix.elements[2] = clipPlane.x;
99205
- projectionMatrix.elements[6] = clipPlane.y;
99206
- projectionMatrix.elements[10] = clipPlane.z + 1.0 - clipBias;
99207
- projectionMatrix.elements[14] = clipPlane.w;
99208
- eye.setFromMatrixPosition(camera.matrixWorld); // Render
100078
+ _classCallCheck(this, Mirror);
99209
100079
 
99210
- if (renderer.outputEncoding !== LinearEncoding) {
99211
- console.warn('THREE.WaterMesh: WebGLRenderer must use LinearEncoding as outputEncoding.');
100080
+ _this = _super.call(this);
100081
+ _this.name = 'mirror_' + _this.id;
100082
+ options = options || {};
100083
+ _this.matrixNeedsUpdate = true;
100084
+ var width = options.textureWidth !== undefined ? options.textureWidth : 512;
100085
+ var height = options.textureHeight !== undefined ? options.textureHeight : 512;
100086
+ _this.clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
100087
+ var mirrorColor = options.color !== undefined ? new Color$1(options.color) : new Color$1(0x7F7F7F);
100088
+ _this.renderer = renderer;
100089
+ _this.mirrorPlane = new Plane$1();
100090
+ _this.normal = new Vector3$1(0, 0, 1);
100091
+ _this.mirrorWorldPosition = new Vector3$1();
100092
+ _this.cameraWorldPosition = new Vector3$1();
100093
+ _this.rotationMatrix = new Matrix4();
100094
+ _this.lookAtPosition = new Vector3$1(0, 0, -1);
100095
+ _this.clipPlane = new Vector4(); // For debug only, show the normal and plane of the mirror
99212
100096
 
99213
- scope.onBeforeRender = function () {};
100097
+ var debugMode = options.debugMode !== undefined ? options.debugMode : false;
99214
100098
 
99215
- return;
100099
+ if (debugMode) {
100100
+ // var arrow = new ArrowHelper(new Vector3(0, 0, 1), new Vector3(0, 0, 0), 10, 0xffff80);
100101
+ // var planeGeometry = new Geometry();
100102
+ // planeGeometry.vertices.push(new Vector3(- 10, - 10, 0));
100103
+ // planeGeometry.vertices.push(new Vector3(10, - 10, 0));
100104
+ // planeGeometry.vertices.push(new Vector3(10, 10, 0));
100105
+ // planeGeometry.vertices.push(new Vector3(- 10, 10, 0));
100106
+ // planeGeometry.vertices.push(planeGeometry.vertices[ 0 ]);
100107
+ // var plane = new Line(planeGeometry, new LineBasicMaterial({ color: 0xffff80 }));
100108
+ // this.add(arrow);
100109
+ // this.add(plane);
100110
+ console.log('[Mage] Mirror is trying to use deprecated geometry.');
99216
100111
  }
99217
100112
 
99218
- if (renderer.toneMapping !== NoToneMapping) {
99219
- console.warn('THREE.WaterMesh: WebGLRenderer must use NoToneMapping as toneMapping.');
99220
-
99221
- scope.onBeforeRender = function () {};
99222
-
99223
- return;
100113
+ if (camera instanceof PerspectiveCamera) {
100114
+ _this.camera = camera;
100115
+ } else {
100116
+ _this.camera = new PerspectiveCamera();
99224
100117
  }
99225
100118
 
99226
- var currentRenderTarget = renderer.getRenderTarget();
99227
- var currentXrEnabled = renderer.xr.enabled;
99228
- var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
99229
- scope.visible = false;
99230
- renderer.xr.enabled = false; // Avoid camera modification and recursion
99231
-
99232
- renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
99233
-
99234
- renderer.setRenderTarget(renderTarget);
99235
- renderer.state.buffers.depth.setMask(true); // make sure the depth buffer is writable so it can be properly cleared, see #18897
99236
-
99237
- if (renderer.autoClear === false) renderer.clear();
99238
- renderer.render(scene, mirrorCamera);
99239
- scope.visible = true;
99240
- renderer.xr.enabled = currentXrEnabled;
99241
- renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
99242
- renderer.setRenderTarget(currentRenderTarget); // Restore viewport
99243
-
99244
- var viewport = camera.viewport;
100119
+ _this.textureMatrix = new Matrix4();
100120
+ _this.mirrorCamera = _this.camera.clone();
100121
+ _this.mirrorCamera.matrixAutoUpdate = true;
100122
+ var parameters = {
100123
+ minFilter: LinearFilter,
100124
+ magFilter: LinearFilter,
100125
+ format: RGBFormat,
100126
+ stencilBuffer: false
100127
+ };
100128
+ _this.renderTarget = new WebGLRenderTarget(width, height, parameters);
100129
+ _this.renderTarget2 = new WebGLRenderTarget(width, height, parameters);
100130
+ _this.material = new ShaderMaterial({
100131
+ fragmentShader: _this.mirrorfragment(),
100132
+ vertexShader: _this.mirrorvertex(),
100133
+ uniforms: UniformsUtils.clone(_this.mirroruniforms())
100134
+ });
100135
+ _this.material.uniforms.mirrorSampler.value = _this.renderTarget.texture;
100136
+ _this.material.uniforms.mirrorColor.value = mirrorColor;
100137
+ _this.material.uniforms.textureMatrix.value = _this.textureMatrix;
99245
100138
 
99246
- if (viewport !== undefined) {
99247
- renderer.state.viewport(viewport);
100139
+ if (!MathUtils.isPowerOfTwo(width) || !MathUtils.isPowerOfTwo(height)) {
100140
+ _this.renderTarget.texture.generateMipmaps = false;
100141
+ _this.renderTarget2.texture.generateMipmaps = false;
99248
100142
  }
99249
- };
99250
- };
99251
-
99252
- WaterMesh.prototype = Object.create(Mesh.prototype);
99253
- WaterMesh.prototype.constructor = WaterMesh;
99254
- const DEFAULT_WATER_HEIGHT = 512;
99255
- const DEFAULT_WATER_WIDTH = 512;
99256
- const DEFAULT_WATER_ALPHA = 1.0;
99257
- const DEFAULT_WATER_DISTORTION_SCALE = 3.7;
99258
100143
 
99259
- let Water = /*#__PURE__*/function (_Element) {
99260
- _inherits(Water, _Element);
100144
+ _this.updateTextureMatrix();
99261
100145
 
99262
- var _super = _createSuper(Water);
100146
+ _this.render();
99263
100147
 
99264
- function Water() {
99265
- var _thisSuper, _this;
100148
+ return _this;
100149
+ }
99266
100150
 
99267
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
100151
+ _createClass(Mirror, [{
100152
+ key: "renderWithMirror",
100153
+ value: function renderWithMirror(otherMirror) {
100154
+ // update the mirror matrix to mirror the current view
100155
+ this.updateTextureMatrix();
100156
+ this.matrixNeedsUpdate = false; // set the camera of the other mirror so the mirrored view is the reference view
99268
100157
 
99269
- _classCallCheck(this, Water);
100158
+ var tempCamera = otherMirror.camera;
100159
+ otherMirror.camera = this.mirrorCamera; // render the other mirror in temp texture
99270
100160
 
99271
- _this = _super.call(this, options);
100161
+ otherMirror.renderTemp();
100162
+ otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture; // render the current mirror
99272
100163
 
99273
- _defineProperty$1(_assertThisInitialized(_this), "update", dt => {
99274
- _get((_thisSuper = _assertThisInitialized(_this), _getPrototypeOf(Water.prototype)), "update", _thisSuper).call(_thisSuper, dt);
100164
+ this.render();
100165
+ this.matrixNeedsUpdate = true; // restore material and camera of other mirror
99275
100166
 
99276
- _this.getBody().material.uniforms.time.value += dt; //1.0 / 60.0;
99277
- });
100167
+ otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture;
100168
+ otherMirror.camera = tempCamera; // restore texture matrix of other mirror
99278
100169
 
99279
- const {
99280
- texture,
99281
- textureNormalName,
99282
- width = DEFAULT_WATER_WIDTH,
99283
- height = DEFAULT_WATER_HEIGHT,
99284
- textureWidth = DEFAULT_WATER_WIDTH,
99285
- textureHeight = DEFAULT_WATER_HEIGHT,
99286
- alpha = DEFAULT_WATER_ALPHA,
99287
- distortionScale = DEFAULT_WATER_DISTORTION_SCALE
99288
- } = options;
99289
- const waterNormals = texture || Images$1.get(textureNormalName || 'waterNormal');
99290
- waterNormals.wrapS = waterNormals.wrapT = RepeatWrapping$1;
99291
- const body = new WaterMesh(new PlaneGeometry(width * 500, height * 500), {
99292
- textureWidth,
99293
- textureHeight,
99294
- waterNormals,
99295
- alpha,
99296
- sunDirection: new Vector3$1(-0.5773502691896258, 0.5773502691896258, -0.5773502691896258),
99297
- sunColor: 0xffffff,
99298
- waterColor: 0x001e0f,
99299
- distortionScale,
99300
- fog: Scene$1.getScene().fog !== undefined
99301
- });
100170
+ otherMirror.updateTextureMatrix();
100171
+ }
100172
+ }, {
100173
+ key: "renderWithMirror",
100174
+ value: function renderWithMirror(otherMirror) {
100175
+ // update the mirror matrix to mirror the current view
100176
+ this.updateTextureMatrix();
100177
+ this.matrixNeedsUpdate = false; // set the camera of the other mirror so the mirrored view is the reference view
99302
100178
 
99303
- _this.setBody({
99304
- body
99305
- });
100179
+ const tempCamera = otherMirror.camera;
100180
+ otherMirror.camera = this.mirrorCamera; // render the other mirror in temp texture
99306
100181
 
99307
- _this.setEntityType(ENTITY_TYPES.MESH);
100182
+ otherMirror.renderTemp();
100183
+ otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture; // render the current mirror
99308
100184
 
99309
- _this.setRotation({
99310
- x: -Math.PI / 2
99311
- });
100185
+ this.render();
100186
+ this.matrixNeedsUpdate = true; // restore material and camera of other mirror
99312
100187
 
99313
- return _this;
99314
- }
100188
+ otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture;
100189
+ otherMirror.camera = tempCamera; // restore texture matrix of other mirror
99315
100190
 
99316
- _createClass(Water, [{
99317
- key: "setSize",
99318
- value: function setSize(size) {
99319
- this.getBody().material.uniforms.size.value = clamp(size, 0.1, 100);
100191
+ otherMirror.updateTextureMatrix();
99320
100192
  }
99321
- }]);
99322
-
99323
- return Water;
99324
- }(Element$1);let Skybox = /*#__PURE__*/function (_Element) {
99325
- _inherits(Skybox, _Element);
99326
-
99327
- var _super = _createSuper(Skybox);
100193
+ }, {
100194
+ key: "updateTextureMatrix",
100195
+ value: function updateTextureMatrix() {
100196
+ this.updateMatrixWorld();
100197
+ this.camera.updateMatrixWorld();
100198
+ this.mirrorWorldPosition.setFromMatrixPosition(this.matrixWorld);
100199
+ this.cameraWorldPosition.setFromMatrixPosition(this.camera.matrixWorld);
100200
+ this.rotationMatrix.extractRotation(this.matrixWorld);
100201
+ this.normal.set(0, 0, 1);
100202
+ this.normal.applyMatrix4(this.rotationMatrix);
100203
+ var view = this.mirrorWorldPosition.clone().sub(this.cameraWorldPosition);
100204
+ view.reflect(this.normal).negate();
100205
+ view.add(this.mirrorWorldPosition);
100206
+ this.rotationMatrix.extractRotation(this.camera.matrixWorld);
100207
+ this.lookAtPosition.set(0, 0, -1);
100208
+ this.lookAtPosition.applyMatrix4(this.rotationMatrix);
100209
+ this.lookAtPosition.add(this.cameraWorldPosition);
100210
+ var target = this.mirrorWorldPosition.clone().sub(this.lookAtPosition);
100211
+ target.reflect(this.normal).negate();
100212
+ target.add(this.mirrorWorldPosition);
100213
+ this.up.set(0, -1, 0);
100214
+ this.up.applyMatrix4(this.rotationMatrix);
100215
+ this.up.reflect(this.normal).negate();
100216
+ this.mirrorCamera.position.copy(view);
100217
+ this.mirrorCamera.up = this.up;
100218
+ this.mirrorCamera.lookAt(target);
100219
+ this.mirrorCamera.updateProjectionMatrix();
100220
+ this.mirrorCamera.updateMatrixWorld();
100221
+ this.mirrorCamera.matrixWorldInverse.getInverse(this.mirrorCamera.matrixWorld); // Update the texture matrix
99328
100222
 
99329
- function Skybox(options) {
99330
- var _this;
100223
+ this.textureMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
100224
+ this.textureMatrix.multiply(this.mirrorCamera.projectionMatrix);
100225
+ this.textureMatrix.multiply(this.mirrorCamera.matrixWorldInverse); // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
100226
+ // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
99331
100227
 
99332
- _classCallCheck(this, Skybox);
100228
+ this.mirrorPlane.setFromNormalAndCoplanarPoint(this.normal, this.mirrorWorldPosition);
100229
+ this.mirrorPlane.applyMatrix4(this.mirrorCamera.matrixWorldInverse);
100230
+ this.clipPlane.set(this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant);
100231
+ var q = new Vector4();
100232
+ var projectionMatrix = this.mirrorCamera.projectionMatrix;
100233
+ q.x = (window.Math.sign(this.clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
100234
+ q.y = (window.Math.sign(this.clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
100235
+ q.z = -1.0;
100236
+ q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]; // Calculate the scaled plane vector
99333
100237
 
99334
- const {
99335
- name = generateRandomName("Skybox"),
99336
- texture = "skybox",
99337
- ...rest
99338
- } = options;
99339
- _this = _super.call(this, {
99340
- name,
99341
- texture,
99342
- ...rest
99343
- });
99344
- _this.cubeMap = typeof texture === "string" ? Images$1.get(texture) : texture;
99345
- const material = new MeshBasicMaterial({
99346
- envMap: _this.cubeMap,
99347
- side: BackSide
99348
- });
99349
- const geometry = new BoxGeometry(1000000, 1000000, 1000000);
100238
+ var c = new Vector4();
100239
+ c = this.clipPlane.multiplyScalar(2.0 / this.clipPlane.dot(q)); // Replacing the third row of the projection matrix
99350
100240
 
99351
- _this.setBody({
99352
- material,
99353
- geometry
99354
- });
100241
+ projectionMatrix.elements[2] = c.x;
100242
+ projectionMatrix.elements[6] = c.y;
100243
+ projectionMatrix.elements[10] = c.z + 1.0 - this.clipBias;
100244
+ projectionMatrix.elements[14] = c.w;
100245
+ }
100246
+ }, {
100247
+ key: "render",
100248
+ value: function render() {
100249
+ if (this.matrixNeedsUpdate) this.updateTextureMatrix();
100250
+ this.matrixNeedsUpdate = true; // Render the mirrored view of the current scene into the target texture
99355
100251
 
99356
- _this.setEntityType(ENTITY_TYPES.SCENERY.TYPE);
100252
+ var scene = this;
99357
100253
 
99358
- _this.setEntitySubtype(ENTITY_TYPES.SCENERY.SUBTYPES.SKYBOX);
100254
+ while (scene.parent !== null) {
100255
+ scene = scene.parent;
100256
+ }
99359
100257
 
99360
- return _this;
99361
- }
100258
+ if (scene !== undefined && scene instanceof Scene$2) {
100259
+ // We can't render ourself to ourself
100260
+ var visible = this.material.visible;
100261
+ this.material.visible = false;
100262
+ this.renderer.render(scene, this.mirrorCamera, this.renderTarget, true);
100263
+ this.material.visible = visible;
100264
+ }
100265
+ }
100266
+ }]);
99362
100267
 
99363
- return Skybox;
99364
- }(Element$1);let Shaders = /*#__PURE__*/function () {
100268
+ return Mirror;
100269
+ }(Object3D);let Shaders = /*#__PURE__*/function () {
99365
100270
  function Shaders() {
99366
100271
  _classCallCheck(this, Shaders);
99367
100272
 
@@ -99439,4 +100344,4 @@ var Shaders$1 = new Shaders();let Shader = function Shader(name, attributes, uni
99439
100344
  ...light_contants,
99440
100345
  ...material_constants,
99441
100346
  ...controls_contants
99442
- };export{AUDIO_RAMPS,AmbientLight,AmbientSound,Atmosphere,Audio$1 as Audio,Axes,BUILTIN,BaseScript,Box,CONTROL_EVENTS,Camera,Color,Cone,Config$1 as Config,Controls$1 as Controls,Cube,CurveLine,Cylinder,DirectionalSound,ENTITY_EVENTS,ENTITY_TYPES,Element$1 as Element,Entity,EventDispatcher,Explosion,Exporter,FEATURES,Features$1 as Features,Fire,Fountain,GameRunner$1 as GameRunner,Grid,HelperSprite,HemisphereLight,INPUT_EVENTS,Images$1 as Images,Importer,Input$1 as Input,Label,LabelComponent,Level,Lights$1 as Lights,Line,Mirror,Models$1 as Models,Ocean,PALETTES,PARTICLES,PHYSICS_CONSTANTS,PHYSICS_EVENTS,ParticleEmitter,ParticleEmitterGroup,Particles$1 as Particles,Physics$1 as Physics,Plane,PointLight,PostProcessing$1 as PostProcessing,Proton,ProtonParticleEmitter,Provider,Rain,Router$1 as Router,Scene$1 as Scene,Scripts$1 as Scripts,Shader,Sky,Skybox,Snow,Sound,Sphere,SpotLight,Sprite,Stats$1 as Stats,SunLight,three_module as THREE,THREEJS_CONTROL_EVENTS,Trail,Universe$1 as Universe,Vector3$1 as Vector3,Water,author,connect,constants,createElement,easing,functions,hitbox as hitboxUtils,index_esm as inferno,map$1 as map,math,object,physicsUtils,index$1 as rxjs,index as store,strings,uuid$1 as uuid,workers,index$2 as xstate};
100347
+ };export{AUDIO_RAMPS,AmbientLight,AmbientSound,Atmosphere,Audio$1 as Audio,Axes,BUILTIN,BaseScript,Box,CONTROL_EVENTS,Camera,Color,Cone,Config$1 as Config,Controls$1 as Controls,Cube,CurveLine,Cylinder,DirectionalSound,ENTITY_EVENTS,ENTITY_TYPES,Element$1 as Element,Entity,EventDispatcher,Explosion,Exporter,FEATURES,Features$1 as Features,Fire,Fountain,GameRunner$1 as GameRunner,Grid,HelperSprite,HemisphereLight,INPUT_EVENTS,Images$1 as Images,Importer,Input$1 as Input,Label,LabelComponent,Level,Lights$1 as Lights,Line,MirrorElement as Mirror,Models$1 as Models,Ocean,PALETTES,PARTICLES,PHYSICS_CONSTANTS,PHYSICS_EVENTS,ParticleEmitter,ParticleEmitterGroup,Particles$1 as Particles,Physics$1 as Physics,Plane,PointLight,PostProcessing$1 as PostProcessing,Proton,ProtonParticleEmitter,Provider,Rain,Router$1 as Router,Scene$1 as Scene,Scripts$1 as Scripts,Shader,Sky,Skybox,Snow,Sound,Sphere,SpotLight,Sprite,Stats$1 as Stats,SunLight,three_module as THREE,THREEJS_CONTROL_EVENTS,Trail,Universe$1 as Universe,Vector3$1 as Vector3,Water,author,connect,constants,createElement,easing,functions,hitbox as hitboxUtils,index_esm as inferno,map$1 as map,math,object,physicsUtils,index$1 as rxjs,index as store,strings,uuid$1 as uuid,workers,index$2 as xstate};