SetMaterialMapCommand.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import { Command } from '../Command.js';
  2. import { ObjectLoader } from 'three';
  3. class SetMaterialMapCommand extends Command {
  4. /**
  5. * @param {Editor} editor
  6. * @param {THREE.Object3D|null} [object=null]
  7. * @param {string} [mapName='']
  8. * @param {THREE.Texture|null} [newMap=null]
  9. * @param {number} [materialSlot=-1]
  10. * @constructor
  11. */
  12. constructor( editor, object = null, mapName = '', newMap = null, materialSlot = - 1 ) {
  13. super( editor );
  14. this.type = 'SetMaterialMapCommand';
  15. this.name = editor.strings.getKey( 'command/SetMaterialMap' ) + ': ' + mapName;
  16. this.object = object;
  17. this.materialSlot = materialSlot;
  18. const material = ( object !== null ) ? editor.getObjectMaterial( object, materialSlot ) : null;
  19. this.oldMap = ( object !== null ) ? material[ mapName ] : undefined;
  20. this.newMap = newMap;
  21. this.mapName = mapName;
  22. }
  23. execute() {
  24. if ( this.oldMap !== null && this.oldMap !== undefined ) this.oldMap.dispose();
  25. const material = this.editor.getObjectMaterial( this.object, this.materialSlot );
  26. material[ this.mapName ] = this.newMap;
  27. material.needsUpdate = true;
  28. this.editor.signals.materialChanged.dispatch( this.object, this.materialSlot );
  29. }
  30. undo() {
  31. const material = this.editor.getObjectMaterial( this.object, this.materialSlot );
  32. material[ this.mapName ] = this.oldMap;
  33. material.needsUpdate = true;
  34. this.editor.signals.materialChanged.dispatch( this.object, this.materialSlot );
  35. }
  36. toJSON() {
  37. const output = super.toJSON( this );
  38. output.objectUuid = this.object.uuid;
  39. output.mapName = this.mapName;
  40. output.newMap = serializeMap( this.newMap );
  41. output.oldMap = serializeMap( this.oldMap );
  42. output.materialSlot = this.materialSlot;
  43. return output;
  44. // serializes a map (THREE.Texture)
  45. function serializeMap( map ) {
  46. if ( map === null || map === undefined ) return null;
  47. const meta = {
  48. geometries: {},
  49. materials: {},
  50. textures: {},
  51. images: {}
  52. };
  53. const json = map.toJSON( meta );
  54. const images = extractFromCache( meta.images );
  55. if ( images.length > 0 ) json.images = images;
  56. json.sourceFile = map.sourceFile;
  57. return json;
  58. }
  59. // Note: The function 'extractFromCache' is copied from Object3D.toJSON()
  60. // extract data from the cache hash
  61. // remove metadata on each item
  62. // and return as array
  63. function extractFromCache( cache ) {
  64. const values = [];
  65. for ( const key in cache ) {
  66. const data = cache[ key ];
  67. delete data.metadata;
  68. values.push( data );
  69. }
  70. return values;
  71. }
  72. }
  73. fromJSON( json ) {
  74. super.fromJSON( json );
  75. this.object = this.editor.objectByUuid( json.objectUuid );
  76. this.mapName = json.mapName;
  77. this.oldMap = parseTexture( json.oldMap );
  78. this.newMap = parseTexture( json.newMap );
  79. this.materialSlot = json.materialSlot;
  80. function parseTexture( json ) {
  81. let map = null;
  82. if ( json !== null ) {
  83. const loader = new ObjectLoader();
  84. const images = loader.parseImages( json.images );
  85. const textures = loader.parseTextures( [ json ], images );
  86. map = textures[ json.uuid ];
  87. map.sourceFile = json.sourceFile;
  88. }
  89. return map;
  90. }
  91. }
  92. }
  93. export { SetMaterialMapCommand };
粤ICP备19079148号