Needle Engine

Changes between version 3.36.3-beta and 3.36.3-beta.1
Files changed (5) hide show
  1. src/engine-components/Component.ts +1 -1
  2. src/engine-components/ContactShadows.ts +9 -1
  3. src/engine/engine_license.ts +29 -12
  4. src/engine/engine_texture.ts +2 -1
  5. src/engine/webcomponents/needle menu/needle-menu.ts +15 -3
src/engine-components/Component.ts CHANGED
@@ -447,7 +447,7 @@
447
447
  this.__destroyed = true;
448
448
  }
449
449
  /** called when you decorate fields with the @validate() decorator
450
- * @param field the name of the field that was changed
450
+ * @param prop the name of the field that was changed
451
451
  */
452
452
  onValidate?(prop?: string): void;
453
453
 
src/engine-components/ContactShadows.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CustomBlending, DoubleSide, Group, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MinEquation, OrthographicCamera, PlaneGeometry, ShaderMaterial, WebGLRenderTarget } from "three";
1
+ import { CustomBlending, DoubleSide, FrontSide, Group, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MinEquation, Object3D, OrthographicCamera, PlaneGeometry, RenderItem, ShaderMaterial, WebGLRenderTarget } from "three";
2
2
  import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
3
3
  import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader.js';
4
4
 
@@ -214,11 +214,19 @@
214
214
 
215
215
  const prevXRState = renderer.xr.enabled;
216
216
  renderer.xr.enabled = false;
217
+
218
+ const list = renderer.renderLists.get(scene, 0);
219
+ const prev = list.transparent;
220
+ list.transparent = [];
217
221
 
218
222
  // render to the render target to get the depths
219
223
  renderer.setRenderTarget(this.renderTarget);
224
+ renderer.clear();
225
+
220
226
  renderer.render(scene, this.shadowCamera);
221
227
 
228
+ list.transparent = prev;
229
+
222
230
  // for the shearing idea
223
231
  // this.shadowCamera.projectionMatrix.copy(mat);
224
232
 
src/engine/engine_license.ts CHANGED
@@ -103,27 +103,40 @@
103
103
  height: 100%;
104
104
  pointer-events: all;
105
105
  zIndex: 2147483647;
106
- background-color: rgba(0,0,0,0.3);
107
- backdrop-filter: blur(10px);
108
- webkitBackdropFilter: blur(10px);
109
106
  line-height: 1.5;
107
+ backdrop-filter: blur(15px);
110
108
  `;
109
+ const expectedStyle = div.style.cssText;
111
110
 
112
111
  const text = document.createElement("div");
113
112
  div.appendChild(text);
114
113
  text.style.cssText = `
115
114
  position: absolute;
116
- top: 50%;
117
- left: 50%;
118
- transform: translate(-50%, -50%);
115
+ left: 0;
116
+ right: 0;
117
+ top:0;
118
+ bottom: 0;
119
+ padding: 10%;
119
120
  color: white;
120
- font-size: 24px;
121
+ font-size: 20px;
121
122
  font-family: sans-serif;
122
123
  text-align: center;
