diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88d3cb25..2a33dc52 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,26 +24,8 @@ jobs: - name: Install dependencies run: npm ci - - name: === Build testing === - run: npm run build - - - name: === Rebranding compatibility testing === - run: npm run test-rebranding - - - name: === Migration tooling testing === - run: npm run test-migrate - - - name: === Lint testing === - run: npm run lint - - - name: === Unit testing === - run: npm run test-unit - - - name: === Unit addons testing === - run: npm run test-unit-addons - - - name: === Examples ready for release === - run: npm run test-e2e-cov + - name: === Repository verification === + run: npm test node-26-parity: name: Node 26 build & entrypoint parity diff --git a/docs/pages/JoltPhysics.html b/docs/pages/JoltPhysics.html index 4f4b3d62..929678a3 100644 --- a/docs/pages/JoltPhysics.html +++ b/docs/pages/JoltPhysics.html @@ -123,6 +123,41 @@
Sets the linear velocity of the given mesh which is part of the physics simulation.
+| + mesh + | +
+ The mesh to update the velocity for. + |
+
| + velocity + | +
+ The new linear velocity. + |
+
| + index + | +
+ If the mesh is instanced, the index represents the instanced ID. +Default is |
+
examples/jsm/physics/JoltPhysics.js diff --git a/docs/pages/JoltPhysics.html.md b/docs/pages/JoltPhysics.html.md index 3ab16ef0..f4719ac7 100644 --- a/docs/pages/JoltPhysics.html.md +++ b/docs/pages/JoltPhysics.html.md @@ -70,6 +70,24 @@ If the mesh is instanced, the index represents the instanced ID. Default is `0`. +### .setMeshVelocity( mesh : Mesh, velocity : Vector3, index : number ) + +Sets the linear velocity of the given mesh which is part of the physics simulation. + +**mesh** + +The mesh to update the velocity for. + +**velocity** + +The new linear velocity. + +**index** + +If the mesh is instanced, the index represents the instanced ID. + +Default is `0`. + ## Source [examples/jsm/physics/JoltPhysics.js](../../examples/jsm/physics/JoltPhysics.js) \ No newline at end of file diff --git a/docs/search.json b/docs/search.json index 1f0a2084..16f053fb 100644 --- a/docs/search.json +++ b/docs/search.json @@ -19054,6 +19054,10 @@ "title": "JoltPhysics#setMeshPosition", "kind": "function" }, + { + "title": "JoltPhysics#setMeshVelocity", + "kind": "function" + }, { "title": "KMZLoader", "kind": "class" diff --git a/editor/js/Script.js b/editor/js/Script.js index f819dc7a..59c9e7fd 100644 --- a/editor/js/Script.js +++ b/editor/js/Script.js @@ -311,7 +311,7 @@ function Script( editor ) { const url = new URL( '../build/4.core.js', document.baseURI ).href; const source = await ( await fetch( url ) ).text(); - server.server.defs.push( buildFourDefs( source ) ); + server.server.defs.push( buildFourDefs( source ) ); server.server.reset(); } catch ( error ) { diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index 3714cdb4..fa8ca467 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -1,3 +1,5 @@ +/* global FOUR */ + const APP = { Player: function () { diff --git a/eslint.config.js b/eslint.config.js index d4168341..36dd8b99 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -28,6 +28,8 @@ export default [ '**/vendor/**', '**/fuse/**', '**/template/static/**', + 'manual/examples/resources/webgl-debug-helper.js', + 'test/treeshake/*.bundle*.js', ] }, diff --git a/examples/jsm/misc/RollerCoaster.js b/examples/jsm/misc/RollerCoaster.js index d59c342e..50d6fd66 100644 --- a/examples/jsm/misc/RollerCoaster.js +++ b/examples/jsm/misc/RollerCoaster.js @@ -223,7 +223,7 @@ class RollerCoasterGeometry extends BufferGeometry { let headingChange = Math.atan2( sample2.x, sample2.z ) - Math.atan2( sample1.x, sample1.z ); if ( headingChange > Math.PI ) headingChange -= Math.PI * 2; - if ( headingChange < -Math.PI ) headingChange += Math.PI * 2; + if ( headingChange < - Math.PI ) headingChange += Math.PI * 2; quaternion.premultiply( rollQuaternion.setFromAxisAngle( forward, - Math.atan( headingChange * 8 ) * 0.5 ) ); @@ -398,7 +398,7 @@ class RollerCoasterLiftersGeometry extends BufferGeometry { let headingChange = Math.atan2( sample2.x, sample2.z ) - Math.atan2( sample1.x, sample1.z ); if ( headingChange > Math.PI ) headingChange -= Math.PI * 2; - if ( headingChange < -Math.PI ) headingChange += Math.PI * 2; + if ( headingChange < - Math.PI ) headingChange += Math.PI * 2; bankedQuaternion.copy( quaternion ); rollQuaternion.setFromAxisAngle( tangent, - Math.atan( headingChange * 8 ) * 0.5 ); diff --git a/examples/jsm/objects/Sky.js b/examples/jsm/objects/Sky.js index e03435bd..d6d31008 100644 --- a/examples/jsm/objects/Sky.js +++ b/examples/jsm/objects/Sky.js @@ -25,9 +25,9 @@ import { * sky.scale.setScalar( 10000 ); * scene.add( sky ); * ``` - * + * * It can be useful to hide the sun disc when generating an environment map to avoid artifacts - * + * * ```js * // disable before rendering environment map * sky.material.uniforms.showSunDisc.value = false; diff --git a/examples/jsm/objects/SkyMesh.js b/examples/jsm/objects/SkyMesh.js index 8509cb28..18140c2e 100644 --- a/examples/jsm/objects/SkyMesh.js +++ b/examples/jsm/objects/SkyMesh.js @@ -27,7 +27,7 @@ import { Fn, float, vec2, vec3, acos, add, mul, clamp, cos, dot, exp, max, mix, * ``` * * It can be useful to hide the sun disc when generating an environment map to avoid artifacts - * + * * ```js * // disable before rendering environment map * sky.showSunDisc.value = false; diff --git a/examples/jsm/physics/JoltPhysics.js b/examples/jsm/physics/JoltPhysics.js index d233a5cd..1d8b483d 100644 --- a/examples/jsm/physics/JoltPhysics.js +++ b/examples/jsm/physics/JoltPhysics.js @@ -130,10 +130,11 @@ async function JoltPhysics() { ? createInstancedBody( mesh, mass, restitution, shape ) : createBody( mesh.position, mesh.quaternion, mass, restitution, shape ); + meshMap.set( mesh, body ); + if ( mass > 0 ) { meshes.push( mesh ); - meshMap.set( mesh, body ); } @@ -178,45 +179,58 @@ async function JoltPhysics() { } - function setMeshPosition( mesh, position, index = 0 ) { + function getBody( mesh, index ) { - if ( mesh.isInstancedMesh ) { + let body = meshMap.get( mesh ); - const bodies = meshMap.get( mesh ); + if ( body === undefined ) { - const body = bodies[ index ]; + throw new Error( 'JoltPhysics: Mesh has not been added to the physics simulation.' ); - bodyInterface.RemoveBody( body.GetID() ); - bodyInterface.DestroyBody( body.GetID() ); + } - const physics = mesh.userData.physics; + if ( mesh.isInstancedMesh ) { - const shape = body.GetShape(); - const body2 = createBody( position, { x: 0, y: 0, z: 0, w: 1 }, physics.mass, physics.restitution, shape ); + body = body[ index ]; - bodies[ index ] = body2; + if ( body === undefined ) { - } else { + throw new RangeError( `JoltPhysics: Instanced mesh index ${index} is out of range.` ); - // TODO: Implement this + } } + return body; + } - function setMeshVelocity( mesh, velocity, index = 0 ) { + function setMeshPosition( mesh, position, index = 0 ) { - /* - let body = meshMap.get( mesh ); + const body = getBody( mesh, index ); + const bodyID = body.GetID(); + const nextPosition = new Jolt.RVec3( position.x, position.y, position.z ); + const zeroVelocity = new Jolt.Vec3( 0, 0, 0 ); - if ( mesh.isInstancedMesh ) { + bodyInterface.SetLinearVelocity( bodyID, zeroVelocity ); + bodyInterface.SetAngularVelocity( bodyID, zeroVelocity ); + bodyInterface.SetPosition( bodyID, nextPosition, Jolt.EActivation_Activate ); - body = body[ index ]; + Jolt.destroy( nextPosition ); + Jolt.destroy( zeroVelocity ); - } + } + + function setMeshVelocity( mesh, velocity, index = 0 ) { + + const body = getBody( mesh, index ); + const bodyID = body.GetID(); + const nextVelocity = new Jolt.Vec3( velocity.x, velocity.y, velocity.z ); - body.setLinvel( velocity ); - */ + bodyInterface.SetLinearVelocity( bodyID, nextVelocity ); + bodyInterface.ActivateBody( bodyID ); + + Jolt.destroy( nextVelocity ); } @@ -325,7 +339,15 @@ async function JoltPhysics() { */ setMeshPosition: setMeshPosition, - // NOOP + /** + * Sets the linear velocity of the given mesh which is part of the physics simulation. + * + * @method + * @name JoltPhysics#setMeshVelocity + * @param {Mesh} mesh The mesh to update the velocity for. + * @param {Vector3} velocity - The new linear velocity. + * @param {number} [index=0] - If the mesh is instanced, the index represents the instanced ID. + */ setMeshVelocity: setMeshVelocity }; diff --git a/examples/jsm/tsl/display/RetroPassNode.js b/examples/jsm/tsl/display/RetroPassNode.js index b91d041e..90124269 100644 --- a/examples/jsm/tsl/display/RetroPassNode.js +++ b/examples/jsm/tsl/display/RetroPassNode.js @@ -158,7 +158,7 @@ class RetroPassNode extends PassNode { let finalUV; - if ( texture.isCubeTextureNode ) { + if ( texture.isCubeTextureNode ) { finalUV = reflectVector; diff --git a/examples/physics_ammo_break.html b/examples/physics_ammo_break.html index 30d4c397..9766b1c6 100644 --- a/examples/physics_ammo_break.html +++ b/examples/physics_ammo_break.html @@ -86,7 +86,7 @@ Ammo().then( function ( AmmoLib ) { - Ammo = AmmoLib; + globalThis.Ammo = AmmoLib; init(); diff --git a/examples/physics_ammo_cloth.html b/examples/physics_ammo_cloth.html index 8c221992..b3167332 100644 --- a/examples/physics_ammo_cloth.html +++ b/examples/physics_ammo_cloth.html @@ -55,7 +55,7 @@ Ammo().then( function ( AmmoLib ) { - Ammo = AmmoLib; + globalThis.Ammo = AmmoLib; init(); diff --git a/examples/physics_ammo_rope.html b/examples/physics_ammo_rope.html index fffa006e..6d992337 100644 --- a/examples/physics_ammo_rope.html +++ b/examples/physics_ammo_rope.html @@ -59,7 +59,7 @@ Ammo().then( function ( AmmoLib ) { - Ammo = AmmoLib; + globalThis.Ammo = AmmoLib; init(); diff --git a/examples/physics_ammo_terrain.html b/examples/physics_ammo_terrain.html index fad6cf81..46641eba 100644 --- a/examples/physics_ammo_terrain.html +++ b/examples/physics_ammo_terrain.html @@ -72,7 +72,7 @@ Ammo().then( function ( AmmoLib ) { - Ammo = AmmoLib; + globalThis.Ammo = AmmoLib; init(); diff --git a/examples/physics_ammo_volume.html b/examples/physics_ammo_volume.html index 69ea60ea..cea827f5 100644 --- a/examples/physics_ammo_volume.html +++ b/examples/physics_ammo_volume.html @@ -63,7 +63,7 @@ Ammo().then( function ( AmmoLib ) { - Ammo = AmmoLib; + globalThis.Ammo = AmmoLib; init(); diff --git a/examples/webgl_lines_fat.html b/examples/webgl_lines_fat.html index ed202ad5..136349d9 100644 --- a/examples/webgl_lines_fat.html +++ b/examples/webgl_lines_fat.html @@ -239,6 +239,7 @@ } else { widthController.name( 'width (pixels)' ).min( 1 ).max( 10 ).setValue( 10 ); + } } ); diff --git a/examples/webgl_materials_texture_html.html b/examples/webgl_materials_texture_html.html index 12a854bf..5091e434 100644 --- a/examples/webgl_materials_texture_html.html +++ b/examples/webgl_materials_texture_html.html @@ -76,6 +76,8 @@ import { RoomEnvironment } from '@tnb1j/4js/addons/environments/RoomEnvironment.js'; import { InteractionManager } from '@tnb1j/4js/addons/interaction/InteractionManager.js'; + const info = document.getElementById( 'info' ); + if ( ! ( 'requestPaint' in HTMLCanvasElement.prototype ) ) { installHtmlInCanvasPolyfill(); diff --git a/examples/webgl_multiple_elements_text.html b/examples/webgl_multiple_elements_text.html index 4cbebda7..2a835eab 100644 --- a/examples/webgl_multiple_elements_text.html +++ b/examples/webgl_multiple_elements_text.html @@ -338,16 +338,19 @@ @@ -359,15 +362,19 @@ @@ -480,26 +487,30 @@ @@ -511,26 +522,30 @@ @@ -641,27 +656,31 @@ @@ -673,27 +692,31 @@ diff --git a/examples/webgpu_custom_fog_scattering.html b/examples/webgpu_custom_fog_scattering.html index b2066518..a5500486 100644 --- a/examples/webgpu_custom_fog_scattering.html +++ b/examples/webgpu_custom_fog_scattering.html @@ -144,7 +144,7 @@ // a couple of dominant trunks close to the camera to anchor the depth - [ [ - 1.1, 4.9, 1.5, 1.1 ], [ 1.5, 4, 1.2, 0.3 ] ].forEach( ( [ x, z, s, ry ] ) => { + [[ - 1.1, 4.9, 1.5, 1.1 ], [ 1.5, 4, 1.2, 0.3 ]].forEach( ( [ x, z, s, ry ] ) => { const hero = new FOUR.Mesh( variants[ variants.length - 1 ], material ); hero.position.set( x, 0, z ); diff --git a/examples/webgpu_lines_fat.html b/examples/webgpu_lines_fat.html index e6aa2ddd..dcb2e163 100644 --- a/examples/webgpu_lines_fat.html +++ b/examples/webgpu_lines_fat.html @@ -255,6 +255,7 @@ } else { widthController.name( 'width (pixels)' ).min( 1 ).max( 10 ).setValue( 10 ); + } } ); diff --git a/examples/webgpu_materials_texture_html.html b/examples/webgpu_materials_texture_html.html index 5d92bed8..a68465f1 100644 --- a/examples/webgpu_materials_texture_html.html +++ b/examples/webgpu_materials_texture_html.html @@ -77,6 +77,8 @@ import { RoomEnvironment } from '@tnb1j/4js/addons/environments/RoomEnvironment.js'; import { InteractionManager } from '@tnb1j/4js/addons/interaction/InteractionManager.js'; + const info = document.getElementById( 'info' ); + if ( ! ( 'requestPaint' in HTMLCanvasElement.prototype ) ) { installHtmlInCanvasPolyfill(); diff --git a/examples/webgpu_shadertoy.html b/examples/webgpu_shadertoy.html index b1b14c81..185df0d4 100644 --- a/examples/webgpu_shadertoy.html +++ b/examples/webgpu_shadertoy.html @@ -228,7 +228,7 @@ } - setup( builder ) { + setup() { if ( this.mainImage === null ) { diff --git a/examples/webxr_vr_rollercoaster.html b/examples/webxr_vr_rollercoaster.html index 8031e5b7..f79ac933 100644 --- a/examples/webxr_vr_rollercoaster.html +++ b/examples/webxr_vr_rollercoaster.html @@ -251,7 +251,7 @@ let headingChange = Math.atan2( tangent2.x, tangent2.z ) - Math.atan2( tangent1.x, tangent1.z ); if ( headingChange > Math.PI ) headingChange -= Math.PI * 2; - if ( headingChange < -Math.PI ) headingChange += Math.PI * 2; + if ( headingChange < - Math.PI ) headingChange += Math.PI * 2; train.up.set( 0, 1, 0 ); bankQuaternion.setFromAxisAngle( tangent, - Math.atan( headingChange * 8 ) * 0.5 ); diff --git a/manual/examples/cameras-logarithmic-depth-buffer.html b/manual/examples/cameras-logarithmic-depth-buffer.html index eadc9fb2..e7790a72 100644 --- a/manual/examples/cameras-logarithmic-depth-buffer.html +++ b/manual/examples/cameras-logarithmic-depth-buffer.html @@ -78,7 +78,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/cameras-orthographic-2-scenes.html b/manual/examples/cameras-orthographic-2-scenes.html index 32a198a9..2185f363 100644 --- a/manual/examples/cameras-orthographic-2-scenes.html +++ b/manual/examples/cameras-orthographic-2-scenes.html @@ -95,7 +95,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/cameras-perspective-2-scenes.html b/manual/examples/cameras-perspective-2-scenes.html index 4bed76d9..8deb43f9 100644 --- a/manual/examples/cameras-perspective-2-scenes.html +++ b/manual/examples/cameras-perspective-2-scenes.html @@ -95,7 +95,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/cameras-perspective.html b/manual/examples/cameras-perspective.html index 7a6021c2..d3d94e85 100644 --- a/manual/examples/cameras-perspective.html +++ b/manual/examples/cameras-perspective.html @@ -75,7 +75,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/cameras-z-fighting.html b/manual/examples/cameras-z-fighting.html index 13164b6c..004d50f7 100644 --- a/manual/examples/cameras-z-fighting.html +++ b/manual/examples/cameras-z-fighting.html @@ -74,7 +74,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/load-gltf-shadows.html b/manual/examples/load-gltf-shadows.html index 59c525aa..13b7e8f8 100644 --- a/manual/examples/load-gltf-shadows.html +++ b/manual/examples/load-gltf-shadows.html @@ -196,7 +196,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/shadows-directional-light-shadow-acne.html b/manual/examples/shadows-directional-light-shadow-acne.html index c10348a5..8b954431 100644 --- a/manual/examples/shadows-directional-light-shadow-acne.html +++ b/manual/examples/shadows-directional-light-shadow-acne.html @@ -256,7 +256,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/shadows-directional-light-with-camera-gui.html b/manual/examples/shadows-directional-light-with-camera-gui.html index 56f57c34..0ebc6932 100644 --- a/manual/examples/shadows-directional-light-with-camera-gui.html +++ b/manual/examples/shadows-directional-light-with-camera-gui.html @@ -221,7 +221,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/shadows-point-light.html b/manual/examples/shadows-point-light.html index bbdff33d..4185ea8c 100644 --- a/manual/examples/shadows-point-light.html +++ b/manual/examples/shadows-point-light.html @@ -197,7 +197,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/shadows-spot-light-with-camera-gui.html b/manual/examples/shadows-spot-light-with-camera-gui.html index b569f71a..150a2a21 100644 --- a/manual/examples/shadows-spot-light-with-camera-gui.html +++ b/manual/examples/shadows-spot-light-with-camera-gui.html @@ -195,7 +195,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/examples/shadows-spot-light-with-shadow-radius.html b/manual/examples/shadows-spot-light-with-shadow-radius.html index 2d1a32dd..5b6573f9 100644 --- a/manual/examples/shadows-spot-light-with-shadow-radius.html +++ b/manual/examples/shadows-spot-light-with-shadow-radius.html @@ -196,7 +196,7 @@ set max( v ) { this.obj[ this.maxProp ] = v; - this.min = this.min; // this will call the min setter + this.min = this.obj[ this.minProp ]; // this will call the min setter } diff --git a/manual/index.html b/manual/index.html index 34c3ffba..46f38a67 100644 --- a/manual/index.html +++ b/manual/index.html @@ -481,6 +481,9 @@