three.js - json scene maker

by mmalex

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.rawgit.com/nmalex/libRAYYS/master/RayysMouse.js"></script>
<script src="https://cdn.rawgit.com/nmalex/libRAYYS/40c79760b008efb024ab50209a09c023e95d3bea/RayysWebColors.js"></script>
<script src="https://cdn.rawgit.com/nmalex/libRAYYS/1654327bdb61ca3c0c026ce7f7fda2b1d1d38e09/RayysMouseMove.js"></script>
<script src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js@cf70d125b048349fb084d8c8395ee790b83c685c/src/FileSaver.js"></script>
<button id="btn-save" onclick="saveToJson()">
Save to JSON
</button>

CSS

body {
  overflow: hidden;
}
#btn-save {
	position: fixed;
}

JavaScript

class RayysObjectDecorator {
	constructor() {
  	// many different decorators may apply at this point,
    // for example decorated obect may be:
    // 1. set color red,
    // 2. present own wireframe,
    // 3. have bounding box wrapper
    // 4. attached move/rotate/scale gizmo
  	this.decorators = {
    	material: undefined,
      children: undefined
    };
    
    // collect decorated objects with info how to undecorate them
  	this.decorated = {
    	material: {},
      children: {}
    };
  }

  decorate(object) {
    // now apply decorators one by one
    this.decorated.material[object.id] = {
      ref: object,               // reference on decorated object
      material: object.material, // backup initial material
    };
    object.material = this.decorators.material(object);

		// attach decorating child geometry
    var dChildren = this.decorators.children(object);
    this.decorated.children[object.id] = {
    	ref: object,
      children: dChildren
    };
    for (let i=0; i<dChildren.length; i++) {
    	object.add(dChildren[i]);
    }
  }
  
  reset(object) {
  	if (object === undefined) { // reset for all
    	// replace decorated material with initial material
      for (let id in this.decorated.material) {
        this.decorated.material[id].ref.material = this.decorated.material[id].material;
        delete this.decorated.material[id];
      }
      
      // now remove all decorating child nodes
      for (let id in this.decorated.children) {
      	var decoratedObj = this.decorated.children[id].ref;
        for (let i=0; i<this.decorated.children[id].children.length; i++) {
        	let dNode = this.decorated.children[id].children[i];
          decoratedObj.remove(dNode);
        }
        delete this.decorated.children[id];
      }
    } else { // reset for given object
    	// restore material
      object.material = this.decorated.material[object.id].material;
      delete this.decorated.material[object.id];
      // remove decorate...