123
- user-select: none;
124
+ pointer-events: all;
125
+ display: flex;
126
+ justify-content: center;
127
+ align-items: center;
128
+ background-color: rgba(0,0,0,.3);
129
+ text-shadow: 0 0 2px black;
124
130
  `;
125
- const forbiddenText = applicationForbiddenText?.length > 1 ? applicationForbiddenText : "Needle Engine<br/>This application is not allowed to run on this domain!";
131
+ const expectedTextStyle = text.style.cssText;
132
+ const forbiddenText = applicationForbiddenText?.length > 1 ? applicationForbiddenText : "This web application has been blacklisted. You might be in violation of the Needle Engine terms of use.<br/>Please contact the Needle support if you think this is a mistake.";
126
133
  text.innerHTML = forbiddenText;
134
+ setInterval(() => {
135
+ if (text.innerHTML !== forbiddenText) text.innerHTML = forbiddenText;
136
+ if (text.parentNode !== div) div.appendChild(text);
137
+ if (div.style.cssText !== expectedStyle) div.style.cssText = expectedStyle;
138
+ if (text.style.cssText !== expectedTextStyle) text.style.cssText = expectedTextStyle;
139
+ }, 500)
127
140
  return div;
128
141
  }
129
142
  let forbiddenElement = createForbiddenElement();
@@ -131,9 +144,13 @@
131
144
  setInterval(() => {
132
145
  if (applicationIsForbidden === true) {
133
146
  if (forbiddenElement.style.cssText !== expectedCSS) forbiddenElement = createForbiddenElement();
134
- if ("isPaused" in ctx) ctx.isPaused = true;
135
- if (forbiddenElement.parentNode !== ctx.domElement.shadowRoot)
136
- ctx.domElement.shadowRoot?.appendChild(forbiddenElement);
147
+ if (ctx.domElement.shadowRoot) {
148
+ if (forbiddenElement.parentNode !== ctx.domElement.shadowRoot)
149
+ ctx.domElement.shadowRoot?.appendChild(forbiddenElement);
150
+ }
151
+ else if (forbiddenElement.parentNode != document.body) {
152
+ document.body.appendChild(forbiddenElement);
153
+ }
137
154
  }
138
155
  }, 500)
139
156
  }
src/engine/engine_texture.ts CHANGED
@@ -9,7 +9,8 @@
9
9
  /**
10
10
  * A RenderTexture can be used to render a scene to a texture automatically by assigning it to the `Camera` component's `targetTexture` property.
11
11
  * You can then assign the `RenderTexture.texture` to materials to be displayed
12
- * @example ```ts
12
+ * @example Create a new RenderTexture and assign it to a camera and material
13
+ * ```typescript
13
14
  * // create new RenderTexture with a resolution
14
15
  * const rt = new RenderTexture(256, 256);
15
16
  * // assign to a camera
src/engine/webcomponents/needle menu/needle-menu.ts CHANGED
@@ -34,7 +34,7 @@
34
34
  private readonly _spatialMenu: NeedleSpatialMenu;
35
35
 
36
36
  constructor(context: Context) {
37
- this._menu = NeedleMenuElement.getOrCreate(context.domElement);
37
+ this._menu = NeedleMenuElement.getOrCreate(context.domElement, context);
38
38
  this._context = context;
39
39
  this._spatialMenu = new NeedleSpatialMenu(context, this._menu);
40
40
  window.addEventListener("message", this.onPostMessage);
@@ -160,7 +160,7 @@
160
160
  return document.createElement(elementName, { is: elementName });
161
161
  }
162
162
 
163
- static getOrCreate(domElement: HTMLElement) {
163
+ static getOrCreate(domElement: HTMLElement, context: Context) {
164
164
  let element = domElement.querySelector(elementName) as NeedleMenuElement | null;
165
165
  if (!element && domElement.shadowRoot) {
166
166
  element = domElement.shadowRoot.querySelector(elementName);
@@ -168,6 +168,7 @@
168
168
  if (!element) {
169
169
  element = NeedleMenuElement.create() as NeedleMenuElement;
170
170
  element._domElement = domElement;
171
+ element._context = context;
171
172
  if (domElement.shadowRoot)
172
173
  domElement.shadowRoot.appendChild(element);
173
174
  else
@@ -177,6 +178,7 @@
177
178
  }
178
179
 
179
180
  private _domElement: HTMLElement | null = null;
181
+ private _context: Context | null = null;
180
182
 
181
183
  constructor() {
182
184
  super();
@@ -414,6 +416,11 @@
414
416
  });
415
417
 
416
418
 
419
+
420
+ let context = this._context;
421
+ // we need to assign it in the timeout because the reference is set *after* the constructor did run
422
+ setTimeout(() => context = this._context);
423
+
417
424
  // watch changes
418
425
  let showInterval = -1;
419
426
  const rootObserver = new MutationObserver(mutations => {
@@ -425,7 +432,12 @@
425
432
  if (!hasProLicense()) {
426
433
  clearInterval(showInterval);
427
434
  showInterval = setInterval(() => {
428
- if (parent != this._domElement?.shadowRoot)
435
+ if (context?.isInAR && context.arOverlayElement) {
436
+ if (parent != context.arOverlayElement) {
437
+ context.arOverlayElement.appendChild(this);
438
+ }
439
+ }
440
+ else if (parent != this._domElement?.shadowRoot)
429
441
  this._domElement?.shadowRoot?.appendChild(this);
430
442
  this.style.display = "flex";
431
443
  this.style.visibility = "visible";