Needle Engine

Changes between version 3.5.11-beta and 3.5.12-beta
Files changed (6) hide show
  1. src/engine-components/export/usdz/extensions/behavior/Behaviour.ts +1 -0
  2. src/engine/engine_license.ts +1 -1
  3. src/engine/engine_physics_rapier.ts +26 -11
  4. src/engine/engine_serialization_builtin_serializer.ts +9 -9
  5. src/engine/engine_types.ts +13 -5
  6. src/engine-components/OrbitControls.ts +3 -1
src/engine-components/export/usdz/extensions/behavior/Behaviour.ts CHANGED
@@ -11,6 +11,7 @@
11
11
  afterSerialize?(ext: BehaviorExtension, context: IContext): void;
12
12
  }
13
13
 
14
+ /** internal USDZ behaviours extension */
14
15
  export class BehaviorExtension implements IUSDExporterExtension {
15
16
 
16
17
  get extensionName(): string {
src/engine/engine_license.ts CHANGED
@@ -116,7 +116,7 @@
116
116
  margin-bottom: 5px;
117
117
  `;
118
118
  let licenseText = "Needle Engine — non commercial version";
119
- console.log("%c" + licenseText, style)
119
+ console.log("%c " + licenseText, style)
120
120
  }
121
121
 
122
122
  function createLicenseElement() {
src/engine/engine_physics_rapier.ts CHANGED
@@ -61,6 +61,8 @@
61
61
 
62
62
  export class RapierPhysics implements IPhysicsEngine {
63
63
 
64
+ debugRenderColliders: boolean = false;
65
+
64
66
  removeBody(obj: IComponent) {
65
67
  if (!obj) return;
66
68
  this.validate();
@@ -244,15 +246,12 @@
244
246
 
245
247
  private rapierRay = new Ray({ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 1 });
246
248
  private raycastVectorsBuffer = new CircularBuffer(() => new Vector3(), 10);
247
- /** Fast raycast against physics colliders
248
- * @param origin ray origin in screen or worldspace
249
- * @param direction ray direction in worldspace
250
- * @param maxDistance max distance to raycast
251
- * @param solid if true it will also hit the collider if origin is already inside it
252
- */
253
- public raycast(origin: Vec2 | Vec3, direction: Vec3 | undefined = undefined, maxDistance: number = Infinity, solid: boolean = true)
249
+ public raycast(origin?: Vec2 | Vec3, direction?: Vec3, maxDistance?: number, solid?: boolean)
254
250
  : null | { point: Vector3, collider: ICollider } {
255
251
 
252
+ if (maxDistance === undefined) maxDistance = Infinity;
253
+ if (solid === undefined) solid = true;
254
+
256
255
  const ray = this.getPhysicsRay(this.rapierRay, origin, direction);
257
256
  if (!ray) return null;
258
257
 
@@ -270,9 +269,12 @@
270
269
  return null;
271
270
  }
272
271
 
273
- public raycastAndGetNormal(origin: Vec2 | Vec3, direction: Vec3 | undefined = undefined, maxDistance: number = Infinity, solid: boolean = true)
272
+ public raycastAndGetNormal(origin?: Vec2 | Vec3, direction?: Vec3, maxDistance?: number, solid?: boolean)
274
273
  : null | { point: Vector3, normal: Vector3, collider: ICollider } {
275
274
 
275
+ if (maxDistance === undefined) maxDistance = Infinity;
276
+ if (solid === undefined) solid = true;
277
+
276
278
  const ray = this.getPhysicsRay(this.rapierRay, origin, direction);
277
279
  if (!ray) return null;
278
280
 
@@ -292,8 +294,13 @@
292
294
  return null;
293
295
  }
294
296
 
295
- private getPhysicsRay(ray: Ray, origin: Vec2 | Vec3, direction: Vec3 | undefined = undefined): Ray | null {
297
+ private getPhysicsRay(ray: Ray, origin?: Vec2 | Vec3, direction?: Vec3): Ray | null {
296
298
  const cam = this.context?.mainCamera;
299
+ if (origin === undefined) {
300
+ const pos = this.context?.input.getPointerPosition(0);
301
+ if (pos) origin = pos;
302
+ else return null;
303
+ }
297
304
  // if we get origin in 2d space we need to project it to 3d space
298
305
  if (origin["z"] === undefined) {
299
306
  if (!cam) {
@@ -306,6 +313,7 @@
306
313
  vec3.z = 0;
307
314
  // if the origin is in screen space we need to convert it to raycaster space
308
315
  if (vec3.x > 1 || vec3.y > 1 || vec3.y < -1 || vec3.x < -1) {
316
+ if (debugPhysics) console.warn("Converting screenspace to raycast space", vec3)
309
317
  this.context?.input.convertScreenspaceToRaycastSpace(vec3);
310
318
  }
311
319
  vec3.unproject(cam);
@@ -742,20 +750,27 @@
742
750
  }
743
751
 
744
752
  private updateDebugRendering(world: World) {
745
- if (debugPhysics || debugColliderPlacement || showColliders) {
753
+ if (debugPhysics || debugColliderPlacement || showColliders || this.debugRenderColliders === true) {
746
754
  if (!this.lines) {
747
755
  const material = new LineBasicMaterial({
748
756
  color: 0x227700,
757
+ fog: false,
749
758
  // vertexColors: THREE.VertexColors
750
759
  });
751
760
  const geometry = new BufferGeometry();
752
761
  this.lines = new LineSegments(geometry, material);
762
+ }
763
+ if (this.lines.parent !== this.context?.scene)
753
764
  this.context?.scene.add(this.lines);
754
- }
755
765
  const buffers = world.debugRender();
756
766
  this.lines.geometry.setAttribute('position', new BufferAttribute(buffers.vertices, 3));
757
767
  this.lines.geometry.setAttribute('color', new BufferAttribute(buffers.colors, 4));
758
768
  }
769
+ else {
770
+ if (this.lines) {
771
+ this.context?.scene.remove(this.lines);
772
+ }
773
+ }
759
774
  }
760
775
 
761
776
  public postStep() {
src/engine/engine_serialization_builtin_serializer.ts CHANGED
@@ -270,20 +270,20 @@
270
270
  let fn: CallInfo | undefined;
271
271
  let args = call.argument;
272
272
 
273
- // This is the final method we pass to the call info (or undefined if the method couldnt be resolved)
274
- const eventMethod = hasMethod ? this.createEventMethod(target, call.method, args) : undefined;
275
-
276
- if (call.argument !== undefined) {
273
+ if (args !== undefined) {
277
274
  if (typeof args === "object") {
278
- args = objectSerializer.onDeserialize(call.argument, context);
279
- if (!args) args = componentSerializer.onDeserialize(call.argument, context);
275
+ // Try to deserialize the call argument to either a object or a component reference
276
+ let argRes = objectSerializer.onDeserialize(call.argument, context);
277
+ if (!argRes) argRes = componentSerializer.onDeserialize(call.argument, context);
278
+ if (argRes) args = argRes;
280
279
  }
281
- fn = new CallInfo(eventMethod, call.enabled);
282
280
  }
283
- else
284
- fn = new CallInfo(eventMethod, call.enabled);
285
281
 
282
+ // This is the final method we pass to the call info (or undefined if the method couldnt be resolved)
283
+ const eventMethod = hasMethod ? this.createEventMethod(target, call.method, args) : undefined;
284
+ fn = new CallInfo(eventMethod, call.enabled);
286
285
 
286
+
287
287
  if (!fn.method)
288
288
  fn[$eventListDebugInfo] = context.object?.name;
289
289
  if (!target || !fn.method) {
src/engine/engine_types.ts CHANGED
@@ -32,6 +32,7 @@
32
32
 
33
33
  export interface IInput {
34
34
  convertScreenspaceToRaycastSpace(vec: Vec2): void;
35
+ getPointerPosition(i: number): Vec2 | null;
35
36
  }
36
37
 
37
38
  export interface IPhysics {
@@ -375,10 +376,15 @@
375
376
  clearCaches();
376
377
 
377
378
  // raycasting
378
- /** fast raycast without getting the normal vector */
379
- raycast(origin: Vec2 | Vec3, direction: Vec3 | undefined, maxDistance: number, solid: boolean): RaycastResult;
379
+ /** Fast raycast against physics colliders
380
+ * @param origin ray origin in screen or worldspace
381
+ * @param direction ray direction in worldspace
382
+ * @param maxDistance max distance to raycast
383
+ * @param solid if true it will also hit the collider if origin is already inside it
384
+ */
385
+ raycast(origin?: Vec2 | Vec3, direction?: Vec3, maxDistance?: number, solid?: boolean): RaycastResult;
380
386
  /** raycast that also gets the normal vector. If you don't need it use raycast() */
381
- raycastAndGetNormal(origin: Vec2 | Vec3, direction: Vec3 | undefined, maxDistance: number, solid: boolean) : RaycastResult;
387
+ raycastAndGetNormal(origin?: Vec2 | Vec3, direction?: Vec3, maxDistance?: number, solid?: boolean): RaycastResult;
382
388
  sphereOverlap(point: Vector3, radius: number): Array<SphereOverlapResult>;
383
389
 
384
390
  // Collider methods
@@ -403,6 +409,8 @@
403
409
  removeBody(body: IComponent);
404
410
 
405
411
  // Joints
406
- addFixedJoint(body1: IRigidbody, body2: IRigidbody)
407
- addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3)
412
+ addFixedJoint(body1: IRigidbody, body2: IRigidbody);
413
+ addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3);
414
+
415
+ debugRenderColliders : boolean;
408
416
  }
src/engine-components/OrbitControls.ts CHANGED
@@ -87,7 +87,9 @@
87
87
  if (camGo && !this.setFromTargetPosition()) {
88
88
  if (this.debugLog)
89
89
  console.log("NO TARGET");
90
- const forward = new Vector3(0, 0, -10).applyMatrix4(camGo.cam.matrixWorld);
90
+ const worldPosition = getWorldPosition(camGo.cam);
91
+ const distanceToCenter = worldPosition.length();
92
+ const forward = new Vector3(0, 0, -distanceToCenter).applyMatrix4(camGo.cam.matrixWorld);
91
93
  this.setTarget(forward, true);
92
94
  }
93
95
  }