feat(All):Initial
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { Command } from './Command';
|
||||
import { ObjectLoader } from '../loader/ObjectLoader';
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @constructor
|
||||
*/
|
||||
class AddObjectCommand extends Command {
|
||||
public object;
|
||||
|
||||
constructor( object ) {
|
||||
super();
|
||||
|
||||
this.type = 'AddObjectCommand';
|
||||
this.object = object;
|
||||
if ( object !== undefined ) {
|
||||
this.name = `Add object`;
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
App.addObject(this.object);
|
||||
App.select(this.object);
|
||||
}
|
||||
|
||||
undo() {
|
||||
App.removeObject( this.object );
|
||||
App.deselect();
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
output.object = this.object.toJSON();
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
this.object = App.getObjectByUuid( json.object.object.uuid );
|
||||
|
||||
if ( this.object === undefined ) {
|
||||
const loader = new ObjectLoader();
|
||||
this.object = loader.parse( json.object );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { AddObjectCommand };
|
||||
@@ -0,0 +1,64 @@
|
||||
import {Object3D} from "three";
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param script javascript object
|
||||
* @constructor
|
||||
*/
|
||||
class AddScriptCommand extends Command {
|
||||
private object: Object3D;
|
||||
private script: any;
|
||||
|
||||
constructor(object:Object3D, script) {
|
||||
super();
|
||||
|
||||
this.type = 'AddScriptCommand';
|
||||
this.name = 'Add script';
|
||||
|
||||
this.object = object;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
execute() {
|
||||
if (App.scripts[this.object.uuid] === undefined) {
|
||||
App.scripts[this.object.uuid] = [];
|
||||
}
|
||||
|
||||
App.scripts[this.object.uuid].push(this.script);
|
||||
|
||||
useDispatchSignal("scriptAdded", this.object,this.script);
|
||||
}
|
||||
|
||||
undo() {
|
||||
if (App.scripts[ this.object.uuid ] === undefined ) return;
|
||||
|
||||
const index = App.scripts[ this.object.uuid ].indexOf( this.script );
|
||||
|
||||
if (index !== -1) {
|
||||
App.scripts[ this.object.uuid ].splice( index, 1 );
|
||||
}
|
||||
|
||||
useDispatchSignal("scriptRemoved", this.object,this.script);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.script = this.script;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.script = json.script;
|
||||
this.object = App.getObjectByUuid(json.objectUuid) as Object3D;
|
||||
}
|
||||
}
|
||||
|
||||
export { AddScriptCommand };
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class Command {
|
||||
protected id:number;
|
||||
protected inMemory:boolean;
|
||||
public updatable:boolean;
|
||||
protected type:string;
|
||||
protected name:string;
|
||||
|
||||
constructor() {
|
||||
this.id = - 1;
|
||||
this.inMemory = false;
|
||||
this.updatable = false;
|
||||
this.type = '';
|
||||
this.name = '';
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output:any = {};
|
||||
output.type = this.type;
|
||||
output.id = this.id;
|
||||
output.name = this.name;
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
this.inMemory = true;
|
||||
this.type = json.type;
|
||||
this.id = json.id;
|
||||
this.name = json.name;
|
||||
}
|
||||
}
|
||||
|
||||
export { Command };
|
||||
@@ -0,0 +1,21 @@
|
||||
export { AddObjectCommand } from './AddObjectCommand';
|
||||
export { AddScriptCommand } from './AddScriptCommand';
|
||||
export { MoveObjectCommand } from './MoveObjectCommand';
|
||||
export { RemoveObjectCommand } from './RemoveObjectCommand';
|
||||
export { RemoveScriptCommand } from './RemoveScriptCommand';
|
||||
export { SetColorCommand } from './SetColorCommand';
|
||||
export { SetGeometryCommand } from './SetGeometryCommand';
|
||||
export { SetGeometryValueCommand } from './SetGeometryValueCommand';
|
||||
export { SetMaterialColorCommand } from './SetMaterialColorCommand';
|
||||
export { SetMaterialCommand } from './SetMaterialCommand';
|
||||
export { SetMaterialMapCommand } from './SetMaterialMapCommand';
|
||||
export { SetMaterialRangeCommand } from './SetMaterialRangeCommand';
|
||||
export { SetMaterialValueCommand } from './SetMaterialValueCommand';
|
||||
export { SetMaterialVectorCommand } from './SetMaterialVectorCommand';
|
||||
export { SetPositionCommand } from './SetPositionCommand';
|
||||
export { SetRotationCommand } from './SetRotationCommand';
|
||||
export { SetScaleCommand } from './SetScaleCommand';
|
||||
export { SetSceneCommand } from './SetSceneCommand';
|
||||
export { SetScriptValueCommand } from './SetScriptValueCommand';
|
||||
export { SetUuidCommand } from './SetUuidCommand';
|
||||
export { SetValueCommand } from './SetValueCommand';
|
||||
@@ -0,0 +1,127 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param newParent THREE.Object3D
|
||||
* @param newBefore THREE.Object3D
|
||||
* @constructor
|
||||
*/
|
||||
class MoveObjectCommand extends Command {
|
||||
public object;
|
||||
public oldParent;
|
||||
public oldIndex;
|
||||
public newParent;
|
||||
public newIndex;
|
||||
public newBefore;
|
||||
|
||||
constructor(object, newParent, newBefore ) {
|
||||
super();
|
||||
|
||||
this.type = 'MoveObjectCommand';
|
||||
this.name = 'Move object';
|
||||
|
||||
this.object = object;
|
||||
this.oldParent = ( object !== undefined ) ? object.parent : undefined;
|
||||
this.oldIndex = ( this.oldParent !== undefined ) ? this.oldParent.children.indexOf( this.object ) : undefined;
|
||||
this.newParent = newParent;
|
||||
|
||||
if ( newBefore !== undefined ) {
|
||||
this.newIndex = ( newParent !== undefined ) ? newParent.children.indexOf( newBefore ) : undefined;
|
||||
} else {
|
||||
this.newIndex = ( newParent !== undefined ) ? newParent.children.length : undefined;
|
||||
}
|
||||
|
||||
if ( this.oldParent === this.newParent && this.newIndex > this.oldIndex ) {
|
||||
this.newIndex--;
|
||||
}
|
||||
|
||||
this.newBefore = newBefore;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.oldParent.remove(this.object);
|
||||
|
||||
/** 放置到新组下时不改变世界坐标 **/
|
||||
// this.newParent.updateWorldMatrix(true, false);
|
||||
// const _m1 = new Matrix4();
|
||||
// _m1.copy(this.newParent.matrixWorld).invert();
|
||||
// if (this.object.parent !== null) {
|
||||
// this.object.parent.updateWorldMatrix( true, false );
|
||||
// _m1.multiply( this.object.parent.matrixWorld );
|
||||
// }
|
||||
// this.object.applyMatrix4( _m1 );
|
||||
/** 放置到新组下时不改变世界坐标 End **/
|
||||
|
||||
const children = this.newParent.children;
|
||||
children.splice( this.newIndex, 0, this.object );
|
||||
this.object.parent = this.newParent;
|
||||
|
||||
/** 放置到新组下时不改变世界坐标 **/
|
||||
// this.object.updateWorldMatrix( false, true );
|
||||
/** 放置到新组下时不改变世界坐标 End **/
|
||||
|
||||
this.object.dispatchEvent({ type: 'added' });
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.newParent.remove(this.object);
|
||||
|
||||
/** 撤销时不改变世界坐标 **/
|
||||
// this.oldParent.updateWorldMatrix(true, false);
|
||||
// const _m1 = new Matrix4();
|
||||
// _m1.copy(this.oldParent.matrixWorld).invert();
|
||||
// if (this.object.parent !== null) {
|
||||
// this.object.parent.updateWorldMatrix(true, false);
|
||||
// _m1.multiply( this.object.parent.matrixWorld );
|
||||
// }
|
||||
// this.object.applyMatrix4(_m1);
|
||||
/** 撤销时不改变世界坐标 End **/
|
||||
|
||||
const children = this.oldParent.children;
|
||||
children.splice( this.oldIndex, 0, this.object );
|
||||
this.object.parent = this.oldParent;
|
||||
|
||||
/** 撤销时不改变世界坐标 **/
|
||||
// this.object.updateWorldMatrix( false, true );
|
||||
/** 撤销时不改变世界坐标 End **/
|
||||
|
||||
this.object.dispatchEvent( { type: 'added' } );
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.newParentUuid = this.newParent.uuid;
|
||||
output.oldParentUuid = this.oldParent.uuid;
|
||||
output.newIndex = this.newIndex;
|
||||
output.oldIndex = this.oldIndex;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
super.fromJSON(json);
|
||||
|
||||
this.object = App.getObjectByUuid(json.objectUuid);
|
||||
this.oldParent = App.getObjectByUuid(json.oldParentUuid);
|
||||
if (this.oldParent === undefined) {
|
||||
this.oldParent = App.scene;
|
||||
}
|
||||
|
||||
this.newParent = App.getObjectByUuid(json.newParentUuid);
|
||||
|
||||
if (this.newParent === undefined) {
|
||||
this.newParent = App.scene;
|
||||
}
|
||||
|
||||
this.newIndex = json.newIndex;
|
||||
this.oldIndex = json.oldIndex;
|
||||
}
|
||||
}
|
||||
|
||||
export { MoveObjectCommand };
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Command } from './Command';
|
||||
import { ObjectLoader } from '../loader/ObjectLoader';
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @constructor
|
||||
*/
|
||||
class RemoveObjectCommand extends Command {
|
||||
public object;
|
||||
public parent;
|
||||
public index;
|
||||
|
||||
constructor( object ) {
|
||||
super();
|
||||
|
||||
this.type = 'RemoveObjectCommand';
|
||||
this.name = 'Remove object';
|
||||
|
||||
this.object = object;
|
||||
this.parent = ( object !== undefined ) ? object.parent : undefined;
|
||||
if ( this.parent !== undefined ) {
|
||||
this.index = this.parent.children.indexOf( this.object );
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
App.removeObject( this.object );
|
||||
App.deselect();
|
||||
}
|
||||
|
||||
undo() {
|
||||
App.addObject( this.object, this.parent, this.index );
|
||||
App.select( this.object );
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
output.object = this.object.toJSON();
|
||||
output.index = this.index;
|
||||
output.parentUuid = this.parent.uuid;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.parent = App.getObjectByUuid( json.parentUuid );
|
||||
if ( this.parent === undefined ) {
|
||||
this.parent = App.scene;
|
||||
}
|
||||
|
||||
this.index = json.index;
|
||||
this.object = App.getObjectByUuid( json.object.object.uuid );
|
||||
|
||||
if ( this.object === undefined ) {
|
||||
const loader = new ObjectLoader();
|
||||
this.object = loader.parse( json.object );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { RemoveObjectCommand };
|
||||
@@ -0,0 +1,68 @@
|
||||
import {Object3D} from "three";
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param script javascript object
|
||||
* @constructor
|
||||
*/
|
||||
class RemoveScriptCommand extends Command {
|
||||
private object: Object3D;
|
||||
private script: any;
|
||||
private index: number = -1;
|
||||
|
||||
constructor(object:Object3D, script) {
|
||||
super();
|
||||
|
||||
this.type = 'RemoveScriptCommand';
|
||||
this.name = 'Remove script';
|
||||
|
||||
this.object = object;
|
||||
this.script = script;
|
||||
if (this.object && this.script) {
|
||||
this.index = App.scripts[this.object.uuid].findIndex((i) => i.name === this.script.name);
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
if (App.scripts[ this.object.uuid ] === undefined) return;
|
||||
|
||||
if (this.index !== -1) {
|
||||
App.scripts[this.object.uuid].splice( this.index, 1 );
|
||||
}
|
||||
|
||||
useDispatchSignal("scriptRemoved",this.object,this.script);
|
||||
}
|
||||
|
||||
undo() {
|
||||
if (App.scripts[ this.object.uuid ] === undefined) {
|
||||
App.scripts[ this.object.uuid ] = [];
|
||||
}
|
||||
|
||||
App.scripts[this.object.uuid].splice(this.index, 0, this.script);
|
||||
|
||||
useDispatchSignal("scriptAdded",this.object,this.script);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.script = this.script;
|
||||
output.index = this.index;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.script = json.script;
|
||||
this.index = json.index;
|
||||
this.object = App.getObjectByUuid(json.objectUuid) as Object3D;
|
||||
}
|
||||
}
|
||||
|
||||
export { RemoveScriptCommand };
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks/useSignal";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param attributeName string
|
||||
* @param newValue integer representing a hex color value
|
||||
* @constructor
|
||||
*/
|
||||
class SetColorCommand extends Command {
|
||||
public object;
|
||||
public attributeName;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, attributeName, newValue ) {
|
||||
super();
|
||||
this.type = 'SetColorCommand';
|
||||
this.name = `Set ${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.attributeName = attributeName;
|
||||
this.oldValue = (object !== undefined) ? this.object[this.attributeName].getStyle() : undefined;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object[ this.attributeName ].setStyle(this.newValue);
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object[ this.attributeName ].setStyle(this.oldValue);
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
update( cmd ) {
|
||||
this.newValue = cmd.newValue;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { SetColorCommand };
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Command } from './Command';
|
||||
import { BufferGeometry,Mesh, InstancedBufferGeometry} from 'three';
|
||||
import { ObjectLoader } from '../loader/ObjectLoader';
|
||||
import {useDispatchSignal} from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param editor Editor
|
||||
* @param object THREE.Object3D
|
||||
* @param newGeometry THREE.Geometry
|
||||
* @constructor
|
||||
*/
|
||||
class SetGeometryCommand extends Command {
|
||||
object:Mesh;
|
||||
private oldGeometry: BufferGeometry | InstancedBufferGeometry | undefined;
|
||||
private newGeometry: BufferGeometry | InstancedBufferGeometry
|
||||
|
||||
constructor(object:Mesh, newGeometry:BufferGeometry) {
|
||||
super();
|
||||
|
||||
this.type = 'SetGeometryCommand';
|
||||
this.name = 'Set geometry';
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.oldGeometry = ( object !== undefined ) ? object.geometry : undefined;
|
||||
this.newGeometry = newGeometry;
|
||||
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object.geometry.dispose();
|
||||
this.object.geometry = this.newGeometry;
|
||||
this.object.geometry.computeBoundingSphere();
|
||||
|
||||
useDispatchSignal("geometryChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object.geometry.dispose();
|
||||
this.oldGeometry && (this.object.geometry = this.oldGeometry);
|
||||
this.object.geometry.computeBoundingSphere();
|
||||
|
||||
useDispatchSignal("geometryChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
update(cmd: { newGeometry: BufferGeometry | InstancedBufferGeometry; }) {
|
||||
this.newGeometry = cmd.newGeometry;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.oldGeometry = this.object.geometry.toJSON();
|
||||
output.newGeometry = this.newGeometry.toJSON();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid ) as Mesh;
|
||||
this.oldGeometry = parseGeometry( json.oldGeometry );
|
||||
this.newGeometry = parseGeometry( json.newGeometry );
|
||||
|
||||
function parseGeometry(data) {
|
||||
const loader = new ObjectLoader();
|
||||
return loader.parseGeometries( [ data ] )[ data.uuid ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { SetGeometryCommand };
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks/useSignal";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param attributeName string
|
||||
* @param newValue number, string, boolean or object
|
||||
* @constructor
|
||||
*/
|
||||
class SetGeometryValueCommand extends Command {
|
||||
public object;
|
||||
public attributeName;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, attributeName, newValue ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetGeometryValueCommand';
|
||||
this.name = `Set geometry.${attributeName}`;
|
||||
|
||||
this.object = object;
|
||||
this.attributeName = attributeName;
|
||||
this.oldValue = ( object !== undefined ) ? object.geometry[ attributeName ] : undefined;
|
||||
this.newValue = newValue;
|
||||
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object.geometry[ this.attributeName ] = this.newValue;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("geometryChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object.geometry[ this.attributeName ] = this.oldValue;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("geometryChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
}
|
||||
}
|
||||
|
||||
export { SetGeometryValueCommand };
|
||||
@@ -0,0 +1,69 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param attributeName string
|
||||
* @param newValue integer representing a hex color value
|
||||
* @constructor
|
||||
*/
|
||||
class SetMaterialColorCommand extends Command {
|
||||
public object;
|
||||
public material;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
public attributeName;
|
||||
|
||||
constructor(object, attributeName, newValue, materialSlot ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetMaterialColorCommand';
|
||||
this.name = `Set material.${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.material = (this.object !== undefined) ? App.getObjectMaterial(object, materialSlot) : undefined;
|
||||
|
||||
this.oldValue = (this.material !== undefined) ? this.material[attributeName].getHex() : undefined;
|
||||
this.newValue = newValue;
|
||||
|
||||
this.attributeName = attributeName;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.material[ this.attributeName ].setHex( this.newValue );
|
||||
useDispatchSignal("materialChanged",this.material);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.material[ this.attributeName ].setHex( this.oldValue );
|
||||
useDispatchSignal("materialChanged",this.material);
|
||||
}
|
||||
|
||||
update( cmd ) {
|
||||
this.newValue = cmd.newValue;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
}
|
||||
}
|
||||
|
||||
export { SetMaterialColorCommand };
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Command } from './Command';
|
||||
import { ObjectLoader } from '../loader/ObjectLoader';
|
||||
import {useDispatchSignal} from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param newMaterial THREE.Material
|
||||
* @constructor
|
||||
*/
|
||||
class SetMaterialCommand extends Command {
|
||||
private object;
|
||||
private materialSlot;
|
||||
private oldMaterial;
|
||||
private newMaterial;
|
||||
|
||||
constructor(object, newMaterial, materialSlot? ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetMaterialCommand';
|
||||
this.name = 'Set new material';
|
||||
|
||||
this.object = object;
|
||||
this.materialSlot = materialSlot;
|
||||
|
||||
this.oldMaterial = App.getObjectMaterial( object, materialSlot );
|
||||
this.newMaterial = newMaterial;
|
||||
}
|
||||
|
||||
execute() {
|
||||
App.setObjectMaterial( this.object, this.materialSlot, this.newMaterial );
|
||||
useDispatchSignal("materialChanged",this.newMaterial);
|
||||
}
|
||||
|
||||
undo() {
|
||||
App.setObjectMaterial( this.object, this.materialSlot, this.oldMaterial );
|
||||
useDispatchSignal("materialChanged",this.oldMaterial);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.oldMaterial = this.oldMaterial.toJSON();
|
||||
output.newMaterial = this.newMaterial.toJSON();
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.oldMaterial = parseMaterial( json.oldMaterial );
|
||||
this.newMaterial = parseMaterial( json.newMaterial );
|
||||
|
||||
function parseMaterial( json ) {
|
||||
const loader = new ObjectLoader();
|
||||
//@ts-ignore
|
||||
const images = loader.parseImages( json.images );
|
||||
const textures = loader.parseTextures( json.textures, images );
|
||||
const materials = loader.parseMaterials( [ json ], textures );
|
||||
return materials[ json.uuid ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { SetMaterialCommand };
|
||||
@@ -0,0 +1,125 @@
|
||||
import { Command } from './Command';
|
||||
import { ObjectLoader } from '../loader/ObjectLoader';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param mapName string
|
||||
* @param newMap THREE.Texture
|
||||
* @constructor
|
||||
*/
|
||||
class SetMaterialMapCommand extends Command {
|
||||
public object;
|
||||
private material;
|
||||
private oldMap;
|
||||
private newMap;
|
||||
private mapName;
|
||||
|
||||
constructor( object, mapName, newMap, materialSlot ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetMaterialMapCommand';
|
||||
this.name = `Set material.${mapName}`;
|
||||
|
||||
this.object = object;
|
||||
this.material = App.getObjectMaterial( object, materialSlot );
|
||||
|
||||
this.oldMap = ( object !== undefined ) ? this.material[ mapName ] : undefined;
|
||||
this.newMap = newMap;
|
||||
|
||||
this.mapName = mapName;
|
||||
}
|
||||
|
||||
execute() {
|
||||
if ( this.oldMap !== null && this.oldMap !== undefined ) this.oldMap.dispose();
|
||||
|
||||
this.material[ this.mapName ] = this.newMap;
|
||||
this.material.needsUpdate = true;
|
||||
|
||||
useDispatchSignal("materialChanged",this.material)
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.material[ this.mapName ] = this.oldMap;
|
||||
this.material.needsUpdate = true;
|
||||
|
||||
useDispatchSignal("materialChanged",this.material)
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.mapName = this.mapName;
|
||||
output.newMap = serializeMap( this.newMap );
|
||||
output.oldMap = serializeMap( this.oldMap );
|
||||
|
||||
return output;
|
||||
|
||||
// serializes a map (THREE.Texture)
|
||||
|
||||
function serializeMap( map ) {
|
||||
|
||||
if ( map === null || map === undefined ) return null;
|
||||
|
||||
const meta = {
|
||||
geometries: {},
|
||||
materials: {},
|
||||
textures: {},
|
||||
images: {}
|
||||
};
|
||||
|
||||
const json = map.toJSON( meta );
|
||||
const images = extractFromCache( meta.images );
|
||||
if ( images.length > 0 ) json.images = images;
|
||||
json.sourceFile = map.sourceFile;
|
||||
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
// Note: The function 'extractFromCache' is copied from Object3D.toJSON()
|
||||
|
||||
// extract data from the cache hash
|
||||
// remove metadata on each item
|
||||
// and return as array
|
||||
function extractFromCache( cache ) {
|
||||
|
||||
const values:any = [];
|
||||
for ( const key in cache ) {
|
||||
|
||||
const data = cache[ key ];
|
||||
delete data.metadata;
|
||||
values.push( data );
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.mapName = json.mapName;
|
||||
this.oldMap = parseTexture( json.oldMap );
|
||||
this.newMap = parseTexture( json.newMap );
|
||||
|
||||
function parseTexture( json ) {
|
||||
let map;
|
||||
if ( json !== null ) {
|
||||
const loader = new ObjectLoader();
|
||||
const images = loader.parseImages( json.images,()=>{} );
|
||||
const textures = loader.parseTextures( [ json ], images );
|
||||
map = textures[ json.uuid ];
|
||||
map.sourceFile = json.sourceFile;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { SetMaterialMapCommand };
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param attributeName string
|
||||
* @param newMinValue number
|
||||
* @param newMaxValue number
|
||||
* @constructor
|
||||
*/
|
||||
class SetMaterialRangeCommand extends Command {
|
||||
public object;
|
||||
public material;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
public attributeName;
|
||||
|
||||
constructor(object, attributeName, newMinValue, newMaxValue, materialSlot ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetMaterialRangeCommand';
|
||||
this.name = `Set material.${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.material = App.getObjectMaterial( object, materialSlot );
|
||||
|
||||
this.oldValue = ( this.material !== undefined && this.material[ attributeName ] !== undefined ) ? [ ...this.material[ attributeName ] ] : undefined;
|
||||
this.newValue = [ newMinValue, newMaxValue ];
|
||||
|
||||
this.attributeName = attributeName;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.material[ this.attributeName ] = [ ...this.newValue ];
|
||||
this.material.needsUpdate = true;
|
||||
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("materialChanged",this.material);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.material[ this.attributeName ] = [ ...this.oldValue ];
|
||||
this.material.needsUpdate = true;
|
||||
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("materialChanged",this.material);
|
||||
}
|
||||
|
||||
update( cmd ) {
|
||||
this.newValue = [ ...cmd.newValue ];
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = [ ...this.oldValue ];
|
||||
output.newValue = [ ...this.newValue ];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = [ ...json.oldValue ];
|
||||
this.newValue = [ ...json.newValue ];
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
}
|
||||
}
|
||||
|
||||
export { SetMaterialRangeCommand };
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param attributeName string
|
||||
* @param newValue number, string, boolean or object
|
||||
* @constructor
|
||||
*/
|
||||
class SetMaterialValueCommand extends Command {
|
||||
public object;
|
||||
public material;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
public attributeName;
|
||||
|
||||
constructor(object, attributeName, newValue, materialSlot = 0 ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetMaterialValueCommand';
|
||||
this.name = `Set material.${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.material = App.getObjectMaterial( object, materialSlot );
|
||||
|
||||
this.oldValue = ( this.material !== undefined ) ? this.material[ attributeName ] : undefined;
|
||||
this.newValue = newValue;
|
||||
|
||||
this.attributeName = attributeName;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.material[ this.attributeName ] = this.newValue;
|
||||
this.material.needsUpdate = true;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("materialChanged",this.material);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.material[ this.attributeName ] = this.oldValue;
|
||||
this.material.needsUpdate = true;
|
||||
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("materialChanged",this.material);
|
||||
}
|
||||
|
||||
update( cmd ) {
|
||||
this.newValue = cmd.newValue;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { SetMaterialValueCommand };
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
class SetMaterialVectorCommand extends Command {
|
||||
public object;
|
||||
private material;
|
||||
private oldValue;
|
||||
private newValue;
|
||||
private attributeName;
|
||||
|
||||
constructor(object, attributeName, newValue, materialSlot) {
|
||||
super();
|
||||
|
||||
this.type = 'SetMaterialColorCommand';
|
||||
this.name = `Set material.${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.material = App.getObjectMaterial( object, materialSlot );
|
||||
|
||||
this.attributeName = attributeName;
|
||||
|
||||
this.oldValue = (this.material !== undefined) ? this.attribute.toArray() : undefined;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
get attribute() {
|
||||
return this.attributeName.split('.').reduce((obj, key) => obj[key], this.material);
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.attribute.fromArray(this.newValue);
|
||||
useDispatchSignal("materialChanged",this.material)
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.attribute.fromArray(this.oldValue);
|
||||
useDispatchSignal("materialChanged",this.material)
|
||||
}
|
||||
|
||||
update( cmd ) {
|
||||
this.newValue = cmd.newValue;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
}
|
||||
}
|
||||
|
||||
export { SetMaterialVectorCommand };
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Vector3 } from 'three';
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from '@/hooks';
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param newValue THREE.Vector3
|
||||
* @param optionaloldValue THREE.Vector3
|
||||
* @constructor
|
||||
*/
|
||||
class SetPositionCommand extends Command {
|
||||
public object;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, newValue, optionaloldValue? ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetPositionCommand';
|
||||
this.name = `Set position`;
|
||||
this.updatable = true;
|
||||
this.object = object;
|
||||
if ( object !== undefined && newValue !== undefined ) {
|
||||
this.oldValue = object.position.clone();
|
||||
this.newValue = newValue.clone();
|
||||
}
|
||||
|
||||
if ( optionaloldValue !== undefined ) {
|
||||
this.oldValue = optionaloldValue.clone();
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object.position.copy( this.newValue );
|
||||
this.object.updateMatrixWorld( true );
|
||||
useDispatchSignal("objectChanged",this.object)
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object.position.copy( this.oldValue );
|
||||
this.object.updateMatrixWorld( true );
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
update( command ) {
|
||||
this.newValue.copy( command.newValue );
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.oldValue = this.oldValue.toArray();
|
||||
output.newValue = this.newValue.toArray();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.oldValue = new Vector3().fromArray( json.oldValue );
|
||||
this.newValue = new Vector3().fromArray( json.newValue );
|
||||
}
|
||||
}
|
||||
|
||||
export { SetPositionCommand };
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Euler } from 'three';
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param newValue THREE.Euler
|
||||
* @param optionaloldValue THREE.Euler
|
||||
* @constructor
|
||||
*/
|
||||
class SetRotationCommand extends Command {
|
||||
public object;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, newValue, optionaloldValue ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetRotationCommand';
|
||||
this.name = `Set rotation`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
|
||||
if ( object !== undefined && newValue !== undefined ) {
|
||||
this.oldValue = object.rotation.clone();
|
||||
this.newValue = newValue.clone();
|
||||
}
|
||||
|
||||
if ( optionaloldValue !== undefined ) {
|
||||
this.oldValue = optionaloldValue.clone();
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object.rotation.copy( this.newValue );
|
||||
this.object.updateMatrixWorld( true );
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object.rotation.copy( this.oldValue );
|
||||
this.object.updateMatrixWorld( true );
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
update( command ) {
|
||||
this.newValue.copy( command.newValue );
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.oldValue = this.oldValue.toArray();
|
||||
output.newValue = this.newValue.toArray();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.oldValue = new Euler().fromArray( json.oldValue );
|
||||
this.newValue = new Euler().fromArray( json.newValue );
|
||||
}
|
||||
}
|
||||
|
||||
export { SetRotationCommand };
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Vector3 } from 'three';
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks/useSignal";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param newValue THREE.Vector3
|
||||
* @param optionaloldValue THREE.Vector3
|
||||
* @constructor
|
||||
*/
|
||||
class SetScaleCommand extends Command {
|
||||
public object;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, newValue, optionaloldValue ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetScaleCommand';
|
||||
this.name = `Set scale`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
|
||||
if ( object !== undefined && newValue !== undefined ) {
|
||||
this.oldValue = object.scale.clone();
|
||||
this.newValue = newValue.clone();
|
||||
}
|
||||
|
||||
if ( optionaloldValue !== undefined ) {
|
||||
this.oldValue = optionaloldValue.clone();
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object.scale.copy( this.newValue );
|
||||
this.object.updateMatrixWorld( true );
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object.scale.copy( this.oldValue );
|
||||
this.object.updateMatrixWorld( true );
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
}
|
||||
|
||||
update( command ) {
|
||||
this.newValue.copy( command.newValue );
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.oldValue = this.oldValue.toArray();
|
||||
output.newValue = this.newValue.toArray();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
this.oldValue = new Vector3().fromArray( json.oldValue );
|
||||
this.newValue = new Vector3().fromArray( json.newValue );
|
||||
}
|
||||
}
|
||||
|
||||
export { SetScaleCommand };
|
||||
@@ -0,0 +1,85 @@
|
||||
import {Scene} from "three";
|
||||
import { Command } from './Command';
|
||||
import { SetUuidCommand } from './SetUuidCommand';
|
||||
import { SetValueCommand } from './SetValueCommand';
|
||||
import { AddObjectCommand } from './AddObjectCommand';
|
||||
import {useSignal} from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
const {setActive,dispatch} = useSignal();
|
||||
|
||||
/**
|
||||
* @param scene containing children to import
|
||||
* @constructor
|
||||
*/
|
||||
class SetSceneCommand extends Command {
|
||||
private cmdArray: any[];
|
||||
constructor(scene:Scene) {
|
||||
super();
|
||||
|
||||
this.type = 'SetSceneCommand';
|
||||
this.name = 'Set scene';
|
||||
|
||||
this.cmdArray = [];
|
||||
|
||||
if (scene !== undefined) {
|
||||
this.cmdArray.push( new SetUuidCommand(App.scene, scene.uuid));
|
||||
this.cmdArray.push( new SetValueCommand(App.scene, 'name', scene.name));
|
||||
this.cmdArray.push( new SetValueCommand(App.scene, 'userData', JSON.parse(JSON.stringify(scene.userData))));
|
||||
|
||||
while ( scene.children.length > 0 ) {
|
||||
const child = scene.children.pop();
|
||||
this.cmdArray.push(new AddObjectCommand(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
execute() {
|
||||
setActive("sceneGraphChanged",false);
|
||||
|
||||
for (let i = 0; i < this.cmdArray.length; i++) {
|
||||
this.cmdArray[i].execute();
|
||||
}
|
||||
|
||||
setActive("sceneGraphChanged",true);
|
||||
dispatch("sceneGraphChanged");
|
||||
}
|
||||
|
||||
undo() {
|
||||
setActive("sceneGraphChanged",false);
|
||||
|
||||
for (let i = this.cmdArray.length - 1; i >= 0; i--) {
|
||||
this.cmdArray[i].undo();
|
||||
}
|
||||
|
||||
setActive("sceneGraphChanged",true);
|
||||
dispatch("sceneGraphChanged");
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
const cmds:string[] = [];
|
||||
for ( let i = 0; i < this.cmdArray.length; i ++ ) {
|
||||
cmds.push(this.cmdArray[ i ].toJSON());
|
||||
}
|
||||
|
||||
output.cmds = cmds;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
super.fromJSON( json );
|
||||
|
||||
const cmds = json.cmds;
|
||||
for ( let i = 0; i < cmds.length; i ++ ) {
|
||||
// @ts-ignore
|
||||
const cmd = new window[cmds[i].type](); // 创建类型为“json.type”的新对象
|
||||
cmd.fromJSON(cmds[i]);
|
||||
this.cmdArray.push(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { SetSceneCommand };
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Object3D } from 'three';
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param script javascript object
|
||||
* @param attributeName string
|
||||
* @param newValue string, object
|
||||
* @constructor
|
||||
*/
|
||||
class SetScriptValueCommand extends Command {
|
||||
private object: Object3D;
|
||||
private script: IScript.IStruct;
|
||||
private attributeName: string;
|
||||
private oldValue: any;
|
||||
private newValue: string;
|
||||
|
||||
constructor(object:Object3D, script:IScript.IStruct, attributeName:string, newValue:string) {
|
||||
super();
|
||||
|
||||
this.type = 'SetScriptValueCommand';
|
||||
this.name = `Set script.${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.script = script;
|
||||
|
||||
this.attributeName = attributeName;
|
||||
this.oldValue = ( script !== undefined ) ? script[ this.attributeName ] : undefined;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.script[this.attributeName] = this.newValue;
|
||||
|
||||
useDispatchSignal("scriptChanged",this.attributeName,this.object,this.script);
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.script[this.attributeName] = this.oldValue;
|
||||
|
||||
useDispatchSignal("scriptChanged",this.attributeName,this.object,this.script);
|
||||
}
|
||||
|
||||
update(cmd) {
|
||||
this.newValue = cmd.newValue;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.index = App.scripts[this.object.uuid].indexOf(this.script);
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
super.fromJSON(json);
|
||||
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
this.attributeName = json.attributeName;
|
||||
this.object = App.getObjectByUuid(json.objectUuid) as Object3D;
|
||||
this.script = App.scripts[json.objectUuid][json.index];
|
||||
}
|
||||
}
|
||||
|
||||
export { SetScriptValueCommand };
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param newValue string
|
||||
* @constructor
|
||||
*/
|
||||
class SetUuidCommand extends Command {
|
||||
public object;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, newValue ) {
|
||||
super();
|
||||
|
||||
this.type = 'SetUuidCommand';
|
||||
this.name = `Update uuid`;
|
||||
|
||||
this.object = object;
|
||||
|
||||
this.oldValue = ( object !== undefined ) ? object.uuid : undefined;
|
||||
this.newValue = newValue;
|
||||
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object.uuid = this.newValue;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object.uuid = this.oldValue;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
this.object = App.getObjectByUuid( json.oldValue );
|
||||
|
||||
if ( this.object === undefined ) {
|
||||
this.object = App.getObjectByUuid( json.newValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { SetUuidCommand };
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Command } from './Command';
|
||||
import { useDispatchSignal } from "@/hooks";
|
||||
import App from "../app/App";
|
||||
|
||||
/**
|
||||
* @param object THREE.Object3D
|
||||
* @param attributeName string
|
||||
* @param newValue number, string, boolean or object
|
||||
* @constructor
|
||||
*/
|
||||
class SetValueCommand extends Command {
|
||||
public object;
|
||||
public attributeName;
|
||||
public oldValue;
|
||||
public newValue;
|
||||
|
||||
constructor(object, attributeName, newValue) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'SetValueCommand';
|
||||
this.name = `Set ${attributeName}`;
|
||||
this.updatable = true;
|
||||
|
||||
this.object = object;
|
||||
this.attributeName = attributeName;
|
||||
this.oldValue = ( object !== undefined ) ? object[ attributeName ] : undefined;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.object[ this.attributeName ] = this.newValue;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.object[ this.attributeName ] = this.oldValue;
|
||||
useDispatchSignal("objectChanged",this.object);
|
||||
useDispatchSignal("sceneGraphChanged");
|
||||
}
|
||||
|
||||
update( cmd ) {
|
||||
this.newValue = cmd.newValue;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const output = super.toJSON();
|
||||
|
||||
output.objectUuid = this.object.uuid;
|
||||
output.attributeName = this.attributeName;
|
||||
output.oldValue = this.oldValue;
|
||||
output.newValue = this.newValue;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
super.fromJSON( json );
|
||||
|
||||
this.attributeName = json.attributeName;
|
||||
this.oldValue = json.oldValue;
|
||||
this.newValue = json.newValue;
|
||||
this.object = App.getObjectByUuid( json.objectUuid );
|
||||
}
|
||||
}
|
||||
|
||||
export { SetValueCommand };
|
||||
Reference in New Issue
Block a user