提交 c1cbfc8a 编写于 作者: D Daniel

added undo/redo for material values, maps, booleans

IMPORTENT: Serialization of Maps does NOT work yet!
上级 4fa8fba2
......@@ -135,7 +135,11 @@
<script src="js/CmdAddScript.js"></script>
<script src="js/CmdRemoveScript.js"></script>
<script src="js/CmdSetScriptValue.js"></script>
<script src="js/CmdSetMaterial.js"></script>
<script src="js/CmdSetMaterialValue.js"></script>
<script src="js/CmdSetMaterialColor.js"></script>
<script src="js/CmdSetMaterialMap.js"></script>
<script src="js/CmdToggleBooleanMaterial.js"></script>
<script src="js/CmdSetScene.js"></script>
<script>
......
......@@ -7,16 +7,22 @@ CmdSetMaterial = function ( object, newMaterial ) {
Cmd.call( this );
this.type = 'CmdSetMaterial';
this.updatable = true;
this.object = object;
this.objectUuid = object !== undefined ? object.uuid : undefined;
this.newMaterial = newMaterial; // only needed for update(cmd)
this.oldMaterial = object !== undefined ? object.material : undefined;
this.newMaterial = newMaterial;
this.oldMaterialJSON = object !== undefined ? object.material.toJSON() : undefined;
this.newMaterialJSON = newMaterial !== undefined ? newMaterial.toJSON() : undefined;
meta = {
geometries: {},
materials: {},
textures: {},
images: {}
};
this.oldMaterialJSON = object !== undefined ? object.material.toJSON( meta ) : undefined;
this.newMaterialJSON = newMaterial !== undefined ? newMaterial.toJSON( meta ) : undefined;
};
......@@ -24,29 +30,15 @@ CmdSetMaterial.prototype = {
execute: function () {
this.object.geometry.dispose();
this.object.geometry = this.parseGeometry( this.newMaterialJSON );
this.object.geometry.computeBoundingSphere();
this.editor.signals.geometryChanged.dispatch( this.object );
this.editor.signals.sceneGraphChanged.dispatch();
this.object.material = this.newMaterial;
this.editor.signals.materialChanged.dispatch( this.newMaterial );
},
undo: function () {
this.object.geometry.dispose();
this.object.geometry = this.parseGeometry( this.oldMaterialJSON );
this.object.geometry.computeBoundingSphere();
this.editor.signals.geometryChanged.dispatch( this.object );
this.editor.signals.sceneGraphChanged.dispatch();
},
update: function ( cmd ) {
this.newMaterialJSON = cmd.newGeometry.toJSON();
this.object.material = this.oldMaterial;
this.editor.signals.materialChanged.dispatch( this.oldMaterial );
},
......@@ -55,8 +47,8 @@ CmdSetMaterial.prototype = {
var output = Cmd.prototype.toJSON.call( this );
output.objectUuid = this.objectUuid;
output.oldMaterialJSON = this.oldMaterialJSON;
output.newMaterialJSON = this.newMaterialJSON;
output.oldMaterial = this.oldMaterialJSON;
output.newMaterial = this.newMaterialJSON;
return output;
......@@ -69,133 +61,18 @@ CmdSetMaterial.prototype = {
this.object = this.editor.objectByUuid( json.objectUuid );
this.objectUuid = json.objectUuid;
this.oldMaterialJSON = json.oldMaterialJSON;
this.newMaterialJSON = json.newMaterialJSON;
},
parseGeometry: function ( data ) {
var geometryLoader = new THREE.JSONLoader();
var bufferGeometryLoader = new THREE.BufferGeometryLoader();
var geometry;
switch ( data.type ) {
case 'PlaneGeometry':
case 'PlaneBufferGeometry':
geometry = new THREE[ data.type ](
data.width,
data.height,
data.widthSegments,
data.heightSegments
);
break;
case 'BoxGeometry':
case 'CubeGeometry': // backwards compatible
geometry = new THREE.BoxGeometry(
data.width,
data.height,
data.depth,
data.widthSegments,
data.heightSegments,
data.depthSegments
);
break;
case 'CircleGeometry':
geometry = new THREE.CircleGeometry(
data.radius,
data.segments
);
this.oldMaterial = this.parseMaterial( json.oldMaterial );
this.newMaterial = this.parseMaterial( json.newMaterial );
break;
this.oldMaterialJSON = json.oldMaterial;
this.newMaterialJSON = json.newMaterial;
case 'CylinderGeometry':
geometry = new THREE.CylinderGeometry(
data.radiusTop,
data.radiusBottom,
data.height,
data.radialSegments,
data.heightSegments,
data.openEnded
);
break;
case 'SphereGeometry':
geometry = new THREE.SphereGeometry(
data.radius,
data.widthSegments,
data.heightSegments,
data.phiStart,
data.phiLength,
data.thetaStart,
data.thetaLength
);
break;
case 'IcosahedronGeometry':
geometry = new THREE.IcosahedronGeometry(
data.radius,
data.detail
);
break;
case 'TorusGeometry':
geometry = new THREE.TorusGeometry(
data.radius,
data.tube,
data.radialSegments,
data.tubularSegments,
data.arc
);
break;
case 'TorusKnotGeometry':
geometry = new THREE.TorusKnotGeometry(
data.radius,
data.tube,
data.radialSegments,
data.tubularSegments,
data.p,
data.q,
data.heightScale
);
break;
case 'BufferGeometry':
geometry = bufferGeometryLoader.parse( data );
break;
case 'Geometry':
geometry = geometryLoader.parse( data.data ).geometry;
},
break;
parseMaterial: function ( data ) {
}
geometry.uuid = data.uuid;
geometry.name = data.name !== undefined ? data.name : '';
return geometry;
var loader = new THREE.ObjectLoader();
return loader.parseMaterials( [ data ] )[ data.uuid ];
}
......
/**
* Created by Daniel on 21.07.15.
*/
CmdSetMaterialColor = function ( object, attributeName, newValue ) {
Cmd.call( this );
this.type = 'CmdSetMaterialColor';
this.updatable = true;
this.object = object;
this.objectUuid = object !== undefined ? object.uuid : undefined;
this.attributeName = attributeName;
this.oldValue = object !== undefined ? this.object.material[ this.attributeName ].getHex() : undefined;
this.newValue = newValue;
};
CmdSetMaterialColor.prototype = {
execute: function () {
this.object.material[ this.attributeName ].setHex( this.newValue );
this.editor.signals.materialChanged.dispatch( this.object.material );
},
undo: function () {
this.object.material[ this.attributeName ].setHex( this.oldValue );
this.editor.signals.materialChanged.dispatch( this.object.material );
},
update: function ( cmd ) {
this.newValue = cmd.newValue;
},
toJSON: function () {
var output = Cmd.prototype.toJSON.call( this );
output.objectUuid = this.objectUuid;
output.attributeName = this.attributeName;
output.oldValue = this.oldValue;
output.newValue = this.newValue;
return output;
},
fromJSON: function ( json ) {
Cmd.prototype.fromJSON.call( this, json );
this.object = this.editor.objectByUuid( json.objectUuid );
this.objectUuid = json.objectUuid;
this.attributeName = json.attributeName;
this.oldValue = json.oldValue;
this.newValue = json.newValue;
}
};
/**
* Created by Daniel on 21.07.15.
*/
CmdSetMaterialMap = function ( object, mapName, newMap ) {
Cmd.call( this );
this.type = 'CmdSetMaterialMap';
this.object = object;
this.mapName = mapName;
this.oldMap = object !== undefined ? object.material[ mapName ] : undefined;
this.newMap = newMap;
this.objectUuid = object !== undefined ? object.uuid : undefined;
/*
if ( object !== undefined ) {
meta = {
geometries: {},
materials: {},
textures: {},
images: {}
};
this.newMapJSON = newMap.toJSON( meta );
this.newMapJSON.images = [ newMap.image.toJSON( meta ) ];
if ( object.material[ mapName ] !== null ) {
this.oldMapJSON = object.material[ mapName ].toJSON( meta );
this.oldMapJSON.textures = [ object.material[ mapName ].texture.toJSON( meta ) ];
}
}
*/
};
CmdSetMaterialMap.prototype = {
execute: function () {
this.object.material[ this.mapName ] = this.newMap;
this.object.material.needsUpdate = true;
this.editor.signals.materialChanged.dispatch( this.object.material );
},
undo: function () {
this.object.material[ this.mapName ] = this.oldMap;
this.object.material.needsUpdate = true;
this.editor.signals.materialChanged.dispatch( this.object.material );
},
toJSON: function () {
var output = Cmd.prototype.toJSON.call( this );
output.objectUuid = this.objectUuid;
output.mapName = this.mapName;
output.oldMap = this.oldMapJSON;
output.newMap = this.newMapJSON;
return output;
},
fromJSON: function ( json ) {
Cmd.prototype.fromJSON.call( this, json );
this.objectUuid = json.objectUuid;
this.mapName = json.mapName;
this.object = this.editor.objectByUuid( json.objectUuid );
this.oldMap = this.parseTexture( json.oldMap );
this.newMap = this.parseTexture( json.newMap );
this.oldMapJSON = json.oldMap;
this.newMapJSON = json.newMap;
},
parseTexture: function ( data, images ) {
var loader = new THREE.ObjectLoader();
return loader.parseTextures( [ data ] )[ data.uuid ];
}
};
......@@ -388,7 +388,7 @@ Sidebar.Material = function ( editor ) {
if ( material.uuid !== undefined && material.uuid !== materialUUID.getValue() ) {
editor.execute( new CmdSetMaterialValue( editor.selected, 'uuid', materialUUID.getValue() ) );
editor.execute( new CmdSetMaterialValue( currentObject, 'uuid', materialUUID.getValue() ) );
}
......@@ -396,7 +396,7 @@ Sidebar.Material = function ( editor ) {
material = new THREE[ materialClass.getValue() ]();
object.material = material;
editor.execute( new CmdSetMaterial( currentObject, material ) );
// TODO Copy other references in the scene graph
// keeping name and UUID then.
// Also there should be means to create a unique
......@@ -405,27 +405,27 @@ Sidebar.Material = function ( editor ) {
}
if ( material.color !== undefined ) {
if ( material.color !== undefined && material.color.getHex() !== materialColor.getHexValue() ) {
material.color.setHex( materialColor.getHexValue() );
editor.execute( new CmdSetMaterialColor( currentObject, 'color', materialColor.getHexValue() ) );
}
if ( material.emissive !== undefined ) {
if ( material.emissive !== undefined && material.emissive.getHex() !== materialEmissive.getHexValue() ) {
material.emissive.setHex( materialEmissive.getHexValue() );
editor.execute( new CmdSetMaterialColor( currentObject, 'emissive', materialEmissive.getHexValue() ) );
}
if ( material.specular !== undefined ) {
if ( material.specular !== undefined && material.specular.getHex() !== materialSpecular.getHexValue() ) {
material.specular.setHex( materialSpecular.getHexValue() );
editor.execute( new CmdSetMaterialColor( currentObject, 'specular', materialSpecular.getHexValue() ) );
}
if ( material.shininess !== undefined ) {
if ( material.shininess !== undefined && Math.abs( material.shininess - materialShininess.getValue() ) >= 0.01 ) {
material.shininess = materialShininess.getValue();
editor.execute( new CmdSetMaterialValue( currentObject, 'shininess', materialShininess.getValue() ) );
}
......@@ -435,16 +435,15 @@ Sidebar.Material = function ( editor ) {
if ( material.vertexColors !== vertexColors ) {
material.vertexColors = vertexColors;
material.needsUpdate = true;
editor.execute( new CmdSetMaterialValue( currentObject, 'vertexColors', vertexColors ) );
}
}
if ( material.skinning !== undefined ) {
if ( material.skinning !== undefined && material.skinning !== materialSkinning.getValue() ) {
material.skinning = materialSkinning.getValue();
editor.execute( new CmdToggleBooleanMaterial( currentObject, 'skinning' ) );
}
......@@ -454,8 +453,12 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.map = mapEnabled ? materialMap.getValue() : null;
material.needsUpdate = true;
var map = mapEnabled ? materialMap.getValue() : null;
if ( material.map !== map ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'map', map ) );
}
} else {
......@@ -471,8 +474,12 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.alphaMap = mapEnabled ? materialAlphaMap.getValue() : null;
material.needsUpdate = true;
var alphaMap = mapEnabled ? materialAlphaMap.getValue() : null;
if ( material.alphaMap !== alphaMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'alphaMap', alphaMap ) );
}
} else {
......@@ -488,9 +495,18 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.bumpMap = bumpMapEnabled ? materialBumpMap.getValue() : null;
material.bumpScale = materialBumpScale.getValue();
material.needsUpdate = true;
var bumpMap = bumpMapEnabled ? materialBumpMap.getValue() : null;
if ( material.bumpMap !== bumpMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'bumpMap', bumpMap ) );
}
if ( material.bumpScale !== materialBumpScale.getValue() ) {
editor.execute( new CmdSetMaterialValue( currentObject, 'bumpScale', materialBumpScale.getValue() ) );
}
} else {
......@@ -506,8 +522,12 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.normalMap = normalMapEnabled ? materialNormalMap.getValue() : null;
material.needsUpdate = true;
var normalMap = normalMapEnabled ? materialNormalMap.getValue() : null;
if ( material.normalMap !== normalMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'normalMap', normalMap ) );
}
} else {
......@@ -523,8 +543,12 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.specularMap = specularMapEnabled ? materialSpecularMap.getValue() : null;
material.needsUpdate = true;
var specularMap = specularMapEnabled ? materialSpecularMap.getValue() : null;
if ( material.specularMap !== normalMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'specularMap', specularMap ) );
}
} else {
......@@ -538,12 +562,21 @@ Sidebar.Material = function ( editor ) {
var envMapEnabled = materialEnvMapEnabled.getValue() === true;
material.envMap = envMapEnabled ? materialEnvMap.getValue() : null;
material.reflectivity = materialReflectivity.getValue();
material.needsUpdate = true;
var envMap = envMapEnabled ? materialEnvMap.getValue() : null;
}
if ( material.envMap !== envMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'envMap', envMap ) );
}
if ( material.reflectivity !== materialReflectivity.getValue() ) {
editor.execute( new CmdSetMaterialValue( currentObject, 'reflectivity', materialReflectivity.getValue() ) );
}
}
if ( material.lightMap !== undefined ) {
......@@ -551,8 +584,12 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.lightMap = specularMapEnabled ? materialLightMap.getValue() : null;
material.needsUpdate = true;
var lightMap = specularMapEnabled ? materialLightMap.getValue() : null;
if ( material.lightMap !== lightMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'lightMap', lightMap ) );
}
} else {
......@@ -568,9 +605,18 @@ Sidebar.Material = function ( editor ) {
if ( objectHasUvs ) {
material.aoMap = aoMapEnabled ? materialAOMap.getValue() : null;
material.aoMapIntensity = materialAOScale.getValue();
material.needsUpdate = true;
var aoMap = aoMapEnabled ? materialAOMap.getValue() : null;
if ( material.aoMap !== aoMap ) {
editor.execute( new CmdSetMaterialMap( currentObject, 'aoMap', aoMap ) );
}
if ( material.aoMapIntensity !== materialAOScale.getValue() ) {
editor.execute( new CmdSetMaterialValue( currentObject, 'aoMapIntensity', materialAOScale.getValue() ) );
}
} else {
......@@ -582,49 +628,65 @@ Sidebar.Material = function ( editor ) {
if ( material.side !== undefined ) {
material.side = parseInt( materialSide.getValue() );
var side = parseInt( materialSide.getValue() );
if ( material.side !== side ) {
editor.execute( new CmdSetMaterialValue( currentObject, 'side', side ) );
}
}
if ( material.shading !== undefined ) {
material.shading = parseInt( materialShading.getValue() );
var shading = parseInt( materialShading.getValue() );
if ( material.shading !== shading ) {
editor.execute( new CmdSetMaterialValue( currentObject, 'shading', shading ) );
}
}
if ( material.blending !== undefined ) {
material.blending = parseInt( materialBlending.getValue() );
var blending = parseInt( materialBlending.getValue() );
if ( material.blending !== blending ) {
editor.execute( new CmdSetMaterialValue( currentObject, 'blending', blending ) );
}
}
if ( material.opacity !== undefined ) {
if ( material.opacity !== undefined && Math.abs( material.opacity - materialOpacity.getValue() ) >= 0.01 ) {
material.opacity = materialOpacity.getValue();
editor.execute( new CmdSetMaterialValue( currentObject, 'opacity', materialOpacity.getValue() ) );
}
if ( material.transparent !== undefined ) {
if ( material.transparent !== undefined && material.transparent !== materialTransparent.getValue() ) {
material.transparent = materialTransparent.getValue();
editor.execute( new CmdToggleBooleanMaterial( currentObject, 'transparent' ) );
}
if ( material.alphaTest !== undefined ) {
if ( material.alphaTest !== undefined && Math.abs( material.alphaTest - materialAlphaTest.getValue() ) >= 0.01 ) {
material.alphaTest = materialAlphaTest.getValue();
editor.execute( new CmdSetMaterialValue( currentObject, 'alphaTest', materialAlphaTest.getValue() ) );
}
if ( material.wireframe !== undefined ) {
if ( material.wireframe !== undefined && material.wireframe !== materialWireframe.getValue() ) {
material.wireframe = materialWireframe.getValue();
editor.execute( new CmdToggleBooleanMaterial( currentObject, 'wireframe' ) );
}
if ( material.wireframeLinewidth !== undefined ) {
if ( material.wireframeLinewidth !== undefined && Math.abs( material.wireframeLinewidth - materialWireframeLinewidth.getValue() ) >= 0.01 ) {
material.wireframeLinewidth = materialWireframeLinewidth.getValue();
editor.execute( new CmdSetMaterialValue( currentObject, 'wireframeLinewidth', materialWireframeLinewidth.getValue() ) );
}
......@@ -685,6 +747,8 @@ Sidebar.Material = function ( editor ) {
function refreshUi(resetTextureSelectors) {
if ( !currentObject ) return;
var material = currentObject.material;
if ( material.uuid !== undefined ) {
......@@ -912,6 +976,7 @@ Sidebar.Material = function ( editor ) {
} );
signals.materialChanged.add( function () { refreshUi() } );
return container;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册