diff --git a/source/Context/Status.tsx b/source/Context/Status.tsx index adf06fb..3bcb630 100644 --- a/source/Context/Status.tsx +++ b/source/Context/Status.tsx @@ -174,11 +174,13 @@ class Status extends Emitter { this.emit("objectChange"); this.emit("labelChange"); this.emit("behaviorChange"); + this.emit("clipChange"); // 清除焦点对象 this.setBehaviorObject(); this.setFocusObject(new Set()); this.setLabelObject(); + this.setClipObject(); // 映射 this.emit("fileLoad"); @@ -196,11 +198,13 @@ class Status extends Emitter { this.on("objectChange", handelFileChange); this.on("behaviorChange", handelFileChange); this.on("labelChange", handelFileChange); + this.on("clipChange", handelFileChange); this.on("individualChange", handelFileChange); this.on("groupAttrChange", handelFileChange); this.on("rangeAttrChange", handelFileChange); this.on("labelAttrChange", handelFileChange); this.on("behaviorAttrChange", handelFileChange); + this.on("clipAttrChange", handelFileChange); this.on("fileChange", () => this.archive.emit("fileChange")); } diff --git a/source/Model/Clip.ts b/source/Model/Clip.ts index f9cf1cc..f73a3c2 100644 --- a/source/Model/Clip.ts +++ b/source/Model/Clip.ts @@ -8,6 +8,7 @@ interface IDrawCommand { type: "points" | "cube"; id: string; data?: Float32Array; + mapId?: number[]; position?: number[]; radius?: number[]; parameter?: IAnyObject; @@ -143,7 +144,7 @@ class Clip { return res; } - public isArrayEqual(a1?: number[], a2?: number[]): boolean { + public isArrayEqual(a1?: Array, a2?: Array): boolean { if ((a1 && !a2) || (!a1 && a2)) { return false; @@ -179,6 +180,26 @@ class Clip { return undefined; } + /** + * ID 映射 + */ + private sorterIdMapper: Map = new Map(); + private sorterIdMapperNextId: number = 1; + + /** + * 获取映射ID + */ + private getMapperId = (id: string): number => { + let mapperId = this.sorterIdMapper.get(id); + if (mapperId === undefined) { + mapperId = this.sorterIdMapperNextId ++; + this.sorterIdMapper.set(id, mapperId); + return mapperId; + } else { + return mapperId; + } + } + /** * 录制一帧 */ @@ -196,10 +217,11 @@ class Clip { const lastCommand = this.getCommandFromLastFrame("points", object.id); // 记录 + const dataBuffer = object.exportPositionId(this.getMapperId); const recodeData: IDrawCommand = { type: "points", id: object.id, - data: object.exportPositionData() + data: dataBuffer[0] } // 对比校验 @@ -209,6 +231,12 @@ class Clip { recodeData.parameter = this.cloneRenderParameter(object.renderParameter); } + if (this.isArrayEqual(dataBuffer[1], lastCommand?.mapId)) { + recodeData.mapId = lastCommand?.mapId; + } else { + recodeData.mapId = dataBuffer[1]; + } + commands.push(recodeData); } @@ -290,6 +318,9 @@ class Clip { command.data = (lastCommand?.data === commands[j].data) ? this.LastFrameData as any : Array.from(commands[j].data ?? []); + command.mapId = (lastCommand?.mapId === commands[j].mapId) ? + this.LastFrameData as any : commands[j].mapId; + command.position = (lastCommand?.position === commands[j].position) ? this.LastFrameData as any : commands[j].position?.concat([]); @@ -336,12 +367,13 @@ class Clip { this.getCommandFromLastFrame(command.type, command.id, resFrame[resFrame.length - 1]) : undefined; - console.log(lastCommand); - // 记录 command.data = (this.LastFrameData as any === commands[j].data) ? lastCommand?.data : new Float32Array(commands[j].data ?? []); + command.mapId = (this.LastFrameData as any === commands[j].mapId) ? + lastCommand?.mapId : commands[j].mapId; + command.position = (this.LastFrameData as any === commands[j].position) ? lastCommand?.position : commands[j].position; diff --git a/source/Model/Group.ts b/source/Model/Group.ts index 024b737..f9f1a63 100644 --- a/source/Model/Group.ts +++ b/source/Model/Group.ts @@ -428,6 +428,22 @@ class Group extends CtrlObject { return dataBuffer; } + /** + * 导出个体id列表 + */ + public exportPositionId(idMapper: (id: string) => number ): [Float32Array, number[]] { + let bi = 0; let ii = 0; + let dataBuffer = new Float32Array(this.individuals.size * 3); + let idBUffer: number[] = new Array(this.individuals.size).fill(""); + this.individuals.forEach((individual) => { + idBUffer[ii ++] = idMapper(individual.id); + dataBuffer[bi ++] = individual.position[0]; + dataBuffer[bi ++] = individual.position[1]; + dataBuffer[bi ++] = individual.position[2]; + }); + return [dataBuffer, idBUffer]; + } + public override toArchive(): IArchiveCtrlObject & IArchiveGroup { return { ...super.toArchive(),