Skip to content

Commit

Permalink
Fix outline transform error (#48)
Browse files Browse the repository at this point in the history
* fix: inherit worldMatrix after remove child
  • Loading branch information
zhuxudong authored Aug 8, 2022
1 parent c6d3dc2 commit c322a89
Showing 1 changed file with 34 additions and 11 deletions.
45 changes: 34 additions & 11 deletions packages/outline/src/OutlineManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
dependentComponents,
Entity,
Material,
Matrix,
MeshRenderer,
PrimitiveMesh,
RenderTarget,
Expand Down Expand Up @@ -41,6 +42,10 @@ export class OutlineManager extends Script {
private _replaceColor: Color = new Color(1, 0, 0, 1);
private _outlineEntities: Entity[] = [];

private _entityMap: Array<{ entity: Entity; parent: Entity; worldMatrix: Matrix }> = [];
private _materialMap: Array<{ renderer: MeshRenderer; material: Material }> = [];
private _renderers: MeshRenderer[] = [];

/** outline color. */
get color(): Color {
return this._material.shaderData.getColor(OutlineManager._outlineColorProp);
Expand Down Expand Up @@ -114,7 +119,9 @@ export class OutlineManager extends Script {
* @param entity - The entity you wanna add.
*/
addEntity(entity: Entity) {
this._outlineEntities.push(entity);
if (this._outlineEntities.indexOf(entity) === -1) {
this._outlineEntities.push(entity);
}
}

/** @internal */
Expand All @@ -126,19 +133,32 @@ export class OutlineManager extends Script {
const originalSolidColor = scene.background.solidColor;
const originalBackgroundMode = scene.background.mode;
const originalScene = this.engine.sceneManager.activeScene;
const parentMap = new Map<Entity, Entity>();
const materialMap = new Map<MeshRenderer, Material>();

const renderers = this._renderers;
const materialMap = this._materialMap;
const entityMap = this._entityMap;
materialMap.length = 0;
entityMap.length = 0;

for (let i = 0, length = this._outlineEntities.length; i < length; i++) {
const entity = this._outlineEntities[i];
const renderers: MeshRenderer[] = [];
entity.getComponentsIncludeChildren(MeshRenderer, renderers);
parentMap.set(entity, entity.parent);
const originalWorldMatrix = entity.transform.worldMatrix.clone();
const originalParent = entity.parent;

this._outlineRoot.addChild(entity);
entity.transform.worldMatrix = originalWorldMatrix;

entityMap.push({
entity,
parent: originalParent,
worldMatrix: originalWorldMatrix
});

renderers.length = 0;
entity.getComponentsIncludeChildren(MeshRenderer, renderers);
for (let j = 0; j < renderers.length; j++) {
const renderer = renderers[j];
materialMap.set(renderer, renderer.getMaterial());
materialMap.push({ renderer, material: renderer.getMaterial() });
renderer.setMaterial(this._replaceMaterial);
}
}
Expand All @@ -165,24 +185,27 @@ export class OutlineManager extends Script {
scene.background.solidColor = originalSolidColor;
scene.background.mode = originalBackgroundMode;

parentMap.forEach((parent, entity) => {
entityMap.forEach(({ entity, parent, worldMatrix }) => {
if (!parent) {
scene.addRootEntity(entity);
} else {
parent.addChild(entity);
}
entity.transform.worldMatrix = worldMatrix;
});
materialMap.forEach((material, renderer) => {
materialMap.forEach(({ material, renderer }) => {
renderer.setMaterial(material);
});
}

/** @internal */
onDestroy() {
this._outlineRoot.destroy();
this._screenEntity.destroy();
this._outlineScene.destroy();
this._renderTarget.getColorTexture().destroy(true);
this._renderTarget.destroy();
this._renderers = null;
this._entityMap = null;
this._materialMap = null;
}
}

Expand Down

0 comments on commit c322a89

Please sign in to comment.