docs: function () {
      var dressing = new THREE.Object3D();
      this.dressing.setAttribute('visible', this.data.dressing != 'none');
      if (this.data.dressing == 'none') {
        return;
      }
      var geometry = new THREE.Geometry(); // mother geometry that will hold all instances
  
      // get array of geometries
      var geoset;
      switch (this.data.dressing){
        case 'cubes': {
          geoset = [new THREE.BoxGeometry(1, 1, 1)];
          geoset[0].applyMatrix(new THREE.Matrix4().makeTranslation(0, 0.5, 0));
          break;
        }
        case 'pyramids': {
          geoset = [new THREE.ConeGeometry(1, 1, 4, 1, true)];
          geoset[0].applyMatrix(new THREE.Matrix4().makeTranslation(0, 0.5, 0));
          break;
        }
        case 'cylinders': {
          geoset = [new THREE.CylinderGeometry(0.5, 0.5, 1, 8, 1, true)];
          geoset[0].applyMatrix(new THREE.Matrix4().makeTranslation(0, 0.5, 0));
          break;
        }
        default: {
          geoset = this.getAssetGeometry(this.assets[this.data.dressing]);
          if (!geoset) return;
          break;
        }
      }
  
      for (var i = 0, r = 88343; i < this.data.dressingAmount; i++, r++) {
  
        var geo = geoset[Math.floor(this.random(33 + i) * geoset.length)];
  /*
        // change vertex colors
        var color = new THREE.Color(0xFFFFFF).multiplyScalar(1 - this.random(66 + i) * 0.3);
  
        for (var f = 0, fl = geo.faces.length; f < fl; f++) {
          var face = geo.faces[f];
          for (var v = 0; v < 3; v++) {
            p = geo.vertices[face[faceindex[v]]]; // get vertex position
            var floorao =  p.y / 4 + 0.75;
            face.vertexColors[v] = new THREE.Color(color.r * floorao, color.g * floorao, color.b * floorao);
          }
        }
  */
        // set random position, rotation and scale
        var ds = this.data.dressingScale;
        var dv = new THREE.Vector3(this.data.dressingVariance.x, this.data.dressingVariance.y, this.data.dressingVariance.z);
        var distance;
        var onPlayArea = this.random(r) < this.data.dressingOnPlayArea;
        if (onPlayArea) {
          distance = this.random(r + 1) * 15;
        }
        else {
          distance = 10 + Math.max(dv.x, dv.z) + 10 * this.random(r + 1) + this.random(r + 2) * this.STAGE_SIZE / 3;
        }
  
        var direction = this.random(r + 3) * Math.PI * 2;
        var matrix = new THREE.Matrix4();
        var scale = this.random(r + 4);
        var uniformScale = this.data.dressingUniformScale;
  
        matrix.compose(
          // position
          new THREE.Vector3(
            Math.cos(direction) * distance,
            0,
            Math.sin(direction) * distance
            ),
          // rotation
          new THREE.Quaternion().setFromAxisAngle(
            new THREE.Vector3(0, 1, 0),
            (this.random(r + 5) - 0.5) * dv.length() * Math.PI * 2
            ),
          // scale
          new THREE.Vector3(
             ds + (uniformScale ? scale : this.random(r + 6)) * dv.x,
             ds + (uniformScale ? scale : this.random(r + 7)) * dv.y,
             ds + (uniformScale ? scale : this.random(r + 8)) * dv.z
            )
          );
  
        // merge with mother geometry
        geometry.merge(geo, matrix);
      }
  
      // convert geometry to buffergeometry
      var bufgeo = new THREE.BufferGeometry();
      bufgeo.fromGeometry(geometry);
  
      // setup material
      var material = new THREE.MeshLambertMaterial({
        color: new THREE.Color(this.data.dressingColor),
        vertexColors: THREE.VertexColors
      });
  
      if (this.data.flatShading) {
        bufgeo.computeVertexNormals();
      }
  
      // create mesh
      var mesh = new THREE.Mesh(bufgeo, material);
      dressing.add(mesh);
      // add to scene
      this.dressing.setObject3D('mesh', dressing);
    }