Browse Source

improved editor UI - selection lists and bug fixes

removed comments

Hooked up texture parameters

Added comments
Aleksandar Rodic 12 years ago
parent
commit
7dddae5d2b
5 changed files with 462 additions and 253 deletions
  1. 7 7
      editor/js/Editor.js
  2. 307 149
      editor/js/Sidebar.Attributes.js
  3. 0 46
      editor/js/Sidebar.Outliner.Scene.js
  4. 3 1
      editor/js/libs/ui.js
  5. 145 50
      editor/js/libs/ui.three.js

+ 7 - 7
editor/js/Editor.js

@@ -997,25 +997,25 @@ Editor.prototype = {
     var name = geometry.name;
 
     if ( geometry instanceof THREE.PlaneGeometry )
-      geometry = this.createGeometry( 'plane', parameters );
+      geometry = this.createGeometry( 'Plane', parameters );
 
     if ( geometry instanceof THREE.CubeGeometry )
-      geometry = this.createGeometry( 'cube', parameters );
+      geometry = this.createGeometry( 'Cube', parameters );
 
     if ( geometry instanceof THREE.CylinderGeometry )
-      geometry = this.createGeometry( 'cylinder', parameters );
+      geometry = this.createGeometry( 'Cylinder', parameters );
 
     if ( geometry instanceof THREE.SphereGeometry )
-      geometry = this.createGeometry( 'sphere', parameters );
+      geometry = this.createGeometry( 'Sphere', parameters );
 
     if ( geometry instanceof THREE.IcosahedronGeometry )
-      geometry = this.createGeometry( 'icosahedron', parameters );
+      geometry = this.createGeometry( 'Icosahedron', parameters );
 
     if ( geometry instanceof THREE.TorusGeometry )
-      geometry = this.createGeometry( 'torus', parameters );
+      geometry = this.createGeometry( 'Torus', parameters );
 
     if ( geometry instanceof THREE.TorusKnotGeometry )
-      geometry = this.createGeometry( 'torusknot', parameters );
+      geometry = this.createGeometry( 'Torusknot', parameters );
 
     geometry.computeBoundingSphere();
     geometry.id = id;

+ 307 - 149
editor/js/Sidebar.Attributes.js

@@ -1,98 +1,145 @@
 Sidebar.Attributes = function ( signals ) {
 
   var scope = this;
-  var object;
+  var model;
   var param = {};
 
-  var primaryParams = [
-    'name',
-    'parent',
-    'geometry',
-    'material',
-    'position',
-    'rotation',
-    'scale',
-    'width',
-    'height',
-    'depth',
-    'widthSegments',
-    'heightSegments',
-    'depthSegments',
-    'radialSegments',
-    'tubularSegments',
-    'radius',
-    'radiusTop',
-    'radiusBottom',
-    'phiStart',
-    'phiLength',
-    'thetaStart',
-    'thetaLength',
-    'tube',
-    'arc',
-    'detail',
-    'p',
-    'q',
-    'heightScale',
-    'openEnded',
-    'color',
-    'groundColor',
-    'ambient',
-    'emissive',
-    'specular',
-    'reflectivity',
-    'shininess',
-    'intensity',
-    'opacity',
-    'transparent',
-    'metal',
-    'wireframe',
-    'visible',
-    'userData'
-  ];
+  var primaryParams = [ 'name', 'parent', 'geometry', 'material', 'position', 'rotation', 'scale', 'width', 'height', 'depth',
+  'widthSegments', 'heightSegments', 'depthSegments', 'radialSegments', 'tubularSegments', 'radius', 'radiusTop', 'radiusBottom',
+  'phiStart', 'phiLength', 'thetaStart', 'thetaLength', 'tube', 'arc', 'detail', 'p', 'q', 'heightScale', 'openEnded',
+  'image', 'sourceFile', 'wrapS', 'wrapT', 'minFilter', 'magFilter', 'format', 'repeat', 'offset', 'flipY', 'type', 'color',
+  'groundColor', 'ambient', 'emissive', 'specular', 'reflectivity', 'shininess', 'intensity', 'opacity', 'transparent', 'metal',
+  'wireframe', 'wireframeLinewidth', 'linewidth', 'visible', 'fog', 'near', 'far', 'exponent', 'map', 'lightMap', 'bumpMap',
+  'normalMap', 'specularMap', 'envMap', 'normalScale', 'bumpScale', 'userData' ];
   
-  var secondaryParams = [
-    'castShadow',
-    'receiveShadow',
-    'useQuaternion',
-    'fog',
-    'depthTest',
-    'depthWrite',
-    'dynamic'
-  ];
-
-  var integerParams = [
-    'widthSegments',
-    'heightSegments',
-    'depthSegments',
-    'radialSegments',
-    'tubularSegments'
-  ];
+  var secondaryParams = [ 'quaternion', 'up', 'distance', 'castShadow', 'receiveShadow', 'useQuaternion', 'depthTest', 'depthWrite',
+  'dynamic', 'children', 'elements', 'vertices', 'normals', 'colors', 'faces', 'faceUvs', 'faceVertexUvs', 'boundingBox',
+  'boundingSphere', 'verticesNeedUpdate', 'elementsNeedUpdate', 'uvsNeedUpdate', 'normalsNeedUpdate', 'tangentsNeedUpdate',
+  'colorsNeedUpdate', 'lineDistancesNeedUpdate', 'buffersNeedUpdate', 'matrix', 'matrixWorld', 'blending', 'side', 'blendSrc',
+  'blendDst', 'blendEquation', 'generateMipmaps', 'premultiplyAlpha', 'needsUpdate', 'anisothropy' ];
+
+  var integerParams = [ 'widthSegments', 'heightSegments', 'depthSegments', 'radialSegments', 'tubularSegments' ];
+
+  var textureParams = [ 'map', 'lightMap', 'bumpMap', 'normalMap', 'specularMap', 'envMap' ];
+
+  var multiOptions = {
+    'blending': {
+      'NoBlending': THREE.NoBlending,
+      'NormalBlending': THREE.NormalBlending,
+      'AdditiveBlending': THREE.AdditiveBlending,
+      'SubtractiveBlending': THREE.SubtractiveBlending,
+      'MultiplyBlending': THREE.MultiplyBlending,
+      'CustomBlending': THREE.CustomBlending
+    }
+    ,
+    'side': {
+      'FrontSide': THREE.FrontSide,
+      'BackSide': THREE.BackSide,
+      'DoubleSide': THREE.DoubleSide
+    },
+    'blendSrc': {
+      'ZeroFactor': THREE.ZeroFactor,
+      'OneFactor': THREE.OneFactor,
+      'SrcAlphaFactor': THREE.SrcAlphaFactor,
+      'OneMinusSrcAlphaFactor': THREE.OneMinusSrcAlphaFactor,
+      'DstAlphaFactor': THREE.DstAlphaFactor,
+      'OneMinusDstAlphaFactor': THREE.OneMinusDstAlphaFactor,      
+      'DstColorFactor': THREE.DstColorFactor,
+      'OneMinusDstColorFactor': THREE.OneMinusDstColorFactor,
+      'SrcAlphaSaturateFactor': THREE.SrcAlphaSaturateFactor
+    },
+    'blendDst': {
+      'ZeroFactor': THREE.ZeroFactor,
+      'OneFactor': THREE.OneFactor,
+      'SrcColorFactor': THREE.SrcColorFactor,
+      'OneMinusSrcColorFactor': THREE.OneMinusSrcColorFactor,
+      'SrcAlphaFactor': THREE.SrcAlphaFactor,
+      'OneMinusSrcAlphaFactor': THREE.OneMinusSrcAlphaFactor,
+      'DstAlphaFactor': THREE.DstAlphaFactor,
+      'OneMinusDstAlphaFactor': THREE.OneMinusDstAlphaFactor
+    },
+    'blendEquation': {
+      'AddEquation': THREE.AddEquation,
+      'SubtractEquation': THREE.SubtractEquation,
+      'ReverseSubtractEquation': THREE.ReverseSubtractEquation
+    },
+    'wrapS': {
+      'RepeatWrapping': THREE.RepeatWrapping,
+      'ClampToEdgeWrapping': THREE.ClampToEdgeWrapping,
+      'MirroredRepeatWrapping': THREE.MirroredRepeatWrapping,
+    },
+    'wrapT': {
+      'RepeatWrapping': THREE.RepeatWrapping,
+      'ClampToEdgeWrapping': THREE.ClampToEdgeWrapping,
+      'MirroredRepeatWrapping': THREE.MirroredRepeatWrapping,
+    },
+    'magFilter': {
+      'NearestFilter': THREE.NearestFilter,
+      'NearestMipMapNearestFilter': THREE.NearestMipMapNearestFilter,
+      'NearestMipMapLinearFilter': THREE.NearestMipMapLinearFilter,
+      'LinearFilter': THREE.LinearFilter,
+      'LinearMipMapNearestFilter': THREE.LinearMipMapNearestFilter,
+      'LinearMipMapLinearFilter': THREE.LinearMipMapLinearFilter,
+    },
+    'minFilter': {
+      'NearestFilter': THREE.NearestFilter,
+      'NearestMipMapNearestFilter': THREE.NearestMipMapNearestFilter,
+      'NearestMipMapLinearFilter': THREE.NearestMipMapLinearFilter,
+      'LinearFilter': THREE.LinearFilter,
+      'LinearMipMapNearestFilter': THREE.LinearMipMapNearestFilter,
+      'LinearMipMapLinearFilter': THREE.LinearMipMapLinearFilter,
+    },
+    'type': {
+      'UnsignedByteType': THREE.UnsignedByteType,
+      'ByteType': THREE.ByteType,
+      'ShortType': THREE.ShortType,
+      'UnsignedShortType': THREE.UnsignedShortType,
+      'IntType': THREE.IntType,
+      'UnsignedIntType': THREE.UnsignedIntType,
+      'FloatType': THREE.FloatType
+    },
+    'format': {
+      'AlphaFormat': THREE.AlphaFormat,
+      'RGBFormat': THREE.RGBFormat,
+      'RGBAFormat': THREE.RGBAFormat,
+      'LuminanceFormat': THREE.LuminanceFormat,
+      'LuminanceAlphaFormat': THREE.LuminanceAlphaFormat,
+      'RGB_S3TC_DXT1_Format': THREE.RGB_S3TC_DXT1_Format,
+      'RGBA_S3TC_DXT1_Format': THREE.RGBA_S3TC_DXT1_Format,
+      'RGBA_S3TC_DXT3_Format': THREE.RGBA_S3TC_DXT3_Format,
+      'RGBA_S3TC_DXT5_Format': THREE.RGBA_S3TC_DXT5_Format,
+      'RGB_PVRTC_4BPPV1_Format': THREE.RGB_PVRTC_4BPPV1_Format,
+      'RGB_PVRTC_2BPPV1_Format': THREE.RGB_PVRTC_2BPPV1_Format,
+      'RGBA_PVRTC_4BPPV1_Format': THREE.RGBA_PVRTC_4BPPV1_Format,
+      'RGBA_PVRTC_2BPPV1_Format': THREE.RGBA_PVRTC_2BPPV1_Format,
+    }
+  }
 
   var container = new UI.Panel();
 
-  var group1 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' );
-  var group2 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ).setOpacity( 0.5 );
-  var group3 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ).setOpacity( 0.25 );//.setDisplay( 'none' ); 
+  var group1 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ).setBackgroundColor( '#ddd' ); // Primary parameters
+  var group2 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ); // Secondary params 
+  var group3 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ).setBackgroundColor( '#ddd' ).setOpacity( 0.25 );//.setDisplay( 'none' ); // everything else
 
   container.add( group1, group2, group3 );
 
   signals.objectChanged.add( function ( changed ) {
       
-    if ( object === changed ) updateUI();
+    if ( model === changed ) updateUI();
 
   } );
 
   signals.selected.add( function ( selected ) {
       
     var selected = editor.listSelected();
-    object = ( selected.length ) ? selected[0] : null;
-
-    createUI();
-    updateUI();
+    var firstSelected = ( selected.length ) ? selected[0] : null;
+    createUI( firstSelected );
 
   } );
 
