@zephyr3d/scene 0.9.25 → 0.9.26
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.
- package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
- package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
- package/dist/animation/joint_dynamics/controller.js +7 -5
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -4
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/skeleton.js +58 -24
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/spring/multi_chain_spring_system.js +577 -179
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +4 -3
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
- package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +2 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_system.js +11 -3
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +10 -0
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/engine.js +53 -43
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptingsystem.js +119 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +3 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +284 -67
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/zhair/zhair_format.js +288 -0
- package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
- package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
- package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
- package/dist/asset/model.js +178 -67
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +193 -21
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +3 -1
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +4019 -1278
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/material/eye.js +932 -0
- package/dist/material/eye.js.map +1 -0
- package/dist/material/hair.js +917 -0
- package/dist/material/hair.js.map +1 -0
- package/dist/material/hairstrand.js +842 -0
- package/dist/material/hairstrand.js.map +1 -0
- package/dist/material/hairstrand_data.js +162 -0
- package/dist/material/hairstrand_data.js.map +1 -0
- package/dist/material/lambert.js +5 -2
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +338 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +120 -19
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +5 -4
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +73 -18
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +4 -4
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +48 -11
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mtoon.js +6 -5
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +146 -28
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrblueprint_instance.js +501 -0
- package/dist/material/pbrblueprint_instance.js.map +1 -0
- package/dist/material/pbrmr.js +15 -16
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/shader/helper.js +330 -20
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +55 -0
- package/dist/material/shader/terrain_blend.js.map +1 -0
- package/dist/material/skin.js +192 -32
- package/dist/material/skin.js.map +1 -1
- package/dist/material/spriteblueprint.js +16 -1
- package/dist/material/spriteblueprint.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +86 -23
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/water.js +3 -1
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +167 -7
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/coloradjust.js +2 -1
- package/dist/posteffect/coloradjust.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js +2 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js +3 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js +4 -1
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/skinsss.js +368 -69
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +16 -9
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +91 -34
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +44 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +45 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cull_visitor.js +19 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +36 -2
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +26 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +52 -51
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +3 -0
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +3 -0
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/oit.js +29 -0
- package/dist/render/oit.js.map +1 -0
- package/dist/render/render_queue.js +3 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +2 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +61 -1
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +73 -8
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +166 -126
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +36 -35
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +8 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +4 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/hair.js +963 -0
- package/dist/scene/hair.js.map +1 -0
- package/dist/scene/light.js +5 -1
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +481 -47
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +3 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +3 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +6 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +3 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +6 -1
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +3 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +6 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/texture_cache.js +309 -0
- package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
- package/dist/scene/water.js +6 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/diffusion.js +54 -0
- package/dist/shaders/diffusion.js.map +1 -0
- package/dist/shaders/shadow.js +33 -21
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/temporal.js +71 -33
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shadow/dom.js +546 -0
- package/dist/shadow/dom.js.map +1 -0
- package/dist/shadow/pcf_opt.js +3 -5
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/receiver_bias.js +41 -0
- package/dist/shadow/receiver_bias.js.map +1 -0
- package/dist/shadow/shader.js +20 -60
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +89 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +50 -50
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +150 -37
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/shape.js +11 -2
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +50 -9
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +112 -2
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +142 -49
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +490 -25
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +898 -4
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +431 -100
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +370 -3
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +133 -1
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +26 -5
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/hair.js +1141 -0
- package/dist/utility/serialization/scene/hair.js.map +1 -0
- package/dist/utility/serialization/scene/light.js +84 -4
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1867 -166
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +231 -14
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +141 -7
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +4 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +4 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +4 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +4 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +96 -95
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/values.js +49 -2
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
package/dist/asset/model.js
CHANGED
|
@@ -18,7 +18,7 @@ import '../animation/joint_dynamics/collision.js';
|
|
|
18
18
|
import '../animation/joint_dynamics/solver.js';
|
|
19
19
|
import { createTransformAccess, JointDynamicsSystem } from '../animation/joint_dynamics/joint_dynamics_system.js';
|
|
20
20
|
import { JointDynamicsModifier } from '../animation/joint_dynamics_modifier.js';
|
|
21
|
-
import { MAX_MORPH_TARGETS,
|
|
21
|
+
import { MAX_MORPH_ATTRIBUTES, MAX_MORPH_TARGETS, getMorphTargetLimit, MAX_SKIN_INFLUENCES } from '../values.js';
|
|
22
22
|
import { Primitive } from '../render/primitive.js';
|
|
23
23
|
import { UnlitMaterial } from '../material/unlit.js';
|
|
24
24
|
import { PBRSpecularGlossinessMaterial } from '../material/pbrsg.js';
|
|
@@ -37,6 +37,30 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
37
37
|
this.name = name;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
function normalizeAssetNodePath(path) {
|
|
41
|
+
return path.replace(/\\/g, '/').split('/').filter(Boolean).join('/');
|
|
42
|
+
}
|
|
43
|
+
function getSkinBindingKey(rig, joints, inverseBindMatrices) {
|
|
44
|
+
const matrixKey = inverseBindMatrices.map((matrix)=>{
|
|
45
|
+
const elements = [];
|
|
46
|
+
for(let i = 0; i < 16; i++){
|
|
47
|
+
elements.push(matrix[i]);
|
|
48
|
+
}
|
|
49
|
+
return elements.join(',');
|
|
50
|
+
}).join('|');
|
|
51
|
+
return `${rig.persistentId}|${joints.map((joint)=>joint.persistentId).join('|')}|${matrixKey}`;
|
|
52
|
+
}
|
|
53
|
+
function getAssetNodePath(node) {
|
|
54
|
+
const segments = [];
|
|
55
|
+
let current = node;
|
|
56
|
+
while(current){
|
|
57
|
+
if (current.name) {
|
|
58
|
+
segments.push(current.name);
|
|
59
|
+
}
|
|
60
|
+
current = current.parent;
|
|
61
|
+
}
|
|
62
|
+
return normalizeAssetNodePath(segments.reverse().join('/'));
|
|
63
|
+
}
|
|
40
64
|
/**
|
|
41
65
|
* Heirarchical node interface for model loading
|
|
42
66
|
* @public
|
|
@@ -665,18 +689,25 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
665
689
|
ASSERT(!!ext, `Unknown image mime type: ${mimeType}`);
|
|
666
690
|
const baseName = this.sanitizeResourceName(this.getImageBaseName(img, i, destName), `${destName}_texture_${i}`);
|
|
667
691
|
const path = await this.tryReuseExactResourcePath(dstVFS, destPath, baseName, ext, usedPaths, `${destName}_texture_${i}`) ?? this.consumeReusableResourcePath(reusableResourcePools, baseName, ext, usedPaths) ?? await this.createUniqueResourcePath(dstVFS, destPath, baseName, ext, usedPaths, `${destName}_texture_${i}`);
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
692
|
+
try {
|
|
693
|
+
if (img.uri) {
|
|
694
|
+
img.data = new Uint8Array(await srcVFS.readFile(img.uri, {
|
|
695
|
+
encoding: 'binary'
|
|
696
|
+
}));
|
|
697
|
+
}
|
|
698
|
+
await dstVFS.writeFile(path, img.data.buffer.slice(img.data.byteOffset, img.data.byteOffset + img.data.byteLength), {
|
|
699
|
+
encoding: 'binary',
|
|
700
|
+
create: true
|
|
701
|
+
});
|
|
702
|
+
img.uri = path;
|
|
703
|
+
img.data = undefined;
|
|
704
|
+
img.mimeType = '';
|
|
705
|
+
} catch (err) {
|
|
706
|
+
console.warn(`Skip missing or unreadable texture during import: ${img.uri || img.name || `${destName}_texture_${i}`}: ${String(err)}`);
|
|
707
|
+
img.uri = undefined;
|
|
708
|
+
img.data = undefined;
|
|
709
|
+
img.mimeType = '';
|
|
672
710
|
}
|
|
673
|
-
await dstVFS.writeFile(path, img.data.buffer.slice(img.data.byteOffset, img.data.byteOffset + img.data.byteLength), {
|
|
674
|
-
encoding: 'binary',
|
|
675
|
-
create: true
|
|
676
|
-
});
|
|
677
|
-
img.uri = path;
|
|
678
|
-
img.data = undefined;
|
|
679
|
-
img.mimeType = '';
|
|
680
711
|
}
|
|
681
712
|
}
|
|
682
713
|
const materialKeys = Object.keys(this._materialList);
|
|
@@ -900,6 +931,7 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
900
931
|
}
|
|
901
932
|
}
|
|
902
933
|
const rigMap = new Map();
|
|
934
|
+
const bindingMap = new Map();
|
|
903
935
|
for (const v of skeletonMeshMap){
|
|
904
936
|
const sk = v[0];
|
|
905
937
|
const joints = sk.joints.map((val)=>{
|
|
@@ -923,7 +955,13 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
923
955
|
rigMap.set(rigKey, rig);
|
|
924
956
|
group.animationSet.rigs.push(new DRef(rig));
|
|
925
957
|
}
|
|
926
|
-
const
|
|
958
|
+
const bindingKey = getSkinBindingKey(rig, joints, sk.inverseBindMatrices);
|
|
959
|
+
let binding = bindingMap.get(bindingKey);
|
|
960
|
+
if (!binding) {
|
|
961
|
+
binding = new SkinBinding(rig, sk.inverseBindMatrices, joints);
|
|
962
|
+
bindingMap.set(bindingKey, binding);
|
|
963
|
+
group.animationSet.skeletons.push(new DRef(binding));
|
|
964
|
+
}
|
|
927
965
|
const nodes = skeletonMeshMap.get(sk);
|
|
928
966
|
if (nodes) {
|
|
929
967
|
if (!nodes.binding) {
|
|
@@ -933,14 +971,14 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
933
971
|
const v = {
|
|
934
972
|
positions: nodes.bounding[i].rawPositions,
|
|
935
973
|
blendIndices: nodes.bounding[i].rawBlendIndices,
|
|
936
|
-
weights: nodes.bounding[i].rawJointWeights
|
|
974
|
+
weights: nodes.bounding[i].rawJointWeights,
|
|
975
|
+
influenceCount: nodes.bounding[i].rawSkinInfluenceCount ?? 4
|
|
937
976
|
};
|
|
938
977
|
mesh.setSkinnedBoundingInfo(nodes.binding.getBoundingInfo(v));
|
|
939
978
|
mesh.skeletonName = nodes.binding.persistentId;
|
|
940
979
|
}
|
|
941
980
|
}
|
|
942
981
|
}
|
|
943
|
-
group.animationSet.skeletons.push(new DRef(nodes.binding));
|
|
944
982
|
}
|
|
945
983
|
}
|
|
946
984
|
if (saveAnimations) {
|
|
@@ -979,8 +1017,9 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
979
1017
|
} else if (track.type === 'weights') {
|
|
980
1018
|
for (const m of track.node.mesh.subMeshes){
|
|
981
1019
|
const mesh = meshMap.get(m);
|
|
982
|
-
|
|
983
|
-
|
|
1020
|
+
const morphTargetLimit = getMorphTargetLimit();
|
|
1021
|
+
if (track.interpolator.stride > morphTargetLimit) {
|
|
1022
|
+
console.error(`Morph target too large: ${track.interpolator.stride}, the project limit is ${morphTargetLimit}`);
|
|
984
1023
|
} else {
|
|
985
1024
|
const morphTrack = new MorphTargetTrack(track.interpolator, track.defaultMorphWeights, m.targetBox, mesh.getBoundingVolume().toAABB(), true);
|
|
986
1025
|
animation.addTrack(mesh, morphTrack);
|
|
@@ -1214,6 +1253,7 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
1214
1253
|
node.rotation.set(assetNode.rotation);
|
|
1215
1254
|
node.scale.set(assetNode.scaling);
|
|
1216
1255
|
if (saveMeshes && assetNode.mesh) {
|
|
1256
|
+
const sourceMorphReferenceAssetPath = this._preprocessOptions?.sourceMorphReferenceAssetPath ?? null;
|
|
1217
1257
|
const meshData = assetNode.mesh;
|
|
1218
1258
|
const skeleton = saveSkeletons ? assetNode.skeleton : null;
|
|
1219
1259
|
for (const subMesh of meshData.subMeshes){
|
|
@@ -1229,7 +1269,7 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
1229
1269
|
meshNode.position = instance.t;
|
|
1230
1270
|
meshNode.scale = instance.s;
|
|
1231
1271
|
meshNode.rotation = instance.r;
|
|
1232
|
-
meshNode.name = subMesh.name;
|
|
1272
|
+
meshNode.name = subMesh.primitive?.name?.trim() || subMesh.name;
|
|
1233
1273
|
meshNode.clipTestEnabled = true;
|
|
1234
1274
|
meshNode.showState = 'inherit';
|
|
1235
1275
|
if (!this._primitiveMap.get(subMesh.primitive)) {
|
|
@@ -1250,7 +1290,20 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
1250
1290
|
mesh: meshData,
|
|
1251
1291
|
subMesh
|
|
1252
1292
|
});
|
|
1253
|
-
|
|
1293
|
+
const morphSource = sourceMorphReferenceAssetPath && subMesh.numTargets > 0 ? (()=>{
|
|
1294
|
+
const nodePath = getAssetNodePath(assetNode);
|
|
1295
|
+
const subMeshName = subMesh.name;
|
|
1296
|
+
if (!nodePath || !subMeshName) {
|
|
1297
|
+
return null;
|
|
1298
|
+
}
|
|
1299
|
+
return {
|
|
1300
|
+
sourcePath: sourceMorphReferenceAssetPath,
|
|
1301
|
+
nodePath,
|
|
1302
|
+
subMeshName
|
|
1303
|
+
};
|
|
1304
|
+
})() : null;
|
|
1305
|
+
processMorphData(subMesh, meshNode, assetNode.weights ?? meshData.morphWeights, meshData.morphNames, morphSource);
|
|
1306
|
+
applyMeshSkinInfluenceData(subMesh, meshNode);
|
|
1254
1307
|
if (skeleton) {
|
|
1255
1308
|
if (!skeletonMeshMap.has(skeleton)) {
|
|
1256
1309
|
skeletonMeshMap.set(skeleton, {
|
|
@@ -1762,30 +1815,28 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
1762
1815
|
return null;
|
|
1763
1816
|
}
|
|
1764
1817
|
}
|
|
1765
|
-
|
|
1766
|
-
const device = getDevice();
|
|
1818
|
+
function applyMeshMorphMetadata(subMesh, mesh, morphWeights, morphNames) {
|
|
1767
1819
|
const numTargets = subMesh.numTargets;
|
|
1768
|
-
if (numTargets === 0) {
|
|
1820
|
+
if (numTargets === 0 || !subMesh.targets || !subMesh.targetBox) {
|
|
1769
1821
|
return;
|
|
1770
1822
|
}
|
|
1823
|
+
const supportedNumTargets = Math.min(numTargets, getMorphTargetLimit());
|
|
1824
|
+
if (supportedNumTargets !== numTargets) {
|
|
1825
|
+
console.warn(`Morph target count truncated from ${numTargets} to ${supportedNumTargets} for mesh "${subMesh.name ?? mesh.name ?? ''}"`);
|
|
1826
|
+
}
|
|
1771
1827
|
const attributes = Object.getOwnPropertyNames(subMesh.targets);
|
|
1772
1828
|
const positionInfo = subMesh.primitive.vertices['position'];
|
|
1773
1829
|
const numVertices = positionInfo ? positionInfo.data.length / getVertexFormatComponentCount(positionInfo.format) >> 0 : 0;
|
|
1774
1830
|
const weightsAndOffsets = new Float32Array(4 + MAX_MORPH_TARGETS + MAX_MORPH_ATTRIBUTES);
|
|
1775
|
-
for(let i = 0; i <
|
|
1831
|
+
for(let i = 0; i < supportedNumTargets; i++){
|
|
1776
1832
|
weightsAndOffsets[4 + i] = morphWeights?.[i] ?? 0;
|
|
1777
1833
|
}
|
|
1778
1834
|
const textureSize = Math.ceil(Math.sqrt(numVertices * attributes.length * numTargets));
|
|
1779
|
-
if (textureSize > device.getDeviceCaps().textureCaps.maxTextureSize) {
|
|
1780
|
-
// TODO: reduce morph attributes
|
|
1781
|
-
throw new Error(`Morph target data too large`);
|
|
1782
|
-
}
|
|
1783
1835
|
weightsAndOffsets[0] = textureSize;
|
|
1784
1836
|
weightsAndOffsets[1] = textureSize;
|
|
1785
1837
|
weightsAndOffsets[2] = numVertices;
|
|
1786
|
-
weightsAndOffsets[3] =
|
|
1838
|
+
weightsAndOffsets[3] = supportedNumTargets;
|
|
1787
1839
|
let offset = 0;
|
|
1788
|
-
const textureData = new Float32Array(textureSize * textureSize * 4);
|
|
1789
1840
|
for(let attrib = 0; attrib < MAX_MORPH_ATTRIBUTES; attrib++){
|
|
1790
1841
|
const index = attributes.indexOf(String(attrib));
|
|
1791
1842
|
if (index < 0) {
|
|
@@ -1798,64 +1849,124 @@ import { MToonMaterial } from '../material/mtoon.js';
|
|
|
1798
1849
|
console.error(`Invalid morph target data`);
|
|
1799
1850
|
return;
|
|
1800
1851
|
}
|
|
1801
|
-
|
|
1802
|
-
const data = info.data[t];
|
|
1803
|
-
for(let i = 0; i < numVertices; i++){
|
|
1804
|
-
for(let j = 0; j < 4; j++){
|
|
1805
|
-
textureData[offset++] = j < info.numComponents ? data[i * info.numComponents + j] : 1;
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1852
|
+
offset += numVertices * 4 * numTargets;
|
|
1809
1853
|
}
|
|
1810
|
-
const morphBoundingBox = new BoundingBox();
|
|
1811
|
-
calculateMorphBoundingBox(morphBoundingBox, subMesh.targetBox, weightsAndOffsets.subarray(4, 4 + MAX_MORPH_TARGETS), numTargets);
|
|
1812
|
-
const meshAABB = mesh.getBoundingVolume().toAABB();
|
|
1813
|
-
morphBoundingBox.minPoint.addBy(meshAABB.minPoint);
|
|
1814
|
-
morphBoundingBox.maxPoint.addBy(meshAABB.maxPoint);
|
|
1815
1854
|
const names = {};
|
|
1816
|
-
for(let i = 0; i <
|
|
1855
|
+
for(let i = 0; i < supportedNumTargets; i++){
|
|
1817
1856
|
const name = morphNames?.[i] ?? `Target${i}`;
|
|
1818
1857
|
names[name] = i;
|
|
1819
1858
|
}
|
|
1820
|
-
mesh.setMorphData({
|
|
1821
|
-
width: textureSize,
|
|
1822
|
-
height: textureSize,
|
|
1823
|
-
data: textureData
|
|
1824
|
-
});
|
|
1825
1859
|
mesh.setMorphInfo({
|
|
1826
1860
|
data: weightsAndOffsets,
|
|
1827
1861
|
names
|
|
1828
1862
|
});
|
|
1829
1863
|
mesh.setMorphBoundingInfo({
|
|
1830
|
-
targetBoxes: subMesh.targetBox,
|
|
1831
|
-
originBox: new BoundingBox(
|
|
1864
|
+
targetBoxes: subMesh.targetBox.slice(0, supportedNumTargets),
|
|
1865
|
+
originBox: new BoundingBox(mesh.getBoundingVolume().toAABB())
|
|
1832
1866
|
});
|
|
1833
|
-
|
|
1867
|
+
}
|
|
1868
|
+
function createMorphSourceDataFromSubMesh(subMesh) {
|
|
1869
|
+
const numTargets = Math.min(subMesh.numTargets, getMorphTargetLimit());
|
|
1870
|
+
if (numTargets === 0 || !subMesh.targets) {
|
|
1871
|
+
return null;
|
|
1872
|
+
}
|
|
1873
|
+
const positionInfo = subMesh.primitive.vertices['position'];
|
|
1874
|
+
const numVertices = positionInfo ? positionInfo.data.length / getVertexFormatComponentCount(positionInfo.format) >> 0 : 0;
|
|
1875
|
+
const targets = {};
|
|
1876
|
+
for (const [attribKey, info] of Object.entries(subMesh.targets)){
|
|
1877
|
+
const attrib = Number(attribKey);
|
|
1878
|
+
if (!info || !Number.isInteger(attrib) || attrib < 0) {
|
|
1879
|
+
continue;
|
|
1880
|
+
}
|
|
1881
|
+
if (info.data.length < numTargets) {
|
|
1882
|
+
console.error(`Invalid morph target data`);
|
|
1883
|
+
return null;
|
|
1884
|
+
}
|
|
1885
|
+
targets[attrib] = {
|
|
1886
|
+
numComponents: info.numComponents,
|
|
1887
|
+
data: info.data.slice(0, numTargets),
|
|
1888
|
+
indices: info.indices?.slice(0, numTargets)
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
return {
|
|
1892
|
+
numTargets,
|
|
1893
|
+
numVertices,
|
|
1894
|
+
targets
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
function applyMeshMorphData(subMesh, mesh) {
|
|
1898
|
+
const sourceData = createMorphSourceDataFromSubMesh(subMesh);
|
|
1899
|
+
if (!sourceData) {
|
|
1900
|
+
mesh.setMorphData(null);
|
|
1901
|
+
mesh.setMorphSourceData(null);
|
|
1902
|
+
return;
|
|
1903
|
+
}
|
|
1904
|
+
mesh.setMorphSourceData(sourceData);
|
|
1905
|
+
}
|
|
1906
|
+
function createSkinInfluenceDataFromSubMesh(subMesh) {
|
|
1907
|
+
// Preserve the influence count captured at import time so runtime settings do not silently
|
|
1908
|
+
// degrade already-imported assets when a project lowers the import limit later on.
|
|
1909
|
+
const influenceCount = Math.max(0, Math.min(subMesh.rawSkinInfluenceCount ?? 4, MAX_SKIN_INFLUENCES, Math.floor((subMesh.rawJointWeights?.length ?? 0) / Math.max(1, (subMesh.rawPositions?.length ?? 0) / 3))));
|
|
1910
|
+
if (influenceCount <= 4 || !subMesh.rawPositions || !subMesh.rawBlendIndices || !subMesh.rawJointWeights || subMesh.rawPositions.length < 3) {
|
|
1911
|
+
return null;
|
|
1912
|
+
}
|
|
1913
|
+
const numVertices = Math.floor(subMesh.rawPositions.length / 3);
|
|
1914
|
+
if (numVertices <= 0) {
|
|
1915
|
+
return null;
|
|
1916
|
+
}
|
|
1917
|
+
const extraInfluenceCount = influenceCount - 4;
|
|
1918
|
+
const pairCount = Math.ceil(extraInfluenceCount / 2);
|
|
1919
|
+
const textureSize = Math.ceil(Math.sqrt(numVertices * pairCount));
|
|
1920
|
+
const textureData = new Float32Array(textureSize * textureSize * 4);
|
|
1921
|
+
for(let vertexIndex = 0; vertexIndex < numVertices; vertexIndex++){
|
|
1922
|
+
const baseOffset = vertexIndex * influenceCount + 4;
|
|
1923
|
+
for(let pairIndex = 0; pairIndex < pairCount; pairIndex++){
|
|
1924
|
+
const influenceIndex = 4 + pairIndex * 2;
|
|
1925
|
+
const sourceIndex = baseOffset + pairIndex * 2;
|
|
1926
|
+
const texelOffset = (vertexIndex * pairCount + pairIndex) * 4;
|
|
1927
|
+
textureData[texelOffset] = Number(subMesh.rawBlendIndices[sourceIndex] ?? 0);
|
|
1928
|
+
textureData[texelOffset + 1] = Number(subMesh.rawJointWeights[sourceIndex] ?? 0);
|
|
1929
|
+
// Odd influence counts leave the second half of the final texel empty.
|
|
1930
|
+
// Do not read it from the next vertex's first influence.
|
|
1931
|
+
if (influenceIndex + 1 < influenceCount) {
|
|
1932
|
+
textureData[texelOffset + 2] = Number(subMesh.rawBlendIndices[sourceIndex + 1] ?? 0);
|
|
1933
|
+
textureData[texelOffset + 3] = Number(subMesh.rawJointWeights[sourceIndex + 1] ?? 0);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
return {
|
|
1938
|
+
width: textureSize,
|
|
1939
|
+
height: textureSize,
|
|
1940
|
+
influenceCount,
|
|
1941
|
+
data: textureData
|
|
1942
|
+
};
|
|
1943
|
+
}
|
|
1944
|
+
function applyMeshSkinInfluenceData(subMesh, mesh) {
|
|
1945
|
+
mesh.setSkinInfluenceData(createSkinInfluenceDataFromSubMesh(subMesh));
|
|
1946
|
+
}
|
|
1947
|
+
/** @internal */ function processMorphData(subMesh, mesh, morphWeights, morphNames, morphSource) {
|
|
1948
|
+
if (subMesh.numTargets === 0) {
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
applyMeshMorphMetadata(subMesh, mesh, morphWeights, morphNames);
|
|
1952
|
+
mesh.setMorphSource(morphSource ?? null);
|
|
1953
|
+
if (morphSource) {
|
|
1954
|
+
mesh.setMorphSourceData(null);
|
|
1955
|
+
mesh.setMorphData(null);
|
|
1956
|
+
} else {
|
|
1957
|
+
applyMeshMorphData(subMesh, mesh);
|
|
1958
|
+
}
|
|
1834
1959
|
}
|
|
1835
1960
|
/** @internal */ function getAssetMeshMorphTargetCount(mesh) {
|
|
1836
1961
|
let count = 0;
|
|
1837
1962
|
for (const subMesh of mesh.subMeshes){
|
|
1838
1963
|
count = Math.max(count, subMesh.numTargets);
|
|
1839
1964
|
}
|
|
1840
|
-
return count;
|
|
1965
|
+
return Math.min(count, getMorphTargetLimit());
|
|
1841
1966
|
}
|
|
1842
1967
|
/** @internal */ function getAssetMeshMorphTargetName(mesh, index) {
|
|
1843
1968
|
return mesh.morphNames?.[index] ?? `Target${index}`;
|
|
1844
1969
|
}
|
|
1845
|
-
/** @internal */ function calculateMorphBoundingBox(morphBoundingBox, keyframeBoundingBox, weights, numTargets) {
|
|
1846
|
-
morphBoundingBox.minPoint.setXYZ(0, 0, 0);
|
|
1847
|
-
morphBoundingBox.maxPoint.setXYZ(0, 0, 0);
|
|
1848
|
-
for(let i = 0; i < numTargets; i++){
|
|
1849
|
-
const weight = weights[i];
|
|
1850
|
-
const keyframeBox = keyframeBoundingBox[i];
|
|
1851
|
-
morphBoundingBox.minPoint.x += keyframeBox.minPoint.x * weight;
|
|
1852
|
-
morphBoundingBox.minPoint.y += keyframeBox.minPoint.y * weight;
|
|
1853
|
-
morphBoundingBox.minPoint.z += keyframeBox.minPoint.z * weight;
|
|
1854
|
-
morphBoundingBox.maxPoint.x += keyframeBox.maxPoint.x * weight;
|
|
1855
|
-
morphBoundingBox.maxPoint.y += keyframeBox.maxPoint.y * weight;
|
|
1856
|
-
morphBoundingBox.maxPoint.z += keyframeBox.maxPoint.z * weight;
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
1970
|
|
|
1860
|
-
export { AssetHierarchyNode, AssetScene, AssetSkeleton, NamedObject, SharedModel };
|
|
1971
|
+
export { AssetHierarchyNode, AssetScene, AssetSkeleton, NamedObject, SharedModel, applyMeshMorphData, applyMeshMorphMetadata, applyMeshSkinInfluenceData, createMorphSourceDataFromSubMesh };
|
|
1861
1972
|
//# sourceMappingURL=model.js.map
|