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-06-12 11:45:45 +08:00
|
|
|
|
import { Database, PhysicalMaterialRecord, TextureTableRecord } from "webcad_ue4_api";
|
2025-04-14 16:37:17 +08:00
|
|
|
|
import { LoadImageFromUrl } from "../helpers/helper.imageLoader";
|
2025-06-13 15:24:17 +08:00
|
|
|
|
import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping, Texture } from "three";
|
2025-04-14 16:37:17 +08:00
|
|
|
|
import { materialRenderer } from "../common/MaterialRenderer";
|
2025-05-09 19:29:09 +08:00
|
|
|
|
import { MaterialIn, MaterialOut } from "../common/MaterialSerializer";
|
2025-05-29 15:53:01 +08:00
|
|
|
|
import { GetConfig } from "../lib/libOutputConfig";
|
2025-06-18 17:45:12 +08:00
|
|
|
|
import { AsyncDelay } from "../helpers/helper.async";
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
2025-05-09 16:31:28 +08:00
|
|
|
|
const sceneSetup = () => {
|
2025-05-09 11:23:57 +08:00
|
|
|
|
let _editor: MaterialEditor | undefined;
|
2025-05-09 14:47:30 +08:00
|
|
|
|
let _database: Database | undefined;
|
2025-05-29 19:00:36 +08:00
|
|
|
|
const _material = ref<PhysicalMaterialRecord>(new PhysicalMaterialRecord());
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const _currGeometry = ref<string>('球');
|
2025-06-13 15:24:17 +08:00
|
|
|
|
const _currTexture = ref<TextureTableRecord>();
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const CurrGeometry = computed({
|
|
|
|
|
|
get: () => _currGeometry.value,
|
|
|
|
|
|
set: (val: string) => ChangeGeometry(val)
|
|
|
|
|
|
})
|
2025-06-13 15:24:17 +08:00
|
|
|
|
const CurrTexture = computed<TextureTableRecord>(() => _currTexture.value);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const Geometries = ref<string[]>([]);
|
2025-05-29 19:00:36 +08:00
|
|
|
|
const Material = computed(() => _material.value);
|
2025-05-29 15:53:01 +08:00
|
|
|
|
const CurrentShowObject = computed(() => _editor.ShowObject);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
|
|
|
|
|
function Initial(canvas: HTMLElement) {
|
|
|
|
|
|
if (_editor) {
|
|
|
|
|
|
console.warn("SceneStore has already been initialized");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-05-09 14:47:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 初始化Database
|
|
|
|
|
|
_database = new Database();
|
|
|
|
|
|
_database.hm.Enable = false; // 关闭历史记录功能
|
|
|
|
|
|
Material.value.Name = _database.MaterialTable.AllocateName(); // 使用Database为材质分配材质名
|
|
|
|
|
|
_database.MaterialTable.Add(Material.value as PhysicalMaterialRecord);
|
2025-05-29 15:53:01 +08:00
|
|
|
|
|
2025-04-14 16:37:17 +08:00
|
|
|
|
// 为Material配置一个ObjectId,否则其无法被序列化
|
2025-05-09 14:47:30 +08:00
|
|
|
|
// Material.value.objectId = new ObjectId(undefined, undefined);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
2025-05-09 16:31:28 +08:00
|
|
|
|
_editor = new MaterialEditor();
|
2025-04-14 16:37:17 +08:00
|
|
|
|
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() {
|
|
|
|
|
|
Material.value.GoodBye();
|
|
|
|
|
|
_editor?.Dispose();
|
|
|
|
|
|
_editor = undefined;
|
2025-05-09 14:47:30 +08:00
|
|
|
|
_database.Destroy();
|
|
|
|
|
|
_database = undefined;
|
2025-05-09 11:23:57 +08:00
|
|
|
|
window.onresize = undefined;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
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() {
|
2025-05-29 19:00:36 +08:00
|
|
|
|
// TODO: Danger: 如果等待下面这一行,会导致更新卡住(未知问题)
|
|
|
|
|
|
Material.value.Update();
|
|
|
|
|
|
// Material.value.Material.needsUpdate = true;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
await _editor.Update();
|
|
|
|
|
|
Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-13 15:24:17 +08:00
|
|
|
|
|
|
|
|
|
|
/** 这是自定义材质更新方法,WebCAD库中的TextureTableRecord.TextureUpdate方法在导出的时候被删除了,所以需要自己实现 */
|
|
|
|
|
|
function UpdateTexture() {
|
|
|
|
|
|
const record = _currTexture.value;
|
|
|
|
|
|
const texture = record['texture'] as Texture;
|
|
|
|
|
|
texture.wrapS = record.WrapS;
|
|
|
|
|
|
texture.wrapT = record.WrapT;
|
|
|
|
|
|
texture.anisotropy = 16;
|
|
|
|
|
|
texture.rotation = record.rotation;
|
|
|
|
|
|
texture.repeat.set(record.repeatX, record.repeatY);
|
|
|
|
|
|
texture.offset.set(record.moveX, record.moveY);
|
|
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
|
|
Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-29 15:53:01 +08:00
|
|
|
|
async function ChangeTextureFromUrlAsync(url?: string) {
|
2025-05-09 14:47:30 +08:00
|
|
|
|
// 关联贴图
|
|
|
|
|
|
const db = Material.value.Db;
|
2025-06-13 15:24:17 +08:00
|
|
|
|
// 材质未初始化
|
|
|
|
|
|
if (!db) {
|
|
|
|
|
|
console.warn("Material has not been initialized");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-06-18 17:37:08 +08:00
|
|
|
|
|
2025-06-18 18:17:37 +08:00
|
|
|
|
// 如果url为空,则保留原有材质中的纹理(修改模式),否则重新实例化纹理对象
|
|
|
|
|
|
let record = Material.value.map?.Object as TextureTableRecord;
|
|
|
|
|
|
if (url) {
|
|
|
|
|
|
record = new TextureTableRecord();
|
|
|
|
|
|
record.Name = db.TextureTable.AllocateName();
|
|
|
|
|
|
db.TextureTable.Add(record);
|
|
|
|
|
|
// 替换map
|
|
|
|
|
|
Material.value.map = record.Id;
|
|
|
|
|
|
}
|
2025-04-14 16:37:17 +08:00
|
|
|
|
|
2025-06-13 15:24:17 +08:00
|
|
|
|
// 设置Store
|
|
|
|
|
|
_currTexture.value = record;
|
|
|
|
|
|
const texture = record['texture'] as Texture;
|
2025-05-29 15:53:01 +08:00
|
|
|
|
if (url) {
|
|
|
|
|
|
record.imageUrl = url;
|
2025-06-13 15:24:17 +08:00
|
|
|
|
texture.image = undefined;
|
2025-05-29 15:53:01 +08:00
|
|
|
|
}
|
2025-05-09 14:47:30 +08:00
|
|
|
|
|
2025-06-13 15:24:17 +08:00
|
|
|
|
if (!texture.image) {
|
2025-06-18 18:17:37 +08:00
|
|
|
|
console.warn('Load Image: ', GetConfig().host + '/' + record.imageUrl);
|
2025-05-29 15:53:01 +08:00
|
|
|
|
const img = await LoadImageFromUrl(GetConfig().host + '/' + record.imageUrl);
|
2025-06-13 15:24:17 +08:00
|
|
|
|
texture.image = img;
|
2025-05-29 15:53:01 +08:00
|
|
|
|
}
|
2025-06-13 15:24:17 +08:00
|
|
|
|
|
|
|
|
|
|
UpdateTexture();
|
2025-06-18 17:37:08 +08:00
|
|
|
|
await record.Update();
|
2025-06-18 17:45:12 +08:00
|
|
|
|
await AsyncDelay(10);
|
2025-04-14 16:37:17 +08:00
|
|
|
|
await UpdateMaterialAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-08 11:34:35 +08:00
|
|
|
|
async function SerializeMaterialAsync() {
|
2025-04-14 16:37:17 +08:00
|
|
|
|
const matJson = MaterialOut(Material.value as PhysicalMaterialRecord);
|
2025-05-09 14:47:30 +08:00
|
|
|
|
console.log(matJson);
|
2025-05-08 11:34:35 +08:00
|
|
|
|
return matJson;
|
2025-04-14 16:37:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 19:29:09 +08:00
|
|
|
|
async function ImportMaterialAsync(materialJson: string) {
|
|
|
|
|
|
const material = MaterialIn(JSON.parse(materialJson));
|
2025-05-29 19:00:36 +08:00
|
|
|
|
_material.value = material;
|
|
|
|
|
|
_editor.setMaterial(_material.value as PhysicalMaterialRecord);
|
2025-05-29 15:53:01 +08:00
|
|
|
|
await ChangeTextureFromUrlAsync();
|
2025-05-29 19:00:36 +08:00
|
|
|
|
await UpdateMaterialAsync();
|
2025-05-09 19:29:09 +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,
|
2025-05-09 19:29:09 +08:00
|
|
|
|
CurrTexture,
|
2025-04-14 16:37:17 +08:00
|
|
|
|
Geometries,
|
|
|
|
|
|
Material,
|
|
|
|
|
|
Initial,
|
|
|
|
|
|
Update,
|
2025-06-13 15:24:17 +08:00
|
|
|
|
UpdateTexture,
|
2025-04-14 16:37:17 +08:00
|
|
|
|
UpdateMaterialAsync,
|
2025-05-09 19:29:09 +08:00
|
|
|
|
ChangeTextureFromUrlAsync,
|
2025-05-08 11:34:35 +08:00
|
|
|
|
SerializeMaterialAsync,
|
2025-05-09 19:29:09 +08:00
|
|
|
|
ImportMaterialAsync,
|
2025-05-09 11:23:57 +08:00
|
|
|
|
GenerateMaterialLogoAsync,
|
2025-05-29 15:53:01 +08:00
|
|
|
|
Dispose,
|
2025-05-29 19:00:36 +08:00
|
|
|
|
CurrentShowObject,
|
|
|
|
|
|
GetEditor: () => _editor
|
2025-04-14 16:37:17 +08:00
|
|
|
|
};
|
2025-05-09 16:31:28 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export const useScene = defineStore('scene', sceneSetup);
|
|
|
|
|
|
export const useSceneRaw = defineStore('sceneRaw', sceneSetup); // 独立场景,用来静默执行材质序列化
|
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
|
|
|
|
}
|