2025-04-14 16:37:17 +08:00
|
|
|
|
import { defineStore } from "pinia";
|
2025-05-08 11:34:35 +08:00
|
|
|
|
import { computed, ref } from "vue";
|
2025-04-14 16:37:17 +08:00
|
|
|
|
import { MaterialEditor } from "../common/MaterialEditor";
|
2025-05-08 11:34:35 +08:00
|
|
|
|
import { ObjectId, PhysicalMaterialRecord, TextureTableRecord } from "webcad_ue4_api";
|
2025-04-14 16:37:17 +08:00
|
|
|
|
import { LoadImageFromUrl } from "../helpers/helper.imageLoader";
|
|
|
|
|
|
import { Texture } from "three";
|
|
|
|
|
|
import { materialRenderer } from "../common/MaterialRenderer";
|
|
|
|
|
|
import { MaterialOut } from "../common/MaterialSerializer";
|
|
|
|
|
|
|
|
|
|
|
|
export const useScene = defineStore('scene', () => {
|
2025-05-09 11:23:57 +08:00
|
|
|
|
let _editor: MaterialEditor | undefined;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const _currGeometry = ref<string>('球');
|
|
|
|
|
|
const _currTexture = ref<Texture>();
|
|
|
|
|
|
const CurrGeometry = computed({
|
|
|
|
|
|
get: () => _currGeometry.value,
|
|
|
|
|
|
set: (val: string) => ChangeGeometry(val)
|
|
|
|
|
|
})
|
|
|
|
|
|
const CurrTexture = computed<Texture>(() => _currTexture.value);
|
|
|
|
|
|
const Geometries = ref<string[]>([]);
|
|
|
|
|
|
const Material = ref<PhysicalMaterialRecord>(new PhysicalMaterialRecord());
|
|
|
|
|
|
|
|
|
|
|
|
function Initial(canvas: HTMLElement) {
|
|
|
|
|
|
if (_editor) {
|
|
|
|
|
|
console.warn("SceneStore has already been initialized");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-05-09 11:23:57 +08:00
|
|
|
|
|
2025-04-14 16:37:17 +08:00
|
|
|
|
// 为Material配置一个ObjectId,否则其无法被序列化
|
|
|
|
|
|
Material.value.objectId = new ObjectId(undefined, undefined);
|
|
|
|
|
|
|
|
|
|
|
|
_editor = MaterialEditor.GetInstance();
|
|
|
|
|
|
Geometries.value = Array.from(_editor.Geometrys.keys());
|
|
|
|
|
|
_currGeometry.value = _editor.CurGeometryName;
|
|
|
|
|
|
|
|
|
|
|
|
_editor.SetViewer(canvas);
|
|
|
|
|
|
_editor.setMaterial((Material.value) as PhysicalMaterialRecord);
|
|
|
|
|
|
|
|
|
|
|
|
const view = _editor.Viewer;
|
|
|
|
|
|
window.onresize = () => {
|
2025-05-09 11:23:57 +08:00
|
|
|
|
view.SetSize(canvas.clientWidth, canvas.clientHeight);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
view.UpdateRender();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 11:23:57 +08:00
|
|
|
|
function Dispose() {
|
|
|
|
|
|
console.log("Disposing...");
|
|
|
|
|
|
Material.value.GoodBye();
|
|
|
|
|
|
_editor?.Dispose();
|
|
|
|
|
|
_editor = undefined;
|
|
|
|
|
|
window.onresize = undefined;
|
|
|
|
|
|
|
|
|
|
|
|
// 释放Singleton
|
|
|
|
|
|
MaterialEditor.ReleaseInstance();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-14 16:37:17 +08:00
|
|
|
|
function ChangeGeometry(geoName: string) {
|
|
|
|
|
|
_currGeometry.value = geoName;
|
|
|
|
|
|
let geo = _editor.Geometrys.get(_currGeometry.value);
|
|
|
|
|
|
if (geo) {
|
|
|
|
|
|
_editor.ShowMesh.geometry = geo;
|
|
|
|
|
|
_editor.Viewer.UpdateRender();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function Update() {
|
|
|
|
|
|
_editor.Viewer.UpdateRender();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function UpdateMaterialAsync() {
|
|
|
|
|
|
await Material.value.Update();
|
|
|
|
|
|
await _editor.Update();
|
|
|
|
|
|
Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function ChangeTextureAsync(url: string) {
|
|
|
|
|
|
const record = new TextureTableRecord();
|
|
|
|
|
|
record.objectId = new ObjectId(undefined, record);
|
|
|
|
|
|
|
|
|
|
|
|
const img = await LoadImageFromUrl(url);
|
|
|
|
|
|
|
|
|
|
|
|
_currTexture.value = record['texture'] as Texture;
|
|
|
|
|
|
_currTexture.value.image = img;
|
2025-05-08 11:34:35 +08:00
|
|
|
|
Material.value.map = img ? record.Id : undefined;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
_currTexture.value.needsUpdate = true;
|
|
|
|
|
|
await UpdateMaterialAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function UpdateTexture(adjustment: TextureAdjustment) {
|
|
|
|
|
|
const texture = _currTexture.value;
|
|
|
|
|
|
texture.wrapS = adjustment.wrapS;
|
|
|
|
|
|
texture.wrapT = adjustment.wrapT;
|
|
|
|
|
|
texture.anisotropy = 16;
|
|
|
|
|
|
texture.rotation = adjustment.rotation;
|
|
|
|
|
|
texture.repeat.set(adjustment.repeatX, adjustment.repeatY);
|
|
|
|
|
|
texture.offset.set(adjustment.moveX, adjustment.moveY);
|
|
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
|
|
|
|
|
|
|
|
Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-08 11:34:35 +08:00
|
|
|
|
async function SerializeMaterialAsync() {
|
2025-04-15 09:35:54 +08:00
|
|
|
|
// TODO: Warn: 是否要生成logo路径?
|
|
|
|
|
|
// const logoPath = await HandleUpdateLogo();
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const matJson = MaterialOut(Material.value as PhysicalMaterialRecord);
|
2025-05-08 11:34:35 +08:00
|
|
|
|
return matJson;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-08 11:34:35 +08:00
|
|
|
|
async function GenerateMaterialLogoAsync() {
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const blob = await materialRenderer.getBlob(Material.value.Material);
|
2025-05-08 11:34:35 +08:00
|
|
|
|
return blob;
|
|
|
|
|
|
// const file = new File([blob], "blob.png", { type: blob.type });
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
2025-05-08 11:34:35 +08:00
|
|
|
|
// const formData = new FormData();
|
|
|
|
|
|
// formData.append("file", file);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
2025-05-08 11:34:35 +08:00
|
|
|
|
// let data = await Post(ImgsUrl.logo, formData);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
2025-05-08 11:34:35 +08:00
|
|
|
|
// let logoPath = "";
|
|
|
|
|
|
// if (data.err_code === RequestStatus.Ok) {
|
|
|
|
|
|
// logoPath = data.images.path;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// return logoPath;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
CurrGeometry,
|
|
|
|
|
|
Geometries,
|
|
|
|
|
|
Material,
|
|
|
|
|
|
Initial,
|
|
|
|
|
|
Update,
|
|
|
|
|
|
UpdateMaterialAsync,
|
|
|
|
|
|
ChangeTextureAsync,
|
|
|
|
|
|
UpdateTexture,
|
2025-05-08 11:34:35 +08:00
|
|
|
|
SerializeMaterialAsync,
|
2025-05-09 11:23:57 +08:00
|
|
|
|
GenerateMaterialLogoAsync,
|
|
|
|
|
|
Dispose
|
2025-04-14 16:37:17 +08:00
|
|
|
|
};
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
export type TextureAdjustment = {
|
|
|
|
|
|
wrapS: number,
|
|
|
|
|
|
wrapT: number,
|
|
|
|
|
|
rotation: number,
|
|
|
|
|
|
repeatX: number,
|
|
|
|
|
|
repeatY: number,
|
|
|
|
|
|
moveX: number,
|
|
|
|
|
|
moveY: number
|
2025-05-08 11:34:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
export interface UploadMaterialRequest {
|
|
|
|
|
|
dirId: string;
|
|
|
|
|
|
materialName: string;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
}
|