Halo, Saya melihat sejumlah besar peringatan datang dari troika-worker.utils.esm.js dengan pesan ini.
Semuanya tampaknya berfungsi dengan baik
ada ide?
Hmm, peringatan itu tidak terpicu hingga ada >1000 permintaan pekerja terbuka. Apakah Anda memiliki banyak sekali contoh teks?
Ya, tapi tidak lebih dari 1000 (setidaknya tidak sengaja)
lebih seperti beberapa ratus
Inilah yang saya render
Tapi jadi apa yang Anda katakan bahwa mungkin ada bug di pihak saya di mana saya membuat lebih banyak contoh daripada yang sebenarnya saya butuhkan dan setelah saya melewati 1000 hitungan itu mulai menimbulkan kesalahan?
Saya telah menyetel instance yang tidak memiliki konten ke .visible = false
tapi saya kira itu masih berarti instance itu ada
apakah Anda akan merekomendasikan daripada menggunakan prop .visible untuk menghapus instance yang tidak digunakan sepenuhnya?
Ahh, itu bisa menjelaskannya. Panggilan apa pun ke .sync() akan tetap dilakukan kepada pekerja di latar belakang meskipun visible:false , dan panggilan tersebut akan menumpuk.
Saya pikir saya pribadi akan memilih untuk membuat/membuang label sesuai permintaan, atau setidaknya mencegah panggilan .sync() untuk yang tersembunyi. Semua permintaan pekerja itu menggunakan pekerja yang sama, jadi jika sibuk memproses label tersembunyi, itu bisa menunda pemrosesan label yang terlihat.
Namun, saya membuat beberapa asumsi, karena tidak melihat kode LabelView Anda yang sebenarnya. Mungkin masih ada bug di pihak saya, jadi LMK apa yang Anda temukan.
Baru saja mencoba memanggil .sync() ketika .visible === true
tapi tetap mendapat peringatan
jika sebaliknya saya hanya membuat instance untuk objek yang terlihat dan menghancurkan yang tidak digunakan maka peringatannya hilang
Hmm, Text
sendiri hanya memanggil sync() di onBeforeRender, yang _seharusnya tidak_ terpicu jika visible=false.
Apakah kode pembungkus LabelView Anda tersedia di mana saja saya bisa mengintip?
Itu bagian dari proyek sumber tertutup
tapi di sini adalah kelas yang relevan, yang mungkin cukup
import {Mesh, MeshBasicMaterial} from "three";
import R from "../../../../../../../../../../resources/Namespace";
import BaseView, {ViewType} from "./BaseView";
import {Text} from "troika-three-text";
import {GeometryInstances} from "../instances/GeometryInstances";
import {MaterialInstances} from "../instances/MaterialInstances";
export enum TextAlign {
left = "left",
right = "right",
center = "center",
justify = "justify",
}
export enum HorizontalAlign {
left = "left",
right = "right",
center = "center",
}
export enum VerticalAlign {
top = "top",
topBaseline = "top-baseline",
middle = "middle",
bottomBaseline = "bottom-baseline",
bottom = "bottom",
}
export interface ILabelData {
content: string;
fontFace?: string;
fontSize?: number;
alignment?: TextAlign;
horizontalAlign?: HorizontalAlign;
verticalAlign?: VerticalAlign;
color?: string;
opacity?: number;
backgroundColor?: string;
highlightable: boolean;
}
export default class LabelView extends BaseView {
get viewObject() {
return this._viewObject as any;
}
get content() {
return this.textMesh.text;
}
set content(content: string) {
if (content !== this.textMesh.text) {
this.textMesh.text = content;
this.textMesh.visible = !!content;
this.syncIfVisible();
}
}
private syncIfVisible() {
// Better for perf: https://github.com/protectwise/troika/issues/112
if (this.textMesh?.text && this.textMesh?.visible && this._isVisible) {
this.textMesh.sync();
}
}
set textAlign(alignment: TextAlign) {
this.textMesh.textAlign = alignment;
this.syncIfVisible();
}
set horizontalAlign(alignment: HorizontalAlign) {
this.textMesh.anchorX = alignment;
this.syncIfVisible();
}
set verticalAlign(alignment: VerticalAlign) {
this.textMesh.anchorY = alignment;
this.syncIfVisible();
}
private backgroundMesh: Mesh | undefined;
private readonly textMesh: any;
private readonly foregroundColor: string;
private highlightable: boolean;
constructor(labelData: ILabelData) {
super(ViewType.Label);
this.foregroundColor = labelData.color || R.colors.elements.labels.foreground;
this.highlightable = labelData.highlightable;
if (labelData.backgroundColor) {
this.textMesh = this.createTextMesh(
labelData.content,
labelData.fontFace,
labelData.fontSize,
labelData.alignment,
labelData.horizontalAlign,
labelData.verticalAlign,
this.foregroundColor,
labelData.opacity,
1);
this.textMesh.addEventListener("synccomplete", () => {
if (this.backgroundMesh) {
this._viewObject.remove(this.backgroundMesh);
}
if (this.textMesh.text) {
const bounds = this.textMesh.textRenderInfo.blockBounds;
this.backgroundMesh =
this.createBackgroundBox(bounds[0], bounds[1], bounds[2], bounds[3], 0);
this._viewObject.add(this.backgroundMesh);
}
});
} else {
this.textMesh = this.createTextMesh(
labelData.content,
labelData.fontFace,
labelData.fontSize,
labelData.alignment,
labelData.horizontalAlign,
labelData.verticalAlign,
this.foregroundColor,
labelData.opacity,
0);
}
this.syncIfVisible();
this._viewObject.add(this.textMesh);
}
public onFrameRendered(elapsedTime: number) {
if (this.highlightable) {
this.setLabelHighlightState();
}
}
private setLabelHighlightState() {
const labelMaterial = this.textMesh.material as MeshBasicMaterial;
if (this._isHighlighted) {
labelMaterial.color.set(R.colors.elements.labels.highlighted);
} else {
labelMaterial.color.set(this.foregroundColor);
}
}
private createTextMesh(content: string,
fontFace = R.layout.labels.font_face.regular,
fontSize = R.layout.labels.font_size,
textAlign = TextAlign.center,
horizontalAlign = HorizontalAlign.center,
verticalAlign = VerticalAlign.middle,
color: string,
opacity = 1,
zLevel: number) {
const labelMesh = new Text();
labelMesh.font = fontFace;
labelMesh.text = content || "";
labelMesh.fontSize = fontSize;
labelMesh.position.z = zLevel;
labelMesh.color = color;
labelMesh.textAlign = textAlign;
labelMesh.anchorX = horizontalAlign;
labelMesh.anchorY = verticalAlign;
labelMesh.material.opacity = opacity;
labelMesh.name = "LabelView";
return labelMesh;
}
private createBackgroundBox(startX: number, startY: number, endX: number, endY: number, zLevel: number) {
const paddingLeft = 1;
const paddingRight = 2;
const paddingTop = 1;
const paddingBottom = 0;
const width = Math.abs(startX) + Math.abs(endX) + paddingLeft + paddingRight;
const height = Math.abs(startY) + Math.abs(endY) + (paddingTop + paddingBottom);
const geometry = GeometryInstances.getInstance().getPlaneGeometryInstance(width, height);
const material = MaterialInstances.getInstance().backgroundColorMaterial;
const mesh = new Mesh(geometry, material);
const posX = ((startX + endX) / 2) + (paddingLeft / 4);
const posY = ((startY + endY) / 2) - (paddingBottom);
// The z level of element in accordance with standards defined in resources
mesh.position.set(posX, posY, zLevel);
mesh.name = "LabelBackgroundBox";
return mesh;
}
}
Hmm, firasat saya adalah syncIfVisible() dipanggil sebelum .visible disetel ke false, tetapi sulit untuk mengatakan dengan pasti tanpa mengetahui cara kerja sistem tampilan Anda.
Hal lain yang saya perhatikan adalah Anda mengeluarkan panggilan syncIfVisible setelah setiap perubahan properti individu (konten, textAlign, horizontalAlign, dll.) yang akan mengeluarkan lebih banyak panggilan ke pekerja daripada yang diperlukan. Jika sistem tampilan Anda memiliki siklus hidup di mana Anda dapat mengeluarkan satu panggilan sinkronisasi setelah semua properti individual disetel, itu akan jauh lebih baik.
Dari apa yang Anda jelaskan, saya pikir peringatan ini berperilaku seperti yang diharapkan; itu dengan benar menyoroti masalah kinerja. Saya menutup masalah ini; jangan ragu untuk membukanya kembali jika Anda percaya secara berbeda. Terima kasih!
Baru kembali ke ini
Jadi ternyata saya dengan mudah memiliki lebih dari 1000 contoh teks dalam adegan saya. Tapi ada tidak semua terlihat pada saat yang sama
Banyak dari mereka hanya muncul di mouse-over dari objek tertentu
Jadi saya bertanya-tanya apa cara terbaik untuk maju di sini:
Secara pribadi saya akan memilih opsi pertama. Saya bisa saja salah, tetapi saya rasa tidak ada gunanya memiliki semua objek label tersembunyi yang ada di grafik adegan.
Mengerti
Saya harus bisa menunjukkannya dengan cepat di mouse hover objek
Apakah Anda merekomendasikan untuk menghancurkannya setelah digunakan dan membuat yang baru saat melayang atau hanya menghapusnya dari adegan threeJs saja?
Sejujurnya saya tidak berpikir akan ada perbedaan yang mencolok. Saya akan mulai dengan apa pun yang paling sederhana untuk dikelola dan dioptimalkan hanya jika Anda melihat ada masalah.
Secara pribadi saya telah banyak melakukan pendekatan buat/hancurkan, dan itu selalu sangat cepat bagi saya.