!1622 重构:材质界面

pull/1601/MERGE
黄诗津 3 years ago committed by ChenX
parent b679fb4420
commit bfa8f1196b

@ -310,22 +310,26 @@ export function ConverMaterialData(material: PhysicalMaterialRecord)
d.baseColorDarkColor = material.baseColorDarkColor.toArray(); d.baseColorDarkColor = material.baseColorDarkColor.toArray();
d.baseColorSaturability = material.baseColorSaturability; d.baseColorSaturability = material.baseColorSaturability;
//透明度附加 if (material.type === "玻璃")//透明度附加
d.opacityContrast = material.opacityContrast; {
d.opacityContrast = (1 - material.opacity) * 3;
d.opacityBorder = material.opacityBorder; d.opacityBorder = material.opacityBorder;
d.opacityMaximum = material.opacityMaximum; d.opacityMaximum = material.opacityMaximum;
d.opacityMinimum = material.opacityMinimum; d.opacityMinimum = material.opacityMinimum;
}
//高光 //高光
d.specular = material.specular; d.specular = material.specular;
d.selfLuminous = material.selfLuminous;//自发光 d.selfLuminous = material.selfLuminous;//自发光
//菲涅尔 if (material.type === "布料" || material.type === "皮革")//菲涅尔
{
d.fresnelPO = material.fresnelPO; d.fresnelPO = material.fresnelPO;
d.fresnelST = material.fresnelST; d.fresnelST = material.fresnelST;
d.fresnelLuminance = material.fresnelLuminance; d.fresnelLuminance = material.fresnelLuminance;
d.fresnelLightColor = material.fresnelLightColor.toArray(); d.fresnelLightColor = material.fresnelLightColor.toArray();
d.fresnelDarkColor = material.fresnelDarkColor.toArray(); d.fresnelDarkColor = material.fresnelDarkColor.toArray();
}
//锐化 //锐化
d.sharpen = material.sharpen; d.sharpen = material.sharpen;

@ -236,6 +236,7 @@ export const DefaultParamMap = Object.freeze({
selfLuminous: 0,//自发光强度 范围0-200 selfLuminous: 0,//自发光强度 范围0-200
//#region 透明度附加 默认折叠 //#region 透明度附加 默认折叠
opacity: 0.6,
opacityContrast: 1, //不透明度对比 默认1 opacityContrast: 1, //不透明度对比 默认1
opacityBorder: 1, //不透明度边界 默认1 opacityBorder: 1, //不透明度边界 默认1
opacityMaximum: 1, //不透明度最大值 默认1 opacityMaximum: 1, //不透明度最大值 默认1
@ -310,21 +311,24 @@ export const DefaultParamMap = Object.freeze({
selfLuminous: 0,//自发光强度 范围0-200 selfLuminous: 0,//自发光强度 范围0-200
})) as MaterialParam, })) as MaterialParam,
// 自定义: Object.freeze(Object.assign({ ...DefaultParam }, {
// })) as MaterialParam,
}); });
export type MaterialType = keyof (typeof DefaultParamMap); export type MaterialType = keyof (typeof DefaultParamMap);
export function SetMaterialParams(mtl: PhysicalMaterialRecord, param: MaterialParam): void export function SetMaterialParams(mtl: PhysicalMaterialRecord, param: MaterialParam): void
{ {
for (let key in DefaultParamMap.) for (let key in param)
{ {
let v = DefaultParamMap.[key];; let v = param[key];
if (v instanceof Color) if (v instanceof Color)
{ {
let c = mtl[key] as Color; let c = mtl[key] as Color;
c.copy(v); c.copy(v);
} }
else else
mtl[key] = DefaultParamMap.[key]; mtl[key] = param[key];
} }
} }

@ -95,8 +95,12 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
this.material.color.set(this.color); this.material.color.set(this.color);
this.material.transparent = this.transparent; this.material.transparent = this.transparent;
this.material.metalness = this.matalness;
this.material.opacity = this.opacity; if (this.type === "玻璃")
this.material.metalness = 0.2;
else
this.material.metalness = Math.min(0.8, this.matalness);
this.material.opacity = Math.max(0.1, this.opacity);
this.material.depthTest = this.depthTest; this.material.depthTest = this.depthTest;
this.material.bumpScale = this.bumpScale; this.material.bumpScale = this.bumpScale;
this.material.roughness = this.roughness; this.material.roughness = this.roughness;
@ -110,6 +114,9 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
this.material.map = texture; this.material.map = texture;
this.material.needsUpdate = true; this.material.needsUpdate = true;
} }
else
this.material.map = undefined;
if (this.useBumpMap && this.bumpMap && !this.bumpMap.IsErase) if (this.useBumpMap && this.bumpMap && !this.bumpMap.IsErase)
{ {
let map = this.bumpMap.Object as TextureTableRecord; let map = this.bumpMap.Object as TextureTableRecord;
@ -118,6 +125,9 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
this.material.bumpMap = texture; this.material.bumpMap = texture;
this.material.needsUpdate = true; this.material.needsUpdate = true;
} }
else
this.material.bumpMap = undefined;
if (this.roughnessMap && this.roughnessMap && !this.roughnessMap.IsErase) if (this.roughnessMap && this.roughnessMap && !this.roughnessMap.IsErase)
{ {
let map = this.roughnessMap.Object as TextureTableRecord; let map = this.roughnessMap.Object as TextureTableRecord;
@ -126,6 +136,9 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
this.material.roughnessMap = texture; this.material.roughnessMap = texture;
this.material.needsUpdate = true; this.material.needsUpdate = true;
} }
else
this.material.roughnessMap = undefined;
this.material.needsUpdate = true; this.material.needsUpdate = true;
this.AsyncUpdated(); this.AsyncUpdated();

