添加材质切换,调节功能
This commit is contained in:
150
src/stores/sceneStore.ts
Normal file
150
src/stores/sceneStore.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { MaterialEditor } from "../common/MaterialEditor";
|
||||
import { Database, ObjectId, PhysicalMaterialRecord, TextureTableRecord } from "webcad_ue4_api";
|
||||
import { LoadImageFromUrl } from "../helpers/helper.imageLoader";
|
||||
import { Texture } from "three";
|
||||
import { materialRenderer } from "../common/MaterialRenderer";
|
||||
import { ImgsUrl, MaterialUrls } from "../api/Api";
|
||||
import { Post, PostJson, RequestStatus } from "../api/Request";
|
||||
import { MaterialOut } from "../common/MaterialSerializer";
|
||||
import { DeflateAsync } from "../helpers/helper.compression";
|
||||
|
||||
export const useScene = defineStore('scene', () => {
|
||||
let _editor: MaterialEditor;
|
||||
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;
|
||||
}
|
||||
|
||||
// 为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 = () => {
|
||||
view.OnSize(canvas.clientWidth, canvas.clientHeight);
|
||||
view.UpdateRender();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
Material.value.map = record.Id;
|
||||
_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();
|
||||
}
|
||||
|
||||
interface UploadMaterialRequest {
|
||||
dirId: string;
|
||||
materialName: string;
|
||||
}
|
||||
async function UploadMaterialAsync(request: UploadMaterialRequest) {
|
||||
const logoPath = await HandleUpdateLogo();
|
||||
const matJson = MaterialOut(Material.value as PhysicalMaterialRecord);
|
||||
const data = await PostJson(MaterialUrls.create, {
|
||||
dir_id: request,
|
||||
name: request.materialName,
|
||||
logo: logoPath,
|
||||
// jsonString -> Deflate -> BinaryString -> Base64
|
||||
file: btoa(String.fromCharCode(...await DeflateAsync(matJson))),
|
||||
zip_type: 'gzip',
|
||||
});
|
||||
if (data.err_code !== RequestStatus.Ok) {
|
||||
throw new Error(data.err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
async function HandleUpdateLogo() {
|
||||
const blob = await materialRenderer.getBlob(Material.value.Material);
|
||||
const file = new File([blob], "blob.png", { type: blob.type });
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
|
||||
let data = await Post(ImgsUrl.logo, formData);
|
||||
|
||||
let logoPath = "";
|
||||
if (data.err_code === RequestStatus.Ok) {
|
||||
logoPath = data.images.path;
|
||||
}
|
||||
return logoPath;
|
||||
}
|
||||
|
||||
return {
|
||||
CurrGeometry,
|
||||
Geometries,
|
||||
Material,
|
||||
Initial,
|
||||
Update,
|
||||
UpdateMaterialAsync,
|
||||
ChangeTextureAsync,
|
||||
UpdateTexture,
|
||||
UploadMaterialAsync,
|
||||
};
|
||||
});
|
||||
|
||||
export type TextureAdjustment = {
|
||||
wrapS: number,
|
||||
wrapT: number,
|
||||
rotation: number,
|
||||
repeatX: number,
|
||||
repeatY: number,
|
||||
moveX: number,
|
||||
moveY: number
|
||||
}
|
||||
Reference in New Issue
Block a user