fix(sdk): 确保所有Object3D对象原型链一致

This commit is contained in:
2026-03-05 11:11:02 +08:00
parent b70084acdb
commit 218f4f31f0
4 changed files with 393 additions and 282 deletions
+27 -13
View File
@@ -5,15 +5,29 @@ import * as THREE from "three";
* @param callback - 以一个object3D对象作为第一个参数的函数。
* @param condition - 需要满足该条件才继续后续回调的条件函数
*/
THREE.Object3D.prototype.traverseByCondition = function(callback, condition){
THREE.Object3D.prototype.traverseByCondition = function (callback, condition) {
if (!condition(this)) return;
callback(this);
const children = this.children;
// 优先使用子对象的traverseByCondition方法,如果没有则降级兜底
const fallbackFn = (child) => {
if (condition(child)) {
callback(child);
}
child.children.forEach(grandChild => fallbackFn(grandChild));
}
for (let i = 0, l = children.length; i < l; i++) {
children[i].traverseByCondition(callback, condition);
// @ts-ignore
if (children[i].traverseByCondition) {
children[i].traverseByCondition(callback, condition);
} else {
// 降级兜底
fallbackFn(children[i]);
}
}
}
@@ -21,8 +35,8 @@ THREE.Object3D.prototype.traverseByCondition = function(callback, condition){
* 判断 parentObj 是否是 当前对象 的任意层级祖先(包括祖父、曾祖父等)
* @param parentObj - 可能是祖先的对象
*/
THREE.Object3D.prototype.isAncestor = function(parentObj) {
let current:THREE.Object3D | null = this;
THREE.Object3D.prototype.isAncestor = function (parentObj) {
let current: THREE.Object3D | null = this;
while (current) {
if (current === parentObj) return true;
current = current.parent;
@@ -33,7 +47,7 @@ THREE.Object3D.prototype.isAncestor = function(parentObj) {
/**
* 重写toJSON方法
*/
THREE.Object3D.prototype.toJSON = function(meta:any) {
THREE.Object3D.prototype.toJSON = function (meta: any) {
// 当从JSON.stringify调用时,meta是一个字符串
const isRootObject = (meta === undefined || typeof meta === 'string');
@@ -60,7 +74,7 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
}
// 标准Object3D序列化
const object:any = {
const object: any = {
uuid: this.uuid,
type: this.type
};
@@ -184,14 +198,14 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
// 判断元数据是否含有材质
// 创建新变量替代,不然正在使用的材质被还原回this.metaData.material会造成播放异常
let _material = this.material;
if(this.metaData?.material){
if (this.metaData.material instanceof THREE.Material){
if (this.metaData?.material) {
if (this.metaData.material instanceof THREE.Material) {
_material = this.metaData.material;
}
}
if (Array.isArray(_material)) {
const uuids:string[] = [];
const uuids: string[] = [];
for (let i = 0, l = _material.length; i < l; i++) {
uuids.push(serialize(meta.materials, _material[i]));
@@ -217,10 +231,10 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
for (let i = 0; i < this.animations.length; i++) {
let animation = this.animations[i];
// 20250306 修复动画导出问题(代码中处理了object3D.animations,此属性下是AnimationAction数组)
if(animation instanceof THREE.AnimationAction){
if (animation instanceof THREE.AnimationAction) {
animation = animation.getClip();
}
if(!animation) continue;
if (!animation) continue;
object.animations.push(serialize(meta.animations, animation));
}
@@ -244,7 +258,7 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
if (skeletons.length > 0) output.skeletons = skeletons;
if (animations.length > 0) output.animations = animations.map(animation => {
animation.tracks = animation.tracks.map(track => {
if(!track.type){
if (!track.type) {
track.type = 'vector';
}
return track;
@@ -261,7 +275,7 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
// 从缓存哈希中提取数据,删除每个项目上的元数据并作为数组返回
function extractFromCache(cache) {
const values:any = [];
const values: any = [];
for (const key in cache) {
const data = cache[key];
delete data.metadata;