From 75ee05997618185db0f4a67ee062d0fcfbb07c60 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 3 Mar 2023 10:18:53 +0100 Subject: [PATCH 1/3] SkinnedMesh: Add bounding volumes. --- src/objects/SkinnedMesh.js | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/objects/SkinnedMesh.js b/src/objects/SkinnedMesh.js index c0d9fd9058da6..534ed781ae3f9 100644 --- a/src/objects/SkinnedMesh.js +++ b/src/objects/SkinnedMesh.js @@ -1,5 +1,7 @@ import { Mesh } from './Mesh.js'; +import { Box3 } from '../math/Box3.js'; import { Matrix4 } from '../math/Matrix4.js'; +import { Sphere } from '../math/Sphere.js'; import { Vector3 } from '../math/Vector3.js'; import { Vector4 } from '../math/Vector4.js'; @@ -10,6 +12,7 @@ const _skinWeight = /*@__PURE__*/ new Vector4(); const _vector3 = /*@__PURE__*/ new Vector3(); const _matrix4 = /*@__PURE__*/ new Matrix4(); +const _vertex = /*@__PURE__*/ new Vector3(); class SkinnedMesh extends Mesh { @@ -25,6 +28,57 @@ class SkinnedMesh extends Mesh { this.bindMatrix = new Matrix4(); this.bindMatrixInverse = new Matrix4(); + this.boundingBox = null; + this.boundingSphere = null; + + } + + computeBoundingBox() { + + const geometry = this.geometry; + + if ( this.boundingBox === null ) { + + this.boundingBox = new Box3(); + + } + + this.boundingBox.makeEmpty(); + + const positionAttribute = geometry.getAttribute( 'position' ); + + for ( let i = 0; i < positionAttribute.count; i ++ ) { + + _vertex.fromBufferAttribute( positionAttribute, i ); + this.applyBoneTransform( i, _vertex ); + this.boundingBox.expandByPoint( _vertex ); + + } + + } + + computeBoundingSphere() { + + const geometry = this.geometry; + + if ( this.boundingSphere === null ) { + + this.boundingSphere = new Sphere(); + + } + + this.boundingSphere.makeEmpty(); + + const positionAttribute = geometry.getAttribute( 'position' ); + + for ( let i = 0; i < positionAttribute.count; i ++ ) { + + _vertex.fromBufferAttribute( positionAttribute, i ); + this.applyBoneTransform( i, _vertex ); + this.boundingSphere.expandByPoint( _vertex ); + + } + } copy( source, recursive ) { From cf39e1133dffa17067dec09a293111567d1184c7 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Mon, 6 Mar 2023 09:57:22 +0100 Subject: [PATCH 2/3] Docs: Update SkinnedMesh pages. --- docs/api/en/objects/SkinnedMesh.html | 24 +++++++++++++++++++ docs/api/it/objects/SkinnedMesh.html | 24 +++++++++++++++++++ docs/api/zh/objects/SkinnedMesh.html | 35 +++++++++++++++++++++++----- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/docs/api/en/objects/SkinnedMesh.html b/docs/api/en/objects/SkinnedMesh.html index 94c763e2a0e1e..bb99d43c90c72 100644 --- a/docs/api/en/objects/SkinnedMesh.html +++ b/docs/api/en/objects/SkinnedMesh.html @@ -116,6 +116,16 @@

[property:Matrix4 bindMatrixInverse]

The base matrix that is used for resetting the bound bone transforms.

+

[property:Box3 boundingBox]

+

+ The bounding box of the [name]. Can be calculated with [page:.computeBoundingBox](). Default is `null`. +

+ +

[property:Sphere boundingSphere]

+

+ The bounding sphere of the [name]. Can be calculated with [page:.computeBoundingSphere](). Default is `null`. +

+

[property:Boolean isSkinnedMesh]

Read-only flag to check if a given object is of type [name]. @@ -145,6 +155,20 @@

[method:SkinnedMesh clone]()

This method does currently not clone an instance of [name] correctly. Please use [page:SkeletonUtils.clone]() in the meanwhile.

+

[method:undefined computeBoundingBox]()

+

+ Computes the bounding box, updating [page:.boundingBox] attribute.
+ Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + If an instance of [name] is animated, this method should be called per frame to compute a correct bounding box. +

+ +

[method:undefined computeBoundingSphere]()

+

+ Computes the bounding sphere, updating [page:.boundingSphere] attribute.
+ Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + If an instance of [name] is animated, this method should be called per frame to compute a correct bounding sphere. +

+

[method:undefined normalizeSkinWeights]()

Normalizes the skin weights. diff --git a/docs/api/it/objects/SkinnedMesh.html b/docs/api/it/objects/SkinnedMesh.html index 21206fe6826e8..564b6600e3a3e 100644 --- a/docs/api/it/objects/SkinnedMesh.html +++ b/docs/api/it/objects/SkinnedMesh.html @@ -117,6 +117,16 @@

[property:Matrix4 bindMatrixInverse]

La matrice di base che viene utilizzata per reimpostare le trasformazioni ossee vincolate.

+

[property:Box3 boundingBox]

+

+ Bounding box per la [name], che può essere calcolato con [page:.computeBoundingBox](). Il valore predefinito è `null`. +

+ +

[property:Sphere boundingSphere]

+

+ Bounding sphere per la [name], che può essere calcolato con [page:.computeBoundingSphere](). Il valore predefinito è `null`. +

+

[property:Boolean isSkinnedMesh]

Flag di sola lettura per verificare se l'oggetto dato è di tipo [name]. @@ -144,6 +154,20 @@

[method:SkinnedMesh clone]()

Questo metodo attualmente non clona correttamente un'istanza di [name]. Si prega di utilizzare [page:SkeletonUtils.clone]() nel frattempo.

+

[method:undefined computeBoundingBox]()

+

+ Computes the bounding box, updating [page:.boundingBox] attribute.
+ Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + If an instance of [name] is animated, this method should be called per frame to compute a correct bounding box. +

+ +

[method:undefined computeBoundingSphere]()

+

+ Computes the bounding sphere, updating [page:.boundingSphere] attribute.
+ Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + If an instance of [name] is animated, this method should be called per frame to compute a correct bounding sphere. +

+

[method:undefined normalizeSkinWeights]()

Normalizza i pesi della skin. diff --git a/docs/api/zh/objects/SkinnedMesh.html b/docs/api/zh/objects/SkinnedMesh.html index 23a1957f50b2e..f5e0f71937f4f 100644 --- a/docs/api/zh/objects/SkinnedMesh.html +++ b/docs/api/zh/objects/SkinnedMesh.html @@ -95,10 +95,6 @@

[name]( [param:BufferGeometry geometry], [param:Material material] )

[page:Material material] —— (可选)一个[page:Material]实例,默认值是一个新的[page:MeshBasicMaterial]。

- - - -

属性

共有属性请参见其基类[page:Mesh]。

@@ -119,6 +115,16 @@

[property:Matrix4 bindMatrixInverse]

该基础矩阵用于重置绑定骨骼的变换。

+

[property:Box3 boundingBox]

+

+ The bounding box of the [name]. Can be calculated with [page:.computeBoundingBox](). Default is `null`. +

+ +

[property:Sphere boundingSphere]

+

+ The bounding sphere of the [name]. Can be calculated with [page:.computeBoundingSphere](). Default is `null`. +

+

[property:Boolean isSkinnedMesh]

Read-only flag to check if a given object is of type [name]. @@ -129,11 +135,14 @@

[property:Skeleton skeleton]

用于表示蒙皮网格中骨骼的层次结构的[page:Skeleton](骨架)。

- -

方法

共有方法请参见其基类[page:Mesh]。

+

[method:Vector3 applyBoneTransform]( [param:Integer index], [param:Vector3 vector] )

+

+ Applies the bone transform associated with the given index to the given position vector. Returns the updated vector. +

+

[method:undefined bind]( [param:Skeleton skeleton], [param:Matrix4 bindMatrix] )

[page:Skeleton skeleton] —— 由一棵[page:Bone Bones]树创建的[page:Skeleton]。
@@ -146,6 +155,20 @@

[method:SkinnedMesh clone]()

This method does currently not clone an instance of [name] correctly. Please use [page:SkeletonUtils.clone]() in the meanwhile.

+

[method:undefined computeBoundingBox]()

+

+ Computes the bounding box, updating [page:.boundingBox] attribute.
+ Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + If an instance of [name] is animated, this method should be called per frame to compute a correct bounding box. +

+ +

[method:undefined computeBoundingSphere]()

+

+ Computes the bounding sphere, updating [page:.boundingSphere] attribute.
+ Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + If an instance of [name] is animated, this method should be called per frame to compute a correct bounding sphere. +

+

[method:undefined normalizeSkinWeights]()

标准化蒙皮的权重。 From c89891d24d4a6bdcc7cd6978317def482902ed9a Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Mon, 6 Mar 2023 16:13:55 +0100 Subject: [PATCH 3/3] Examples: Clean up. --- examples/webgl_loader_collada_skinning.html | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/examples/webgl_loader_collada_skinning.html b/examples/webgl_loader_collada_skinning.html index 3a0174393e519..98109b1a1e42e 100644 --- a/examples/webgl_loader_collada_skinning.html +++ b/examples/webgl_loader_collada_skinning.html @@ -61,16 +61,6 @@ const avatar = collada.scene; const animations = avatar.animations; - avatar.traverse( function ( node ) { - - if ( node.isSkinnedMesh ) { - - node.frustumCulled = false; - - } - - } ); - mixer = new THREE.AnimationMixer( avatar ); mixer.clipAction( animations[ 0 ] ).play();