-  function createUI() {
+  function createUI( newModel ) {
+
+    model = newModel;
 
     param = {};
 
@@ -100,34 +147,106 @@ Sidebar.Attributes = function ( signals ) {
     while ( group2.dom.hasChildNodes() ) group2.dom.removeChild( group2.dom.lastChild );
     while ( group3.dom.hasChildNodes() ) group3.dom.removeChild( group3.dom.lastChild );
 
-    if ( object ) {
-
+    if ( model ) {
       for ( var i in primaryParams ) addElement( primaryParams[i], group1 );
-
       for ( var i in secondaryParams ) addElement( secondaryParams[i], group2 );
-
-      for ( var key in object ) addElement( key, group3 );
-
+      for ( var key in model ) addElement( key, group3 );
     }
 
+    updateUI();
 
   }
 
   function addElement( key, parent ) {
 
-    if ( object[ key ] !== undefined && param[ key ] === undefined ) {
+    if ( model[ key ] !== undefined && param[ key ] === undefined ) {
+
+      // Params from multiOptions
+
+      for ( var i in multiOptions ) {
+        if ( i == key ) {
+          param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
+          parent.add( param[ key ] );
+          return;
+        }
+      }
+
+      // Special params
+
+      if ( key === 'parent' ) {
+
+        param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
+        param[ key ].name.setColor( '#0080f0' ).onClick( function(){ createUI( editor.objects[ param[ key ].getValue() ] ) } );
+        parent.add( param[ key ] );
+        return;
+
+      }
+
+      if ( key === 'geometry' ) {
+
+        param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
+        param[ key ].name.setColor( '#0080f0' ).onClick( function(){  createUI( editor.geometries[ param[ key ].getValue() ] ) } );
+        parent.add( param[ key ] );
+        return;
+
+      }
+
+      if ( key == 'material' ) {
+
+        param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
+        param[ key ].name.setColor( '#0080f0' ).onClick( function(){  createUI( editor.materials[ param[ key ].getValue() ] ) } );
+        parent.add( param[ key ] );
+        return;
+
+      }
+
+      if ( key == 'userData' ) {
+
+        param[ key ] = new UI.ParamJson( key ).onChange( updateParam );
+        parent.add( param[ key ] );
+        return;
+
+      }
+
+      // Texture params
+
+      for ( var i in textureParams ) {
+
+        if ( key == textureParams[ i ] ) {
+
+          param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
+          param[ key ].name.setColor( '#0080f0' ).onClick( function(){
+
+            var value = param[ key ].getValue();
+            if ( value == 'new' ) {
+
+              var texture = editor.createTexture();
+              model[ key ] = texture;
+              createUI( texture );
+
+            } else createUI( editor.textures[ value ] )
 
-      if ( typeof object[ key ] === 'string' ) {
+          } );
+          parent.add( param[ key ] );
+          return;
+
+        }
+        
+      }
+
+      // Params by type
+
+      if ( typeof model[ key ] === 'string' ) {
 
         param[ key ] = new UI.ParamString( key ).onChange( updateParam );
         parent.add( param[ key ] );
 
-      } else if ( typeof object[ key ] === 'boolean' ) {
+      } else if ( typeof model[ key ] === 'boolean' ) {
 
         param[ key ] = new UI.ParamBool( key ).onChange( updateParam );
         parent.add( param[ key ] );
 
-      } else if ( typeof object[ key ] === 'number' ) {
+      } else if ( typeof model[ key ] === 'number' ) {
 
         if ( integerParams.indexOf( key ) != -1 )
           param[ key ] = new UI.ParamInteger( key ).onChange( updateParam );
@@ -137,39 +256,39 @@ Sidebar.Attributes = function ( signals ) {
         
         parent.add( param[ key ] );
 
-      } else if ( object[ key ] instanceof THREE.Vector3 ) {
+      } else if ( model[ key ] instanceof THREE.Vector2 ) {
 
-        var hasLock = ( key === 'scale' ) ? true : false;
-        param[ key ] = new UI.ParamVector3( key, hasLock ).onChange( updateParam );
+        param[ key ] = new UI.ParamVector2( key ).onChange( updateParam );
         parent.add( param[ key ] );
 
-      } else if ( object[ key ] instanceof THREE.Color ) {
+      } else if ( model[ key ] instanceof THREE.Vector3 ) {
 
-        param[ key ] = new UI.ParamColor( key ).onChange( updateParam );
+        param[ key ] = new UI.ParamVector3( key ).onChange( updateParam );
         parent.add( param[ key ] );
 
-      } else if ( key === 'parent' ) {
+      } else if ( model[ key ] instanceof THREE.Vector4 || model[ key ] instanceof THREE.Quaternion ) {
 
-        param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
-        param[ key ].name.setColor( '#0080f0' ).onClick( function(){  editor.select( editor.objects[ param[ key ].getValue() ] ) } );
+        param[ key ] = new UI.ParamVector4( key ).onChange( updateParam );
         parent.add( param[ key ] );
 
-      } else if ( key === 'geometry' ) {
+      } else if ( model[ key ] instanceof THREE.Color ) {
 
-        param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
-        param[ key ].name.setColor( '#0080f0' ).onClick( function(){  editor.select( editor.geometries[ param[ key ].getValue() ] ) } );
+        param[ key ] = new UI.ParamColor( key ).onChange( updateParam );
         parent.add( param[ key ] );
 
-      } else if ( key == 'material' ) {
+      } else if ( model[ key ] instanceof Array ) {
 
-        param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
-        param[ key ].name.setColor( '#0080f0' ).onClick( function(){  editor.select( editor.materials[ param[ key ].getValue() ] ) } );
-        parent.add( param[ key ] );
+        if ( model[ key ].length ) {
 
-      } else if ( key == 'userData' ) {
+          param[ key ] = new UI.Text( key ).setColor( '#0080f0' ).onClick( function(){  createUI( model[ key ] ) } );
+          parent.add( param[ key ], new UI.Break() );
+          
+        }
 
-        param[ key ] = new UI.ParamJson( key ).onChange( updateParam );
-        parent.add( param[ key ] );
+      } else if ( typeof model[ key ] !== 'function' ) {
+
+        param[ key ] = new UI.Text( key ).setColor( '#0080f0' ).onClick( function(){  createUI( model[ key ] ) } );
+        parent.add( param[ key ], new UI.Break() );
 
       }
 
@@ -179,46 +298,56 @@ Sidebar.Attributes = function ( signals ) {
 
   function updateUI() {
 
-    if ( object ) {
+    if ( model ) {
 
-      for ( var key in object ) {
+      for ( var key in model ) {
 
-        if ( typeof object[ key ] === 'string' ) param[ key ].setValue( object[ key ] );
+        // Params from multiOptions
 
-        else if ( typeof object[ key ] === 'boolean' ) param[ key ].setValue( object[ key ] );
+        for ( var i in multiOptions ) {
+          if ( i == key ) {
+            for ( var j in multiOptions[ i ] ) {
 
-        else if ( typeof object[ key ] === 'number' ) param[ key ].setValue( object[ key ] );
+              var options = {};
 
-        else if ( object[ key ] instanceof THREE.Vector3 ) param[ key ].setValue( object[ key ] );
+              for ( var j in multiOptions[ i ] ) options[ multiOptions[ i ][ j ] ] = j;
+              
+              param[ key ].setOptions( options );
+              param[ key ].setValue( model[ key ] );
+              break;
 
-        else if ( object[ key ] instanceof THREE.Color ) param[ key ].setValue( object[ key ] );
+            }
+          }
+        }
 
-        else if ( object[ key ] && key === 'parent' ) {
+        // Special params
+
+        if ( key === 'parent' ) {
 
           var options = {};
-          for ( var id in editor.objects ) if ( object.id != id ) options[ id ] = editor.objects[ id ].name;
+          for ( var id in editor.objects ) if ( model.id != id ) options[ id ] = editor.objects[ id ].name;
           param[ key ].setOptions( options );
-          if ( object.parent !== undefined ) param[ key ].setValue( object.parent.id );
+          if ( model[ key ] !== undefined ) param[ key ].setValue( model[ key ].id );
 
-        } else if ( object[ key ] && key === 'geometry' ) {
+        } else if ( key === 'geometry' ) {
 
           var options = {};
-          for ( var id in editor.geometries ) if ( object.id != id ) options[ id ] = editor.geometries[ id ].name;
+          for ( var id in editor.geometries ) options[ id ] = editor.geometries[ id ].name;
           param[ key ].setOptions( options );
-          if ( object.geometry !== undefined ) param[ key ].setValue( object.geometry.id );
+          if ( model[ key ] !== undefined ) param[ key ].setValue( model[ key ].id );
 
-        } else if ( object[ key ] && key === 'material' ) {
+        } else if ( key === 'material' ) {
 
           var options = {};
-          for ( var id in editor.materials ) if ( object.id != id ) options[ id ] = editor.materials[ id ].name;
+          for ( var id in editor.materials ) options[ id ] = editor.materials[ id ].name;
           param[ key ].setOptions( options );
-          if ( object.material !== undefined ) param[ key ].setValue( object.material.id );
+          if ( model[ key ] !== undefined ) param[ key ].setValue( model[ key ].id );
 
         } else if ( key == 'userData' ) {
 
           try {
 
-            param[ key ].setValue( JSON.stringify( object.userData, null, '  ' ) );
+            param[ key ].setValue( JSON.stringify( model.userData, null, '  ' ) );
 
           } catch ( error ) {
 
@@ -226,70 +355,99 @@ Sidebar.Attributes = function ( signals ) {
 
           }
 
-        }
+        // Texture params
 
-      }
+        } else if ( textureParams.indexOf( key ) != -1 ) {
 
-    }
+          var options = {};
+          options[ 'new' ] = 'New texture';
+          for ( var id in editor.textures ) options[ id ] = editor.textures[ id ].name;
+          param[ key ].setOptions( options );
 
-  }
+          param[ key ].setValue( 'new' );
+          if ( model[ key ] ) param[ key ].setValue( model[ key ].id );
 
-  function updateParam( event ) {
+        } 
 
-    var key = event.srcElement.name;
+        // Params by type
 
-    if ( typeof object[ key ] === 'string' ) object[ key ] = param[ key ].getValue();
+        else if ( typeof model[ key ] === 'string' ) param[ key ].setValue( model[ key ] );
 
-    else if ( typeof object[ key ] === 'boolean' ) object[ key ] = param[ key ].getValue();
+        else if ( typeof model[ key ] === 'boolean' ) param[ key ].setValue( model[ key ] );
 
-    else if ( typeof object[ key ] === 'number' ) object[ key ] = param[ key ].getValue();
+        else if ( typeof model[ key ] === 'number' ) param[ key ].setValue( model[ key ] );
 
-    else if ( object[ key ] instanceof THREE.Color ) object[ key ].setHex( param[ key ].getValue() );
+        else if ( model[ key ] instanceof THREE.Vector3 ) param[ key ].setValue( model[ key ] );
 
-    else if ( object[ key ] instanceof THREE.Vector3 ) object[ key ].copy( param[ key ].getValue() );
+        else if ( model[ key ] instanceof THREE.Color ) param[ key ].setValue( model[ key ] );
 
-    else if ( key === 'parent' ) {
+      }
 
-      if ( param[ key ].getValue() != object.id )
-        editor.parent( object, editor.objects[ param[ key ].getValue() ] );
+    }
 
-    } else if ( key === 'geometry' ) {
+  }
 
-      if ( param[ key ].getValue() != object.geometry.id )
-        object.geometry = editor.geometries[ param[ key ].getValue() ];
+  function updateParam( event ) {
 
-    } else if ( key === 'material' ) {
+    var key = event.srcElement.name;
+    var value = ( param[ key ].getValue ) ? param[ key ].getValue() : null;
 
-      if ( param[ key ].getValue() != object.material.id )
-        object.material = editor.materials[ param[ key ].getValue() ];
+    // Special params
 
-    } else if ( key === 'userData' ) {
+    if ( key === 'parent' ) editor.parent( object, editor.objects[ value ] );
 
-      try {
+    else if ( key === 'geometry' ) model[ key ] = editor.geometries[ value ];
 
-        object.userData = JSON.parse( param[ key ].getValue() );
+    else if ( key === 'material' ) model[ key ] = editor.materials[ value ];
 
+    else if ( key === 'userData' ) {
+    
+      try {
+         model[ key ] = JSON.parse( value );
       } catch ( error ) {
-
         console.log( error );
-
       }
+    
+    } else if ( textureParams.indexOf( key ) != -1 ) {
+      
+      if ( value == 'new' ) {
+
+        var texture = editor.createTexture();
+        model[ key ] = texture;
+        createUI( texture );
+
+      } else model[ key ] = editor.textures[ value ];
 
     }
 
-    if ( object instanceof THREE.Object3D ) {
+    // Params by type
+
+    else if ( typeof model[ key ] === 'string' ) model[ key ] = value;
+
+    else if ( typeof model[ key ] === 'boolean' ) model[ key ] = value;
+
+    else if ( typeof model[ key ] === 'number' ) model[ key ] = parseFloat( value );
+
+    else if ( model[ key ] instanceof THREE.Color ) model[ key ].setHex( value );
+
+    else if ( model[ key ] instanceof THREE.Vector3 ) model[ key ].copy( value );
+
+    // Post actions
+
+    if ( model instanceof THREE.Object3D ) {
 
-      signals.objectChanged.dispatch( object );
+      signals.objectChanged.dispatch( model );
 
-    } else if ( object instanceof THREE.Geometry ) {
+    } else if ( model instanceof THREE.Geometry ) {
 
       var geoParams = {};
-      for ( var i in param ) geoParams[ i ] = param[ i ].getValue();
-      editor.updateGeometry( object, geoParams );
+      for ( var i in param )
+        if ( param[ i ].getValue ) geoParams[ i ] = param[ i ].getValue();
+      editor.updateGeometry( model, geoParams );
 
-    } else if ( object instanceof THREE.Material ) {
+    } else if ( model instanceof THREE.Material ) {
 
-      signals.materialChanged.dispatch( object );
+      signals.materialChanged.dispatch( model );
 
     }
 

+ 0 - 46
editor/js/Sidebar.Outliner.Scene.js

@@ -24,42 +24,6 @@ Sidebar.Outliner.Scene = function ( signals ) {
 	fogTypeRow.add( fogType );
 	container.add( fogTypeRow );
 
-	var fogColorRow = new UI.Panel();
-	fogColorRow.setDisplay( 'none' );
-	var fogColor = new UI.Color().setValue( '#aaaaaa' ).onChange(
-		function() { editor.setFog( { color: fogColor.getHexValue() } ) }
-	);
-	fogColorRow.add( new UI.Text( 'Fog color' ).setWidth( '90px' ).setColor( '#666' ) );
-	fogColorRow.add( fogColor );
-	container.add( fogColorRow );
-
-	var fogNearRow = new UI.Panel();
-	fogNearRow.setDisplay( 'none' );
-	var fogNear = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, Infinity ).onChange(
-		function() { editor.setFog( { near: fogNear.getValue() } ) }
-	);
-	fogNearRow.add( new UI.Text( 'Fog near' ).setWidth( '90px' ).setColor( '#666' ) );
-	fogNearRow.add( fogNear );
-	container.add( fogNearRow );
-
-	var fogFarRow = new UI.Panel();
-	fogFarRow.setDisplay( 'none' );
-	var fogFar = new UI.Number( 5000 ).setWidth( '60px' ).setRange( 0, Infinity ).onChange(
-		function() { editor.setFog( { far: fogFar.getValue() } ) }
-	);
-	fogFarRow.add( new UI.Text( 'Fog far' ).setWidth( '90px' ).setColor( '#666' ) );
-	fogFarRow.add( fogFar );
-	container.add( fogFarRow );
-
-	var fogDensityRow = new UI.Panel();
-	fogDensityRow.setDisplay( 'none' );
-	var fogDensity = new UI.Number( 0.00025 ).setWidth( '60px' ).setRange( 0, 0.1 ).setPrecision( 5 ).onChange(
-		function() { editor.setFog( { density: fogDensity.getValue() } ) }
-	);
-	fogDensityRow.add( new UI.Text( 'Fog density' ).setWidth( '90px' ).setColor( '#666' ) );
-	fogDensityRow.add( fogDensity );
-	container.add( fogDensityRow );
-
 	//
 
 	var scene = null;
@@ -144,18 +108,13 @@ Sidebar.Outliner.Scene = function ( signals ) {
 
 		if ( scene.fog ) {
 
-			fogColor.setHexValue( scene.fog.color.getHex() );
-
 			if ( scene.fog instanceof THREE.Fog ) {
 
 				fogType.setValue( "Fog" );
-				fogNear.setValue( scene.fog.near );
-				fogFar.setValue( scene.fog.far );
 
 			} else if ( scene.fog instanceof THREE.FogExp2 ) {
 
 				fogType.setValue( "FogExp2" );
-				fogDensity.setValue( scene.fog.density );
 
 			}
 
@@ -167,11 +126,6 @@ Sidebar.Outliner.Scene = function ( signals ) {
 
 		var type = fogType.getValue();
 
-		fogColorRow.setDisplay( type === 'None' ? 'none' : '' );
-		fogNearRow.setDisplay( type === 'Fog' ? '' : 'none' );
-		fogFarRow.setDisplay( type === 'Fog' ? '' : 'none' );
-		fogDensityRow.setDisplay( type === 'FogExp2' ? '' : 'none' );
-
 	}
 
 	// events

+ 3 - 1
editor/js/libs/ui.js

@@ -43,7 +43,7 @@ UI.Element.prototype = {
 // properties
 
 var properties = [ 'position', 'left', 'top', 'right', 'bottom', 'width', 'height', 'border', 'borderLeft',
-'borderTop', 'borderRight', 'borderBottom', 'borderColor', 'display', 'overflow', 'margin', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'padding', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'color',
+'borderTop', 'borderRight', 'borderBottom', 'borderColor', 'boxSizing', 'display', 'overflow', 'margin', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'padding', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'color',
 'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textTransform', 'cursor' ];
 
 properties.forEach( function ( property ) {
@@ -199,6 +199,7 @@ UI.Text = function ( text ) {
 	dom.style.cursor = 'default';
 	dom.style.display = 'inline-block';
 	dom.style.verticalAlign = 'top';
+	dom.style.overflow = 'hidden';
 
 	this.dom = dom;
 	this.setValue( text );
@@ -233,6 +234,7 @@ UI.Input = function () {
 	var dom = document.createElement( 'input' );
 	dom.className = 'Input';
 	dom.style.padding = '2px';
+	// dom.style.boxSizing = 'border-box';
 	dom.style.marginTop = '-2px';
 	dom.style.marginLeft = '-2px';
 	dom.style.border = '1px solid #ccc';

+ 145 - 50
editor/js/libs/ui.three.js

@@ -22,9 +22,9 @@ UI.ParamString = function ( name ) {
 UI.ParamString.prototype = Object.create( UI.Panel.prototype );
 
 
-UI.ParamString.prototype.setValue = function ( value ) {
+UI.ParamString.prototype.setValue = function ( model ) {
 
-	this.string.setValue( value );
+	this.string.setValue( model );
 
 };
 
@@ -58,9 +58,9 @@ UI.ParamInteger = function ( name ) {
 
 UI.ParamInteger.prototype = Object.create( UI.Panel.prototype );
 
-UI.ParamInteger.prototype.setValue = function ( value ) {
+UI.ParamInteger.prototype.setValue = function ( model ) {
 
-	this.integer.setValue( value );
+	this.integer.setValue( model );
 
 };
 
@@ -93,9 +93,9 @@ UI.ParamFloat = function ( name ) {
 
 UI.ParamFloat.prototype = Object.create( UI.Panel.prototype );
 
-UI.ParamFloat.prototype.setValue = function ( value ) {
+UI.ParamFloat.prototype.setValue = function ( model ) {
 
-	this.float.setValue( value );
+	this.float.setValue( model );
 
 };
 
@@ -115,7 +115,7 @@ UI.ParamBool = function ( name ) {
 
 	var row = new UI.Panel();
 
-	this.name = new UI.Text( name ).setWidth( '90px' ).setColor( '#666' ).setPosition( 'relative' ).setLeft( '25px' );
+	this.name = new UI.Text( name ).setWidth( 'auto' ).setColor( '#666' ).setPosition( 'relative' ).setLeft( '25px' );
 	this.bool = new UI.Checkbox().setPosition( 'absolute' ).setLeft( '10px' );
 	this.bool.dom.name = name;
 
@@ -128,9 +128,9 @@ UI.ParamBool = function ( name ) {
 
 UI.ParamBool.prototype = Object.create( UI.Panel.prototype );
 
-UI.ParamBool.prototype.setValue = function ( value ) {
+UI.ParamBool.prototype.setValue = function ( model ) {
 
-	this.bool.setValue( value );
+	this.bool.setValue( model );
 
 };
 
@@ -141,69 +141,167 @@ UI.ParamBool.prototype.getValue = function () {
 
 };
 
-// Vector3
+// Vector2
 
-UI.ParamVector3 = function ( name, scaleLock ) {
+UI.ParamVector2 = function ( name ) {
 
   UI.Panel.call( this );
 
-  scaleLock = scaleLock ? scaleLock : false;
-
 	var scope = this;
 
 	var row = new UI.Panel();
 
 	this.name = new UI.Text( name ).setWidth( '90px' ).setColor( '#666' );
 
-	this.x = new UI.Number().setWidth( '50px' ).onChange( setYZ );
-	this.y = new UI.Number().setWidth( '50px' ).onChange( setXZ );
-	this.z = new UI.Number().setWidth( '50px' ).onChange( setXY );
+	this.x = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.y ] ) } );
+	this.y = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.x ] ) } );
+
 	this.x.dom.name = name;
 	this.y.dom.name = name;
-	this.z.dom.name = name;
 	
-	row.add( this.name, this.x, this.y, this.z );
-
-	if ( scaleLock ) {
+	row.add( this.name, this.x, this.y );
 	
-		this.scaleLock = new UI.Checkbox().setPosition( 'absolute' ).setLeft( '75px' );
-		row.add( this.scaleLock );
-
-	}
+	this.scaleLock = new UI.Checkbox().setPosition( 'absolute' ).setRight( '10px' );
+	row.add( this.scaleLock );
 
 	this.add( row );
 
-	function setYZ( event ) {
+	function scaleProportionately( event, targets ) {
 
 		if ( scope.scaleLock && scope.scaleLock.getValue() && event.srcElement.oldValue ) {
 
 			var scale = event.srcElement.value / event.srcElement.oldValue;
-			scope.y.setValue( parseFloat(scope.y.getValue()) * scale );
-			scope.z.setValue( parseFloat(scope.z.getValue()) * scale );
+			for ( var i in targets ) {
+
+				targets[ i ].setValue( parseFloat(targets[ i ].getValue()) * scale );
+			
+			}
 
 		}
 
 	}
 
-	function setXZ( event ) {
+	return this;
+
+};
+
+UI.ParamVector2.prototype = Object.create( UI.Panel.prototype );
+
+UI.ParamVector2.prototype.setValue = function ( model ) {
+
+	this.x.setValue( model.x );
+	this.y.setValue( model.y );
+
+};
+
+UI.ParamVector2.prototype.getValue = function () {
+
+	return new THREE.Vector2( this.x.getValue(), this.y.getValue() );
+
+};
+
+// Vector3
+
+UI.ParamVector3 = function ( name ) {
+
+  UI.Panel.call( this );
+
+	var scope = this;
+
+	var row = new UI.Panel();
+
+	this.name = new UI.Text( name ).setWidth( '90px' ).setColor( '#666' );
+
+	this.x = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.y, scope.z ] ) } );
+	this.y = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.x, scope.z ] ) } );
+	this.z = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.x, scope.y ] ) } );
+
+	this.x.dom.name = name;
+	this.y.dom.name = name;
+	this.z.dom.name = name;
+	
+	row.add( this.name, this.x, this.y, this.z );
+	
+	this.scaleLock = new UI.Checkbox().setPosition( 'absolute' ).setRight( '10px' );
+	row.add( this.scaleLock );
+
+
+	this.add( row );
+
+	function scaleProportionately( event, targets ) {
 
 		if ( scope.scaleLock && scope.scaleLock.getValue() && event.srcElement.oldValue ) {
 
 			var scale = event.srcElement.value / event.srcElement.oldValue;
-			scope.x.setValue( parseFloat(scope.x.getValue()) * scale );
-			scope.z.setValue( parseFloat(scope.z.getValue()) * scale );
+			for ( var i in targets ) {
+
+				targets[ i ].setValue( parseFloat(targets[ i ].getValue()) * scale );
+			
+			}
 
 		}
 
 	}
 
-	function setXY( event ) {
+	return this;
+
+};
+
+UI.ParamVector3.prototype = Object.create( UI.Panel.prototype );
+
+UI.ParamVector3.prototype.setValue = function ( model ) {
+
+	this.x.setValue( model.x );
+	this.y.setValue( model.y );
+	this.z.setValue( model.z );
+
+};
+
+UI.ParamVector3.prototype.getValue = function () {
+
+	return new THREE.Vector3( this.x.getValue(), this.y.getValue(), this.z.getValue() );
+
+};
+
+// Vector4
+
+UI.ParamVector4 = function ( name ) {
+
+  UI.Panel.call( this );
+
+	var scope = this;
+
+	var row = new UI.Panel();
+
+	this.name = new UI.Text( name ).setWidth( '90px' ).setColor( '#666' );
+
+	this.x = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.y, scope.z, scope.w ] ) } );
+	this.y = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.x, scope.z, scope.w ] ) } );
+	this.z = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.x, scope.y, scope.w ] ) } );
+	this.w = new UI.Number().setWidth( '35px' ).onChange( function( event ) { scaleProportionately( event, [ scope.x, scope.y, scope.z ] ) } );
+
+	this.x.dom.name = name;
+	this.y.dom.name = name;
+	this.z.dom.name = name;
+	this.w.dom.name = name;
+	
+	row.add( this.name, this.x, this.y, this.z, this.w );
+
+	this.scaleLock = new UI.Checkbox().setPosition( 'absolute' ).setRight( '10px' );
+	row.add( this.scaleLock );
+
+	this.add( row );
+
+	function scaleProportionately( event, targets ) {
 
 		if ( scope.scaleLock && scope.scaleLock.getValue() && event.srcElement.oldValue ) {
 
 			var scale = event.srcElement.value / event.srcElement.oldValue;
-			scope.x.setValue( parseFloat(scope.x.getValue()) * scale );
-			scope.y.setValue( parseFloat(scope.y.getValue()) * scale );
+			for ( var i in targets ) {
+
+				targets[ i ].setValue( parseFloat(targets[ i ].getValue()) * scale );
+			
+			}
 
 		}
 
@@ -213,20 +311,20 @@ UI.ParamVector3 = function ( name, scaleLock ) {
 
 };
 
-UI.ParamVector3.prototype = Object.create( UI.Panel.prototype );
+UI.ParamVector4.prototype = Object.create( UI.Panel.prototype );
 
-UI.ParamVector3.prototype.setValue = function ( value ) {
+UI.ParamVector4.prototype.setValue = function ( model ) {
 
-	this.x.setValue( value.x );
-	this.y.setValue( value.y );
-	this.z.setValue( value.z );
+	this.x.setValue( model.x );
+	this.y.setValue( model.y );
+	this.z.setValue( model.z );
+	this.w.setValue( model.w );
 
 };
 
+UI.ParamVector4.prototype.getValue = function () {
 
-UI.ParamVector3.prototype.getValue = function () {
-
-	return new THREE.Vector3( this.x.getValue(), this.y.getValue(), this.z.getValue() );
+	return new THREE.Vector4( this.x.getValue(), this.y.getValue(), this.z.getValue(), this.w.getValue() );
 
 };
 
@@ -259,7 +357,6 @@ UI.ParamColor.prototype.setValue = function ( color ) {
 
 };
 
-
 UI.ParamColor.prototype.getValue = function () {
 
 	return this.color.getHexValue();
@@ -291,13 +388,12 @@ UI.ParamSelect = function ( name ) {
 
 UI.ParamSelect.prototype = Object.create( UI.Panel.prototype );
 
-UI.ParamSelect.prototype.setValue = function ( value ) {
+UI.ParamSelect.prototype.setValue = function ( model ) {
 
-	this.select.setValue( value );
+	this.select.setValue( model );
 
 };
 
-
 UI.ParamSelect.prototype.getValue = function ( value ) {
 
 	return this.select.getValue( value );
@@ -394,7 +490,7 @@ UI.Texture.prototype.getValue = function () {
 
 };
 
-UI.Texture.prototype.setValue = function ( value ) {
+UI.Texture.prototype.setValue = function ( model ) {
 
 	this.texture = value;
 
@@ -463,7 +559,7 @@ UI.CubeTexture.prototype.getValue = function () {
 
 };
 
-UI.CubeTexture.prototype.setValue = function ( value ) {
+UI.CubeTexture.prototype.setValue = function ( model ) {
 
 	this.texture = value;
 
@@ -510,13 +606,12 @@ UI.ParamJson = function ( name ) {
 
 UI.ParamJson.prototype = Object.create( UI.Panel.prototype );
 
-UI.ParamJson.prototype.setValue = function ( value ) {
+UI.ParamJson.prototype.setValue = function ( model ) {
 
-	this.json.setValue( value );
+	this.json.setValue( model );
 
 };
 
-
 UI.ParamJson.prototype.getValue = function () {
 
 	return this.json.getValue();