@ -22,6 +22,8 @@ export class TextureTableRecord extends SymbolTableRecord
@AutoRecord moveX = 0;//材质位移 @AutoRecord moveX = 0;//材质位移
@AutoRecord moveY = 0; @AutoRecord moveY = 0;
@AutoRecord imgUrl: string = "";
set WrapS(wrap: Wrapping) set WrapS(wrap: Wrapping)
{ {
if (wrap !== this.wrapS) if (wrap !== this.wrapS)
@ -46,23 +48,23 @@ export class TextureTableRecord extends SymbolTableRecord
private texture: Texture = new Texture(); private texture: Texture = new Texture();
async Update() async Update()
{ {
let imgUrl: string;
if (this.imageUrl.endsWith("Default.png") || !this.imageUrl) if (this.imageUrl.endsWith("Default.png") || !this.imageUrl)
{ {
imgUrl = ResourcesCDN_HOST + "Default.webp"; this.imgUrl = ResourcesCDN_HOST + "Default.webp";
this.imageUrl = ""; this.imageUrl = "";
} }
else else
imgUrl = CURRENT_HOST + "/" + this.imageUrl; this.imgUrl = CURRENT_HOST + "/" + this.imageUrl;
if (!this.texture.image || (this.texture.image && this.texture.image.src !== imgUrl)) if (!this.texture.image || (this.texture.image && this.texture.image.src !== this.imgUrl))
this.texture.image = await LoadImageFromUrl(imgUrl); this.texture.image = await LoadImageFromUrl(this.imgUrl);
this.texture.wrapS = this.wrapS; this.texture.wrapS = this.wrapS;
this.texture.wrapT = this.wrapT; this.texture.wrapT = this.wrapT;
this.texture.anisotropy = 16; this.texture.anisotropy = 16;
this.texture.rotation = this.rotation; this.texture.rotation = this.rotation;
this.texture.repeat.set(this.repeatX, this.repeatY); this.texture.repeat.set(this.repeatX, this.repeatY);
this.texture.offset.set(this.moveX, this.moveY);
this.texture.needsUpdate = true; this.texture.needsUpdate = true;
for (let f of this.waits) for (let f of this.waits)

@ -15,7 +15,7 @@ export class MaterialEditor extends Singleton
{ {
Geometrys: Map<string, Geometry | BufferGeometry>; Geometrys: Map<string, Geometry | BufferGeometry>;
m_CurGeometryName = observable.box("球"); CurGeometryName = observable.box("球");
Canvas: HTMLElement; Canvas: HTMLElement;
ShowObject: Object3D; ShowObject: Object3D;
ShowMesh: Mesh; ShowMesh: Mesh;
@ -36,8 +36,8 @@ export class MaterialEditor extends Singleton
["立方体", new BoxBufferGeometry(1e3, 1e3, 1e3, 1, 1, 1)], ["立方体", new BoxBufferGeometry(1e3, 1e3, 1e3, 1, 1, 1)],
["环面纽结", new TorusKnotBufferGeometry(0.7 * 1e3, 0.3 * 1e3, 128, 64)], ["环面纽结", new TorusKnotBufferGeometry(0.7 * 1e3, 0.3 * 1e3, 128, 64)],
["圆锥体", new ConeBufferGeometry(1 * 1e3, 2 * 1e3, 32)], ["圆锥体", new ConeBufferGeometry(1 * 1e3, 2 * 1e3, 32)],
["球(多面)", new SphereBufferGeometry(1 * 1e3, 64, 64)], // ["球(多面)", new SphereBufferGeometry(1 * 1e3, 64, 64)],
["立方体(多面)", new BoxBufferGeometry(1 * 1e3, 1 * 1e3, 1 * 1e3, 128, 128, 128)] // ["立方体(多面)", new BoxBufferGeometry(1 * 1e3, 1 * 1e3, 1 * 1e3, 128, 128, 128)]
] ]
); );
} }
@ -49,6 +49,7 @@ export class MaterialEditor extends Singleton
this.Viewer.PreViewer.Cursor.CursorObject.visible = false; this.Viewer.PreViewer.Cursor.CursorObject.visible = false;
this.Viewer.CameraCtrl.CameraType = CameraType.PerspectiveCamera; this.Viewer.CameraCtrl.CameraType = CameraType.PerspectiveCamera;
this.Viewer.UsePass = false; this.Viewer.UsePass = false;
this.Viewer.Renderer.setClearColor(0xE0E0E0, 1);
this.initScene(); this.initScene();
new MaterialEditorCamerControl(this.Viewer); new MaterialEditorCamerControl(this.Viewer);
} }
@ -62,13 +63,13 @@ export class MaterialEditor extends Singleton
{ {
this.Canvas = canvas; this.Canvas = canvas;
this.initViewer(); this.initViewer();
this.m_CurGeometryName.set("球"); this.CurGeometryName.set("球");
} }
initScene() initScene()
{ {
let scene = this.Viewer.Scene; let scene = this.Viewer.Scene;
this.ShowObject = new Object3D(); this.ShowObject = new Object3D();
let geo = this.Geometrys.get(this.m_CurGeometryName.get()); let geo = this.Geometrys.get(this.CurGeometryName.get());
this.ShowMesh = new Mesh(geo); this.ShowMesh = new Mesh(geo);
this.ShowMesh.scale.set(1000, 1000, 1000); this.ShowMesh.scale.set(1000, 1000, 1000);
@ -76,7 +77,7 @@ export class MaterialEditor extends Singleton
scene.add(this.ShowObject); scene.add(this.ShowObject);
let remove = autorun(() => let remove = autorun(() =>
{ {
let geo = this.Geometrys.get(this.m_CurGeometryName.get()); let geo = this.Geometrys.get(this.CurGeometryName.get());
if (geo) if (geo)
{ {
this.ShowMesh.geometry = geo; this.ShowMesh.geometry = geo;
@ -111,7 +112,7 @@ export class MaterialEditor extends Singleton
async Update() async Update()
{ {
let mat = this.ShowMesh.material as MeshPhysicalMaterial; let mat = this.ShowMesh.material as MeshPhysicalMaterial;
if (this.Material.map && this.Material.map.Object) if (this.Material.map && this.Material.map.Object && this.Material.useMap)
{ {
let texture = this.Material.map.Object as TextureTableRecord; let texture = this.Material.map.Object as TextureTableRecord;
await texture.Update(); await texture.Update();

@ -202,7 +202,7 @@ export class MaterialContainer extends React.Component<MaterialContainerProps, {
id={MATCONTENTID} id={MATCONTENTID}
style={{ style={{
width: 1200, width: 1200,
height: 820 height: 840
}} }}
> >
</div> </div>

@ -5,7 +5,7 @@ import ResizeObserver from 'resize-observer-polyfill';
import { PhysicalMaterialRecord } from '../../DatabaseServices/PhysicalMaterialRecord'; import { PhysicalMaterialRecord } from '../../DatabaseServices/PhysicalMaterialRecord';
import { MaterialEditor } from '../../Editor/MaterialEditor'; import { MaterialEditor } from '../../Editor/MaterialEditor';
import { MATCONTENTID } from '../Components/MaterialContainer'; import { MATCONTENTID } from '../Components/MaterialContainer';
import { Select } from '../MaterialEditor/MaterialCommon'; import { Objects } from '../MaterialEditor/MaterialCommon';
import { PropertiesPane } from '../MaterialEditor/PropertiesPane'; import { PropertiesPane } from '../MaterialEditor/PropertiesPane';
import { MaterialStore } from '../Store/MaterialStore'; import { MaterialStore } from '../Store/MaterialStore';
@ -24,6 +24,7 @@ export class MaterialEditorLayout
private initViewer() private initViewer()
{ {
let canvas = document.getElementById("MaterialCanvas"); let canvas = document.getElementById("MaterialCanvas");
canvas.style.position = "relative";
this.editor = MaterialEditor.GetInstance() as MaterialEditor; this.editor = MaterialEditor.GetInstance() as MaterialEditor;
this.editor.SetViewer(canvas); this.editor.SetViewer(canvas);
this.editor.setMaterial(this.material); this.editor.setMaterial(this.material);
@ -54,6 +55,10 @@ export class MaterialEditorLayout
this.htmlEl.appendChild(canvasContainer); this.htmlEl.appendChild(canvasContainer);
let object = document.createElement("div");
object.id = "object";
canvasContainer.appendChild(object);
let rightContainer = document.createElement("div"); let rightContainer = document.createElement("div");
this.htmlEl.appendChild(rightContainer); this.htmlEl.appendChild(rightContainer);
@ -68,24 +73,28 @@ export class MaterialEditorLayout
rightContainer.appendChild(obejctContainer); rightContainer.appendChild(obejctContainer);
} }
getSceneConfigEl()
{
return document.getElementById("SceneConfig");
}
getAttributePanelEl() getAttributePanelEl()
{ {
return document.getElementById("MaterialAttribute"); return document.getElementById("MaterialAttribute");
} }
getobject()
{
return document.getElementById("object");
}
renderSceneConfig() renderSceneConfig()
{ {
ReactDOM.render( ReactDOM.render(
<Select prompt="物体" <Objects
value={this.editor.m_CurGeometryName} value={this.editor.CurGeometryName}
selects={[...this.editor.Geometrys.keys()].map(k => selects={[...this.editor.Geometrys.keys()].map(k =>
{ {
return { label: k, value: k }; return { lable: k, value: k };
})} /> })}
, this.getSceneConfigEl()); lable={["球", "环", "立", "结", "椎"]}
/>
, this.getobject()
);
} }
renderAttributePanel() renderAttributePanel()
@ -101,7 +110,7 @@ export class MaterialEditorLayout
dispose() dispose()
{ {
ReactDOM.unmountComponentAtNode(this.getSceneConfigEl()); ReactDOM.unmountComponentAtNode(this.getobject());
ReactDOM.unmountComponentAtNode(this.getAttributePanelEl()); ReactDOM.unmountComponentAtNode(this.getAttributePanelEl());
(MaterialStore.GetInstance() as MaterialStore).Destroy(); (MaterialStore.GetInstance() as MaterialStore).Destroy();
this.destroyFuncs.forEach(f => f()); this.destroyFuncs.forEach(f => f());

@ -1,9 +1,13 @@
import { autorun, IObservableValue, observable } from "mobx"; import { Icon, InputGroup, Popover, PopoverPosition, Tooltip } from "@blueprintjs/core";
import { action, autorun, IObservableValue, observable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { SketchPicker } from 'react-color'; import { SketchPicker } from 'react-color';
import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping } from "three"; import { ClampToEdgeWrapping, Color, MirroredRepeatWrapping, RepeatWrapping } from "three";
import { safeEval } from "../../Common/eval"; import { safeEval } from "../../Common/eval";
import { DefaultParamMap, MaterialType, SetMaterialParams } from "../../DatabaseServices/IMaterialDefaultParam";
import { PhysicalMaterialRecord } from "../../DatabaseServices/PhysicalMaterialRecord";
import { MaterialStore } from "../Store/MaterialStore";
const LabelStyle: React.CSSProperties = { display: "flex", margin: 3 }; const LabelStyle: React.CSSProperties = { display: "flex", margin: 3 };
const PromptStyle: React.CSSProperties = { alignSelf: "center", width: 60 }; const PromptStyle: React.CSSProperties = { alignSelf: "center", width: 60 };
@ -13,6 +17,21 @@ const InputStyle: React.CSSProperties = {
width: "100%", width: "100%",
overflow: 'hidden' overflow: 'hidden'
}; };
const TypeSelectStyle: React.CSSProperties = {
position: "absolute",
right: 0,
bottom: 8,
display: "flex"
};
const TypeSelectButton: React.CSSProperties = {
width: 30,
height: 30,
backgroundColor: "white",
borderRadius: "8px",
lineHeight: "25px",
textAlign: "center",
overflow: "hidden"
};
export class Input extends React.Component< export class Input extends React.Component<
{ {
@ -106,27 +125,73 @@ export class ColorSelect extends React.Component<{ color: IObservableValue<strin
render() render()
{ {
return ( return (
<> <Popover
<button position={PopoverPosition.TOP}
style={{ width: 100, height: 25, background: this.props.color.get() }} minimal
onClick={e => content={
{
this.bSelectColor = true;
}} />
{this.bSelectColor &&
<div style={PopoverStyle}>
<div
style={CoverStyle}
onClick={this.handleClose} />
<SketchPicker <SketchPicker
color={this.props.color.get()} color={this.props.color.get()}
onChange={color => onChange={(color) =>
{ {
this.props.color.set(color.hex); this.props.color.set(color.hex);
}} }}
/> />
</div>} }
</> >
<InputGroup
style={{ height: 24, width: 90, marginTop: 2 }}
value={this.props.color.get()}
small
leftElement={
<Icon
icon='stop'
iconSize={20}
color={this.props.color.get()}
/>
}
/>
</Popover>
);
}
}
@observer
export class LightDarkColor extends React.Component<{ color: IObservableValue<Color>; }, {}>{
@observable bSelectColor = false;
handleClose = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) =>
{
this.bSelectColor = false;
e.preventDefault();
e.stopPropagation();
};
render()
{
return (
<Popover
position={PopoverPosition.TOP}
minimal
content={
<SketchPicker
color={this.props.color.get()}
onChange={(color) =>
{
this.props.color.set(new Color(color.hex));
}}
/>
}
>
<InputGroup
style={{ height: 24, width: 90, marginTop: 2 }}
value={`#${this.props.color.get().getHexString()}`}
small
leftElement={
<Icon
icon='stop'
iconSize={20}
color={`#${this.props.color.get().getHexString()}`}
/>
}
/>
</Popover>
); );
} }
} }
@ -303,6 +368,120 @@ export class Select extends React.Component<{ value: IObservableValue<any>, prom
} }
} }
export class Objects extends React.Component<{ value: IObservableValue<any>, selects: { lable: string, value: any; }[], lable: string[]; }, {}>
{
render()
{
return (
<div style={{ ...TypeSelectStyle }} >
{this.props.selects.map((op, i) =>
<Tooltip content={op.lable}>
<button type="button" key={i}
style={{ ...TypeSelectButton }}
onClick={() => { this.props.value.set(op.value); }}
>
{this.props.lable[i]}
</button>
</Tooltip>
)}
</div>
);
}
}
export class TypeSelect extends React.Component<{ value: IObservableValue<MaterialType>, prompt: string, selects: MaterialType[], store: MaterialStore; }, {}>{
selectEl: HTMLSelectElement;
dispose: Function;
componentDidMount()
{
this.dispose = autorun(() =>
{
let value = this.props.value.get();
if (this.selectEl)
this.selectEl.value = value;
});
}
componentWillUnmount()
{
if (this.dispose)
this.dispose();
}
setMaterial = action((material: PhysicalMaterialRecord) =>
{
// if (material.type === "自定义")
// return;
let Material = material;
let store = this.props.store;
store.matalness.set(Material.matalness);
store.roughness.set(Material.roughness);
store.specular.set(Material.specular);
store.bumpScale.set(Material.bumpScale);
store.baseColorLuminance.set(Material.baseColorLuminance);
store.baseColorSaturability.set(Material.baseColorSaturability);
store.baseColorLightColor.set(Material.baseColorLightColor);
store.baseColorDarkColor.set(Material.baseColorDarkColor);
store.useTransparent.set(material.transparent);
if (material.type === "布料" || material.type === "皮革")
{
store.fresnelPO.set(Material.fresnelPO);
store.fresnelST.set(Material.fresnelST);
store.fresnelLuminance.set(Material.fresnelLuminance);
store.fresnelLightColor.set(Material.fresnelLightColor);
store.fresnelDarkColor.set(Material.fresnelDarkColor);
}
if (material.type === "玻璃")
{
store.transparent.set(1 - Material.opacity);
store.opacityContrast.set(Material.opacityContrast);
store.opacityBorder.set(Material.opacityBorder);
store.opacityMaximum.set(Material.opacityMaximum);
store.opacityMinimum.set(Material.opacityMinimum);
}
});
render()
{
return (
<label style={LabelStyle}>
<span style={{ ...PromptStyle, ...{ width: 50 } }}>
{this.props.prompt}
</span>
<select
style={{ flexGrow: 1 }}
defaultValue={this.props.value.get()}
ref={e => this.selectEl = e}
onChange={action(e =>
{
let PhysicalMaterial = new PhysicalMaterialRecord();
for (let op of this.props.selects)
{
if (op === e.target.value)
{
this.props.value.set(op);
SetMaterialParams(PhysicalMaterial, DefaultParamMap[op]);
PhysicalMaterial.type = op;
if (op === "玻璃")
PhysicalMaterial.transparent = true;
else
PhysicalMaterial.transparent = false;
this.setMaterial(PhysicalMaterial);
return;
}
}
})}
>
{
this.props.selects.map((op, i) => <option key={i} value={op}>{op}</option>)
}
</select>
</label >
);
}
}
export const WrapSelects = [ export const WrapSelects = [
{ label: "镜像平铺", value: MirroredRepeatWrapping }, { label: "镜像平铺", value: MirroredRepeatWrapping },

@ -1,37 +1,113 @@
import { Divider, Checkbox } from "@blueprintjs/core"; import { Button, Checkbox, Collapse, Divider, Radio, RadioGroup } from "@blueprintjs/core";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { DefaultParamMap } from "../../DatabaseServices/IMaterialDefaultParam";
import { MaterialStore } from "../Store/MaterialStore"; import { MaterialStore } from "../Store/MaterialStore";
import { Check, ColorSelect, Lable, LableInput, Slider, Input } from "./MaterialCommon"; import { Check, ColorSelect, Lable, LableInput, LightDarkColor, Slider, TypeSelect } from "./MaterialCommon";
import { MaterialLinkShopId } from "./MaterialLinkShop"; import { MaterialLinkShopId } from "./MaterialLinkShop";
import { Texture } from "./TextureItem"; import { Texture } from "./TextureItem";
import { TextureList } from "./TextureList"; import { TextureList } from "./TextureList";
const ButtonStyle: React.CSSProperties = {
fontSize: 14, outline: "none", justifyContent: "left"
};
//材质的属性面板 //材质的属性面板
@inject('store') @inject('store')
@observer @observer
export class PropertiesPane extends React.Component<{ store?: MaterialStore; }, {}>{ export class PropertiesPane extends React.Component<{ store?: MaterialStore; }, {}>{
public state = {
materialExtension: true,
colorExtension: false,
texturaExtension: true,
fresnelExtension: true,
OpacityExtension: true,
};
render() render()
{ {
let store = this.props.store; let store = this.props.store;
let ParamMap = [];
for (const key in DefaultParamMap)
{
ParamMap.push(key);
}
return ( return (
<> <>
<div style={{ <div style={{
fontSize: "14px", fontSize: "14px",
margin: "5px" marginLeft: "5px",
width: 395,
height: 840,
overflow: "scroll"
}}> }}>
<LableInput prompt="名称" value={store.name} /> <LableInput prompt="名称" value={store.name} />
<Divider />
<Button
minimal
text="材质"
icon={this.state.materialExtension ? "caret-down" : "caret-right"}
style={ButtonStyle}
onClick={() => { this.setState({ materialExtension: !this.state.materialExtension }); }}
/>
{
this.state.materialExtension &&
<MaterialLinkShopId /> <MaterialLinkShopId />
<Lable prompt="颜色" style={{ width: "50%" }}> }
<Divider />
<TypeSelect prompt="类型"
value={store.materialType}
selects={[...ParamMap]}
store={store} />
<Divider />
<div style={{ display: "flex" }}>
<Button
minimal
text="颜色"
icon={this.state.colorExtension ? "caret-down" : "caret-right"}
style={ButtonStyle}
onClick={() => { this.setState({ colorExtension: !this.state.colorExtension }); }}
/>
<ColorSelect color={store.color} /> <ColorSelect color={store.color} />
</div>
{
this.state.colorExtension &&
<div>
<Slider prompt="亮度" value={store.baseColorLuminance} min={-1} max={1} step={0.1} />
{/* <Lable prompt="" style={{ width: "50%" }}>
<LightDarkColor color={store.baseColorLightColor} />
</Lable> */}
<Lable prompt="暗部颜色" style={{ width: "50%" }}>
<LightDarkColor color={store.baseColorDarkColor} />
</Lable> </Lable>
<Check prompt="透明" value={store.useTransparent} /> <Slider prompt="饱和度" value={store.baseColorSaturability} min={0} max={1} step={0.1} />
<Slider prompt="透明度" value={store.transparent} min={0} max={1} step={0.1} /> </div>
<Slider prompt="凹凸度" value={store.bumpScale} min={0} max={1} step={0.1} /> }
<Divider />
<Button
minimal
text="质感"
icon={this.state.texturaExtension ? "caret-down" : "caret-right"}
style={ButtonStyle}
onClick={() => { this.setState({ texturaExtension: !this.state.texturaExtension }); }}
/>
<Collapse isOpen={this.state.texturaExtension} keepChildrenMounted={true}>
<Slider prompt="法线强度" value={store.bumpScale} min={0} max={1} step={0.1} />
<Slider prompt="粗糙度" value={store.roughness} min={0} max={1} step={0.1} /> <Slider prompt="粗糙度" value={store.roughness} min={0} max={1} step={0.1} />
<Slider prompt="金属度" value={store.matalness} min={0} max={1} step={0.1} /> <Slider prompt="金属度" value={store.matalness} min={0} max={1} step={0.1} />
<Checkbox label="铺满到板件" checked={store.isFull} onChange={() => store.isFull = !store.isFull} /> <Slider prompt="高光" value={store.specular} min={0} max={1} step={0.1} />
</Collapse>
<Divider /> <Divider />
<div style={{ display: "flex" }}>
<Checkbox style={{ paddingRight: 50 }} label="铺满到板件" checked={store.isFull} onChange={() => store.isFull = !store.isFull} />
<RadioGroup
inline
selectedValue={this.props.store.coordinate}
onChange={(e) => { this.props.store.coordinate = e.currentTarget.value; }}>
<Radio label="世界坐标" value="0" />
<Radio label="UV坐标" value="1" />
</RadioGroup>
</div>
<div style={{ <div style={{
overflowY: "auto", overflowY: "auto",
overflowX: "hidden", overflowX: "hidden",
@ -39,18 +115,70 @@ export class PropertiesPane extends React.Component<{ store?: MaterialStore; },
<Texture <Texture
prompt="纹理贴图" prompt="纹理贴图"
textureStore={store.textureMaping} textureStore={store.textureMaping}
isopen={true}
/> />
<Divider /> <Divider />
<Texture {/* <Texture
prompt="凹凸贴图" prompt="凹凸贴图"
textureStore={store.bumpMaping} textureStore={store.bumpMaping}
isopen={false}
/> />
<Divider /> <Divider />
<Texture <Texture
prompt="粗糙贴图" prompt="粗糙贴图"
textureStore={store.roughnessMaping} textureStore={store.roughnessMaping}
isopen={false}
/> */}
</div>
{
(store.materialType.get() === "皮革" || store.materialType.get() === "布料" /*|| store.materialType.get() === "自定义"*/) &&
<div>
<Button
minimal
text="菲涅尔"
icon={this.state.fresnelExtension ? "caret-down" : "caret-right"}
style={ButtonStyle}
onClick={() => { this.setState({ fresnelExtension: !this.state.fresnelExtension }); }}
/> />
{
this.state.fresnelExtension &&
<>
<Slider prompt="对比度" value={store.fresnelPO} min={-1} max={10} step={0.1} />
<Slider prompt="强度" value={store.fresnelST} min={0} max={20} step={0.1} />
<Slider prompt="亮度" value={store.fresnelLuminance} min={0} max={20} step={0.1} />
{/* <Lable prompt="" style={{ width: "50%" }}>
<LightDarkColor color={store.fresnelLightColor} />
</Lable> */}
<Lable prompt="暗部颜色" style={{ width: "50%" }}>
<LightDarkColor color={store.fresnelDarkColor} />
</Lable>
</>
}
</div> </div>
}
{
(store.materialType.get() === "玻璃" /* || store.materialType.get() === "自定义"*/) &&
<div>
<Button
minimal
text="不透明度"
icon={this.state.OpacityExtension ? "caret-down" : "caret-right"}
style={ButtonStyle}
onClick={() => { this.setState({ OpacityExtension: !this.state.OpacityExtension }); }}
/>
{
this.state.OpacityExtension &&
<>
<Check prompt="透明" value={store.useTransparent} />
<Slider prompt="透明度" value={store.transparent} min={0} max={1} step={0.1} />
{/* <Slider prompt="对比" value={store.opacityContrast} min={0} max={1} step={0.1} /> */}
<Slider prompt="边界" value={store.opacityBorder} min={0} max={1} step={0.1} />
<Slider prompt="最大值" value={store.opacityMinimum} min={0} max={1} step={0.1} />
<Slider prompt="最小值" value={store.opacityMaximum} min={0} max={1} step={0.1} />
</>
}
</div>
}
</div > </div >
<TextureList /> <TextureList />
</> </>

@ -1,4 +1,4 @@
import { Button, Intent, Label } from "@blueprintjs/core"; import { Button, Collapse, Icon, Intent, Label } from "@blueprintjs/core";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping } from "three"; import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping } from "three";
@ -6,16 +6,22 @@ import { TextureTableRecord } from "../../DatabaseServices/Texture";
import { MaterialStore } from "../Store/MaterialStore"; import { MaterialStore } from "../Store/MaterialStore";
import { TextureStore } from "../Store/TextureStore"; import { TextureStore } from "../Store/TextureStore";
import { Check, Input, Select } from "./MaterialCommon"; import { Check, Input, Select } from "./MaterialCommon";
import { CURRENT_HOST } from "../../Common/HostUrl";
const PromptStyle: React.CSSProperties = { alignSelf: "center", width: 60 }; const PromptStyle: React.CSSProperties = { alignSelf: "center", width: 60 };
const SpanStyle: React.CSSProperties = { alignSelf: "center", width: 20 }; const SpanStyle: React.CSSProperties = { alignSelf: "center", textAlign: "center", width: 20 };
const InputStyle: React.CSSProperties = { const InputStyle: React.CSSProperties = {
flexBasis: "0%", flexBasis: "0%",
flexGrow: 1, flexGrow: 1,
width: "100%", width: "100%",
overflow: 'hidden' overflow: 'hidden'
}; };
const ImageStyle: React.CSSProperties = {
width: "150%",
height: "150%",
position: "absolute",
left: "-25%",
top: " -25%"
};
export const WrapSelects = [ export const WrapSelects = [
{ label: "镜像平铺", value: MirroredRepeatWrapping }, { label: "镜像平铺", value: MirroredRepeatWrapping },
{ label: "平铺", value: RepeatWrapping }, { label: "平铺", value: RepeatWrapping },
@ -26,11 +32,20 @@ interface ITextureProps
prompt: string; prompt: string;
textureStore: TextureStore; textureStore: TextureStore;
store?: MaterialStore; store?: MaterialStore;
isopen?: boolean;
} }
@inject('store') @inject('store')
@observer @observer
export class Texture extends React.Component<ITextureProps, {}>{ export class Texture extends React.Component<ITextureProps, { isopen: boolean; }, {}>{
constructor(props)
{
super(props);
this.state = {
isopen: props.isopen
};
}
handleSelectImg = () => handleSelectImg = () =>
{ {
const { store, textureStore } = this.props; const { store, textureStore } = this.props;
@ -54,7 +69,32 @@ export class Texture extends React.Component<ITextureProps, {}>{
<> <>
<div> <div>
<div className="flex-between"> <div className="flex-between">
<span style={{ fontSize: 16 }}>{this.props.prompt}:</span> <Button
minimal
text={`${this.props.prompt}:`}
icon={this.state.isopen ? "caret-down" : "caret-right"}
style={{ fontSize: 14, width: "60%", outline: "none", justifyContent: "left" }}
onClick={() => { this.setState({ isopen: !this.state.isopen }); }}
/>
{
!this.state.isopen &&
<div
style={{
position: "relative",
userSelect: "none",
overflow: "hidden",
width: 30,
height: 30
}}>
<img
src={textureStore.imgUrl ? textureStore.imgUrl : undefined}
style={{
...ImageStyle,
transform: `rotateZ(${textureStore.rotation}deg)`
}}
/>
</div>
}
<Button <Button
intent={Intent.PRIMARY} intent={Intent.PRIMARY}
style={{ style={{
@ -62,6 +102,7 @@ export class Texture extends React.Component<ITextureProps, {}>{
height: 20, height: 20,
lineHeight: "20px", lineHeight: "20px",
padding: "0 10px", padding: "0 10px",
marginTop: 5,
}} }}
text="复用纹理" text="复用纹理"
onClick={() => onClick={() =>
@ -71,21 +112,29 @@ export class Texture extends React.Component<ITextureProps, {}>{
}} }}
/> />
</div> </div>
<Collapse isOpen={this.state.isopen} keepChildrenMounted={true}>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<div className="img-select-hint" onDoubleClick={this.handleSelectImg}> <div className="img-select-hint" onDoubleClick={this.handleSelectImg} style={{ width: 140, height: 140 }}>
{
!textureStore.use.get() &&
<div
style={{ color: "#eee", position: "absolute", top: 0, right: 0, zIndex: 2 }}>
<Icon icon="disable" />
使
</div>
}
<img <img
src={textureStore.textureImg ? CURRENT_HOST + "/" + textureStore.textureImg : undefined} src={textureStore.imgUrl ? textureStore.imgUrl : undefined}
style={{ style={{
width: 140, ...ImageStyle,
height: 140,
transform: `rotateZ(${textureStore.rotation}deg)` transform: `rotateZ(${textureStore.rotation}deg)`
}} }}
/> />
</div> </div>
<div style={{ flexBasis: 0, flexGrow: 1 }}> <div style={{ flexBasis: 0, flexGrow: 1 }}>
<Check prompt="使用" value={textureStore.use} promptStyle={{ width: 50 }} /> <Check prompt="使用" value={textureStore.use} promptStyle={{ width: 50 }} />
<Select prompt="包装U" value={textureStore.warpS} selects={WrapSelects} /> <Select prompt="平铺U" value={textureStore.warpS} selects={WrapSelects} />
<Select prompt="包装V" value={textureStore.wrapT} selects={WrapSelects} /> <Select prompt="平铺V" value={textureStore.wrapT} selects={WrapSelects} />
<Label style={{ <Label style={{
display: "flex", display: "flex",
margin: 3, margin: 3,
@ -97,6 +146,19 @@ export class Texture extends React.Component<ITextureProps, {}>{
value={textureStore.rotation} value={textureStore.rotation}
/> />
</Label> </Label>
<div style={{ margin: 3, display: "flex" }}>
<span style={{ ...PromptStyle, width: 50, whiteSpace: "nowrap" }}></span>
<span style={SpanStyle}>X</span>
<Input
value={textureStore.moveX}
disabled={textureStore.warpS.get() === ClampToEdgeWrapping}
/>
<span style={SpanStyle}>Y</span>
<Input
value={textureStore.moveY}
disabled={textureStore.wrapT.get() === ClampToEdgeWrapping}
/>
</div>
<div style={{ margin: 3, display: "flex" }}> <div style={{ margin: 3, display: "flex" }}>
<span style={{ ...PromptStyle, width: 50, whiteSpace: "nowrap" }}>(m)</span> <span style={{ ...PromptStyle, width: 50, whiteSpace: "nowrap" }}>(m)</span>
<span style={SpanStyle}></span> <span style={SpanStyle}></span>
@ -110,10 +172,12 @@ export class Texture extends React.Component<ITextureProps, {}>{
disabled={textureStore.wrapT.get() === ClampToEdgeWrapping} disabled={textureStore.wrapT.get() === ClampToEdgeWrapping}
/> />
</div> </div>
</div> </div>
</div> </div>
</Collapse>
</div> </div>
</> </>
); );
} }
} };

@ -1,10 +1,12 @@
import { Intent } from "@blueprintjs/core"; import { Intent } from "@blueprintjs/core";
import { action, autorun, observable, toJS } from "mobx"; import { action, autorun, observable, toJS } from "mobx";
import { Color } from "three";
import { end } from "xaop"; import { end } from "xaop";
import { ConverMaterialData } from "../../Add-on/ExportData"; import { ConverMaterialData } from "../../Add-on/ExportData";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { Singleton } from "../../Common/Singleton"; import { Singleton } from "../../Common/Singleton";
import { UpdateDraw } from "../../Common/Status"; import { UpdateDraw } from "../../Common/Status";
import { MaterialType } from "../../DatabaseServices/IMaterialDefaultParam";
import { IGoodProps, PhysicalMaterialRecord } from "../../DatabaseServices/PhysicalMaterialRecord"; import { IGoodProps, PhysicalMaterialRecord } from "../../DatabaseServices/PhysicalMaterialRecord";
import { TextureTableRecord } from "../../DatabaseServices/Texture"; import { TextureTableRecord } from "../../DatabaseServices/Texture";
import { MaterialEditor } from "../../Editor/MaterialEditor"; import { MaterialEditor } from "../../Editor/MaterialEditor";
@ -23,6 +25,13 @@ export class MaterialStore extends Singleton
matalness = observable.box(0.2); matalness = observable.box(0.2);
// 基础色
baseColorLuminance = observable.box(0);
baseColorLightColor = observable.box(new Color(0.5, 0.5, 0.5));
baseColorDarkColor = observable.box(new Color(0, 0, 0));
baseColorSaturability = observable.box(1);
materialType = observable.box<MaterialType>("木纹");
useTransparent = observable.box(false); useTransparent = observable.box(false);
transparent = observable.box(0); transparent = observable.box(0);
@ -30,8 +39,24 @@ export class MaterialStore extends Singleton
bumpScale = observable.box(0); bumpScale = observable.box(0);
bumpMaping = new TextureStore(); bumpMaping = new TextureStore();
roughness = observable.box(0); roughness = observable.box(0);
specular = observable.box(0);
roughnessMaping = new TextureStore(); roughnessMaping = new TextureStore();
// 菲涅尔
fresnelPO = observable.box(1);
fresnelST = observable.box(1);
fresnelLuminance = observable.box(1);
fresnelLightColor = observable.box(new Color(1, 1, 1));
fresnelDarkColor = observable.box(new Color(1, 1, 1));
// 不透明度
opacityContrast = observable.box(1);
opacityBorder = observable.box(1);
opacityMaximum = observable.box(1);
opacityMinimum = observable.box(0.3);
protected reactionDestroy; protected reactionDestroy;
@observable coordinate = "0";
@observable isOpenTexture = false; @observable isOpenTexture = false;
@observable isOpenImgList = false; @observable isOpenImgList = false;
@observable goodsInfo: IGoodProps = { @observable goodsInfo: IGoodProps = {
@ -75,10 +100,25 @@ export class MaterialStore extends Singleton
{ {
this.name.get(); this.name.get();
this.color.get(); this.color.get();
this.baseColorLuminance.get();
this.baseColorLightColor.get();
this.baseColorDarkColor.get();
this.baseColorSaturability.get();
this.materialType.get();
this.useTransparent.get(); this.useTransparent.get();
this.transparent.get(); this.transparent.get();
this.bumpScale.get(); this.bumpScale.get();
this.roughness.get(); this.roughness.get();
this.specular.get();
this.fresnelPO.get();
this.fresnelST.get();
this.fresnelLuminance.get();
this.fresnelLightColor.get();
this.fresnelDarkColor.get();
this.opacityContrast.get();
this.opacityBorder.get();
this.opacityMaximum.get();
this.opacityMinimum.get();
if (this.Material) if (this.Material)
this.UpdateMaterial(); this.UpdateMaterial();
}); });
@ -136,13 +176,6 @@ export class MaterialStore extends Singleton
this.Material.map = this.textureMaping.textureId; this.Material.map = this.textureMaping.textureId;
this.Material.bumpMap = this.bumpMaping.textureId; this.Material.bumpMap = this.bumpMaping.textureId;
this.Material.roughnessMap = this.roughnessMaping.textureId; this.Material.roughnessMap = this.roughnessMaping.textureId;
//同步到效果图
if (userConfig.synchronousEnable)
{
let d: IncrementData = { Add: { Entitys: [], Materials: [] }, Change: { Entitys: [], Materials: [ConverMaterialData(this.Material)] }, Delete: { Entitys: [], Materials: [] } };
app.WebSocket.Send(JSON.stringify(d));
}
} }
UpdateMaterial = async () => UpdateMaterial = async () =>
{ {
@ -150,11 +183,26 @@ export class MaterialStore extends Singleton
{ {
this.Material.Name = this.name.get(); this.Material.Name = this.name.get();
this.Material.color = this.color.get(); this.Material.color = this.color.get();
this.Material.baseColorLuminance = this.baseColorLuminance.get();
this.Material.baseColorLightColor = this.baseColorLightColor.get();
this.Material.baseColorDarkColor = this.baseColorDarkColor.get();
this.Material.baseColorSaturability = this.baseColorSaturability.get();
this.Material.type = this.materialType.get() as MaterialType;
this.Material.transparent = this.useTransparent.get(); this.Material.transparent = this.useTransparent.get();
this.Material.matalness = this.matalness.get(); this.Material.matalness = this.matalness.get();
this.Material.opacity = 1 - this.transparent.get(); this.Material.opacity = 1 - this.transparent.get();
this.Material.bumpScale = this.bumpScale.get(); this.Material.bumpScale = this.bumpScale.get();
this.Material.roughness = this.roughness.get(); this.Material.roughness = this.roughness.get();
this.Material.specular = this.specular.get();
this.Material.fresnelPO = this.fresnelPO.get();
this.Material.fresnelST = this.fresnelST.get();
this.Material.fresnelLuminance = this.fresnelLuminance.get();
this.Material.fresnelLightColor = this.fresnelLightColor.get();
this.Material.fresnelDarkColor = this.fresnelDarkColor.get();
this.Material.opacityContrast = this.opacityContrast.get();
this.Material.opacityBorder = this.opacityBorder.get();
this.Material.opacityMaximum = this.opacityMaximum.get();
this.Material.opacityMinimum = this.opacityMinimum.get();
this.Material.useMap = this.textureMaping.use.get(); this.Material.useMap = this.textureMaping.use.get();
this.Material.useBumpMap = this.bumpMaping.use.get(); this.Material.useBumpMap = this.bumpMaping.use.get();
this.Material.useRoughnessMap = this.roughnessMaping.use.get(); this.Material.useRoughnessMap = this.roughnessMaping.use.get();
@ -168,6 +216,13 @@ export class MaterialStore extends Singleton
await this.Material.Update(); await this.Material.Update();
await (MaterialEditor.GetInstance() as MaterialEditor).Update(); await (MaterialEditor.GetInstance() as MaterialEditor).Update();
//同步到效果图 (3个贴图的Store都会触发这个 一共触发了4次)
if (userConfig.synchronousEnable)
{
let d: IncrementData = { Add: { Entitys: [], Materials: [] }, Change: { Entitys: [], Materials: [ConverMaterialData(this.Material)] }, Delete: { Entitys: [], Materials: [] } };
app.WebSocket.Send(JSON.stringify(d));
}
} }
}; };
@action @action
@ -177,11 +232,26 @@ export class MaterialStore extends Singleton
{ {
this.name.set(this.Material.Name); this.name.set(this.Material.Name);
this.color.set(this.Material.color); this.color.set(this.Material.color);
this.baseColorLuminance.set(this.Material.baseColorLuminance);
this.baseColorLightColor.set(this.Material.baseColorLightColor);
this.baseColorDarkColor.set(this.Material.baseColorDarkColor);
this.baseColorSaturability.set(this.Material.baseColorSaturability);
this.materialType.set(this.Material.type);
this.useTransparent.set(this.Material.transparent); this.useTransparent.set(this.Material.transparent);
this.matalness.set(this.Material.matalness); this.matalness.set(this.Material.matalness);
this.transparent.set(parseFloat((1 - this.Material.opacity).toFixed(2))); this.transparent.set(parseFloat((1 - this.Material.opacity).toFixed(2)));
this.bumpScale.set(this.Material.bumpScale); this.bumpScale.set(this.Material.bumpScale);
this.roughness.set(this.Material.roughness); this.roughness.set(this.Material.roughness);
this.specular.set(this.Material.specular);
this.fresnelPO.set(this.Material.fresnelPO);
this.fresnelST.set(this.Material.fresnelST);
this.fresnelLuminance.set(this.Material.fresnelLuminance);
this.fresnelLightColor.set(this.Material.fresnelLightColor);
this.fresnelDarkColor.set(this.Material.fresnelDarkColor);
this.opacityContrast.set(this.Material.opacityContrast);
this.opacityBorder.set(this.Material.opacityBorder);
this.opacityMaximum.set(this.Material.opacityMaximum);
this.opacityMinimum.set(this.Material.opacityMinimum);
this.isFull = this.Material.IsFull; this.isFull = this.Material.IsFull;
Object.assign(this.goodsInfo, this.Material.GoodsInfo); Object.assign(this.goodsInfo, this.Material.GoodsInfo);

@ -1,4 +1,4 @@
import { autorun, observable } from "mobx"; import { action, autorun, observable } from "mobx";
import { ClampToEdgeWrapping, MathUtils, MirroredRepeatWrapping } from "three"; import { ClampToEdgeWrapping, MathUtils, MirroredRepeatWrapping } from "three";
import { FixedNotZero } from "../../Common/Utils"; import { FixedNotZero } from "../../Common/Utils";
import { ObjectId } from "../../DatabaseServices/ObjectId"; import { ObjectId } from "../../DatabaseServices/ObjectId";
@ -12,7 +12,10 @@ export class TextureStore
/**由于老板觉得这个不好算 已经改成贴图的尺寸了*/ /**由于老板觉得这个不好算 已经改成贴图的尺寸了*/
repeatX = observable.box(1); repeatX = observable.box(1);
repeatY = observable.box(1); repeatY = observable.box(1);
moveX = observable.box(0);
moveY = observable.box(0);
@observable textureImg = ""; @observable textureImg = "";
@observable imgUrl = "";
rotation = observable.box(0); //角度 rotation = observable.box(0); //角度
textureId: ObjectId; textureId: ObjectId;
autorunFun: Function; autorunFun: Function;
@ -28,6 +31,8 @@ export class TextureStore
this.warpS.get(); this.warpS.get();
this.repeatX.get(); this.repeatX.get();
this.repeatY.get(); this.repeatY.get();
this.moveX.get();
this.moveY.get();
this.rotation.get(); this.rotation.get();
this.UpdateEvent(); this.UpdateEvent();
}); });
@ -50,13 +55,18 @@ export class TextureStore
this.wrapT.set(MirroredRepeatWrapping); this.wrapT.set(MirroredRepeatWrapping);
this.repeatX.set(1); this.repeatX.set(1);
this.repeatY.set(1); this.repeatY.set(1);
this.moveX.set(0);
this.moveY.set(0);
this.rotation.set(0); this.rotation.set(0);
this.textureImg = ""; this.textureImg = "";
this.imgUrl = "";
this.textureId = null; this.textureId = null;
} }
} }
private updateing = false; private updateing = false;
@action
UpdateStore(textureId: ObjectId | TextureTableRecord) UpdateStore(textureId: ObjectId | TextureTableRecord)
{ {
if (!textureId) return; if (!textureId) return;
@ -78,11 +88,14 @@ export class TextureStore
this.repeatX.set(1 / texture.repeatX); this.repeatX.set(1 / texture.repeatX);
this.repeatY.set(1 / texture.repeatY); this.repeatY.set(1 / texture.repeatY);
this.moveX.set(texture.moveX);
this.moveY.set(texture.moveY);
this.warpS.set(texture.WrapS); this.warpS.set(texture.WrapS);
this.wrapT.set(texture.WrapT); this.wrapT.set(texture.WrapT);
let deg = MathUtils.radToDeg(texture.rotation); let deg = MathUtils.radToDeg(texture.rotation);
this.rotation.set(parseFloat(FixedNotZero(deg, 1))); this.rotation.set(parseFloat(FixedNotZero(deg, 1)));
this.textureImg = texture.imageUrl; this.textureImg = texture.imageUrl;
this.imgUrl = texture.imgUrl;
this.updateing = false; this.updateing = false;
} }
@ -100,7 +113,10 @@ export class TextureStore
this.repeatX.set(1); this.repeatX.set(1);
} }
else else
{
texture.repeatX = 1 / this.repeatX.get(); texture.repeatX = 1 / this.repeatX.get();
texture.moveX = this.moveX.get();
}
if (texture.WrapT === ClampToEdgeWrapping) if (texture.WrapT === ClampToEdgeWrapping)
{ {
@ -108,7 +124,10 @@ export class TextureStore
this.repeatY.set(1); this.repeatY.set(1);
} }
else else
{
texture.repeatY = 1 / this.repeatY.get(); texture.repeatY = 1 / this.repeatY.get();
texture.moveY = this.moveY.get();
}
} }
} }

Loading…
Cancel
Save