Sidebar.Attributes.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. Sidebar.Attributes = function ( signals ) {
  2. var scope = this;
  3. var model;
  4. var param = {};
  5. var primaryParams = [ 'name', 'parent', 'geometry', 'material', 'position', 'rotation', 'scale', 'width', 'height', 'depth',
  6. 'widthSegments', 'heightSegments', 'depthSegments', 'radialSegments', 'tubularSegments', 'radius', 'radiusTop', 'radiusBottom',
  7. 'phiStart', 'phiLength', 'thetaStart', 'thetaLength', 'tube', 'arc', 'detail', 'p', 'q', 'heightScale', 'openEnded',
  8. 'image', 'sourceFile', 'wrapS', 'wrapT', 'minFilter', 'magFilter', 'format', 'repeat', 'offset', 'flipY', 'type', 'color',
  9. 'groundColor', 'ambient', 'emissive', 'specular', 'reflectivity', 'shininess', 'intensity', 'opacity', 'transparent', 'metal',
  10. 'wireframe', 'wireframeLinewidth', 'linewidth', 'visible', 'fog', 'near', 'far', 'exponent', 'map', 'lightMap', 'bumpMap',
  11. 'normalMap', 'specularMap', 'envMap', 'normalScale', 'bumpScale', 'userData' ];
  12. var secondaryParams = [ 'quaternion', 'up', 'distance', 'castShadow', 'receiveShadow', 'useQuaternion', 'depthTest', 'depthWrite',
  13. 'dynamic', 'children', 'elements', 'vertices', 'normals', 'colors', 'faces', 'faceUvs', 'faceVertexUvs', 'boundingBox',
  14. 'boundingSphere', 'verticesNeedUpdate', 'elementsNeedUpdate', 'uvsNeedUpdate', 'normalsNeedUpdate', 'tangentsNeedUpdate',
  15. 'colorsNeedUpdate', 'lineDistancesNeedUpdate', 'buffersNeedUpdate', 'matrix', 'matrixWorld', 'blending', 'side', 'blendSrc',
  16. 'blendDst', 'blendEquation', 'generateMipmaps', 'premultiplyAlpha', 'needsUpdate', 'anisothropy' ];
  17. var integerParams = [ 'widthSegments', 'heightSegments', 'depthSegments', 'radialSegments', 'tubularSegments' ];
  18. var textureParams = [ 'map', 'lightMap', 'bumpMap', 'normalMap', 'specularMap', 'envMap' ];
  19. var multiOptions = {
  20. 'blending': {
  21. 'NoBlending': THREE.NoBlending,
  22. 'NormalBlending': THREE.NormalBlending,
  23. 'AdditiveBlending': THREE.AdditiveBlending,
  24. 'SubtractiveBlending': THREE.SubtractiveBlending,
  25. 'MultiplyBlending': THREE.MultiplyBlending,
  26. 'CustomBlending': THREE.CustomBlending
  27. }
  28. ,
  29. 'side': {
  30. 'FrontSide': THREE.FrontSide,
  31. 'BackSide': THREE.BackSide,
  32. 'DoubleSide': THREE.DoubleSide
  33. },
  34. 'blendSrc': {
  35. 'ZeroFactor': THREE.ZeroFactor,
  36. 'OneFactor': THREE.OneFactor,
  37. 'SrcAlphaFactor': THREE.SrcAlphaFactor,
  38. 'OneMinusSrcAlphaFactor': THREE.OneMinusSrcAlphaFactor,
  39. 'DstAlphaFactor': THREE.DstAlphaFactor,
  40. 'OneMinusDstAlphaFactor': THREE.OneMinusDstAlphaFactor,
  41. 'DstColorFactor': THREE.DstColorFactor,
  42. 'OneMinusDstColorFactor': THREE.OneMinusDstColorFactor,
  43. 'SrcAlphaSaturateFactor': THREE.SrcAlphaSaturateFactor
  44. },
  45. 'blendDst': {
  46. 'ZeroFactor': THREE.ZeroFactor,
  47. 'OneFactor': THREE.OneFactor,
  48. 'SrcColorFactor': THREE.SrcColorFactor,
  49. 'OneMinusSrcColorFactor': THREE.OneMinusSrcColorFactor,
  50. 'SrcAlphaFactor': THREE.SrcAlphaFactor,
  51. 'OneMinusSrcAlphaFactor': THREE.OneMinusSrcAlphaFactor,
  52. 'DstAlphaFactor': THREE.DstAlphaFactor,
  53. 'OneMinusDstAlphaFactor': THREE.OneMinusDstAlphaFactor
  54. },
  55. 'blendEquation': {
  56. 'AddEquation': THREE.AddEquation,
  57. 'SubtractEquation': THREE.SubtractEquation,
  58. 'ReverseSubtractEquation': THREE.ReverseSubtractEquation
  59. },
  60. 'wrapS': {
  61. 'RepeatWrapping': THREE.RepeatWrapping,
  62. 'ClampToEdgeWrapping': THREE.ClampToEdgeWrapping,
  63. 'MirroredRepeatWrapping': THREE.MirroredRepeatWrapping,
  64. },
  65. 'wrapT': {
  66. 'RepeatWrapping': THREE.RepeatWrapping,
  67. 'ClampToEdgeWrapping': THREE.ClampToEdgeWrapping,
  68. 'MirroredRepeatWrapping': THREE.MirroredRepeatWrapping,
  69. },
  70. 'magFilter': {
  71. 'NearestFilter': THREE.NearestFilter,
  72. 'NearestMipMapNearestFilter': THREE.NearestMipMapNearestFilter,
  73. 'NearestMipMapLinearFilter': THREE.NearestMipMapLinearFilter,
  74. 'LinearFilter': THREE.LinearFilter,
  75. 'LinearMipMapNearestFilter': THREE.LinearMipMapNearestFilter,
  76. 'LinearMipMapLinearFilter': THREE.LinearMipMapLinearFilter,
  77. },
  78. 'minFilter': {
  79. 'NearestFilter': THREE.NearestFilter,
  80. 'NearestMipMapNearestFilter': THREE.NearestMipMapNearestFilter,
  81. 'NearestMipMapLinearFilter': THREE.NearestMipMapLinearFilter,
  82. 'LinearFilter': THREE.LinearFilter,
  83. 'LinearMipMapNearestFilter': THREE.LinearMipMapNearestFilter,
  84. 'LinearMipMapLinearFilter': THREE.LinearMipMapLinearFilter,
  85. },
  86. 'type': {
  87. 'UnsignedByteType': THREE.UnsignedByteType,
  88. 'ByteType': THREE.ByteType,
  89. 'ShortType': THREE.ShortType,
  90. 'UnsignedShortType': THREE.UnsignedShortType,
  91. 'IntType': THREE.IntType,
  92. 'UnsignedIntType': THREE.UnsignedIntType,
  93. 'FloatType': THREE.FloatType
  94. },
  95. 'format': {
  96. 'AlphaFormat': THREE.AlphaFormat,
  97. 'RGBFormat': THREE.RGBFormat,
  98. 'RGBAFormat': THREE.RGBAFormat,
  99. 'LuminanceFormat': THREE.LuminanceFormat,
  100. 'LuminanceAlphaFormat': THREE.LuminanceAlphaFormat,
  101. 'RGB_S3TC_DXT1_Format': THREE.RGB_S3TC_DXT1_Format,
  102. 'RGBA_S3TC_DXT1_Format': THREE.RGBA_S3TC_DXT1_Format,
  103. 'RGBA_S3TC_DXT3_Format': THREE.RGBA_S3TC_DXT3_Format,
  104. 'RGBA_S3TC_DXT5_Format': THREE.RGBA_S3TC_DXT5_Format,
  105. 'RGB_PVRTC_4BPPV1_Format': THREE.RGB_PVRTC_4BPPV1_Format,
  106. 'RGB_PVRTC_2BPPV1_Format': THREE.RGB_PVRTC_2BPPV1_Format,
  107. 'RGBA_PVRTC_4BPPV1_Format': THREE.RGBA_PVRTC_4BPPV1_Format,
  108. 'RGBA_PVRTC_2BPPV1_Format': THREE.RGBA_PVRTC_2BPPV1_Format,
  109. }
  110. }
  111. var container = new UI.Panel();
  112. var group1 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ).setBackgroundColor( '#ddd' ); // Primary parameters
  113. var group2 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ); // Secondary params
  114. var group3 = new UI.Panel().setBorderTop( '1px solid #ccc' ).setPadding( '10px' ).setBackgroundColor( '#ddd' ).setOpacity( 0.25 );//.setDisplay( 'none' ); // everything else
  115. container.add( group1, group2, group3 );
  116. signals.objectChanged.add( function ( changed ) {
  117. if ( model === changed ) updateUI();
  118. } );
  119. signals.selected.add( function ( selected ) {
  120. var selected = editor.listSelected();
  121. var firstSelected = ( selected.length ) ? selected[0] : null;
  122. createUI( firstSelected );
  123. } );
  124. function createUI( newModel ) {
  125. model = newModel;
  126. param = {};
  127. while ( group1.dom.hasChildNodes() ) group1.dom.removeChild( group1.dom.lastChild );
  128. while ( group2.dom.hasChildNodes() ) group2.dom.removeChild( group2.dom.lastChild );
  129. while ( group3.dom.hasChildNodes() ) group3.dom.removeChild( group3.dom.lastChild );
  130. if ( model ) {
  131. for ( var i in primaryParams ) addElement( primaryParams[i], group1 );
  132. for ( var i in secondaryParams ) addElement( secondaryParams[i], group2 );
  133. for ( var key in model ) addElement( key, group3 );
  134. }
  135. updateUI();
  136. }
  137. function addElement( key, parent ) {
  138. if ( model[ key ] !== undefined && param[ key ] === undefined ) {
  139. // Params from multiOptions
  140. for ( var i in multiOptions ) {
  141. if ( i == key ) {
  142. param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
  143. parent.add( param[ key ] );
  144. return;
  145. }
  146. }
  147. // Special params
  148. if ( key === 'parent' ) {
  149. param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
  150. param[ key ].name.setColor( '#0080f0' ).onClick( function(){ createUI( editor.objects[ param[ key ].getValue() ] ) } );
  151. parent.add( param[ key ] );
  152. return;
  153. }
  154. if ( key === 'geometry' ) {
  155. param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
  156. param[ key ].name.setColor( '#0080f0' ).onClick( function(){ createUI( editor.geometries[ param[ key ].getValue() ] ) } );
  157. parent.add( param[ key ] );
  158. return;
  159. }
  160. if ( key == 'material' ) {
  161. param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
  162. param[ key ].name.setColor( '#0080f0' ).onClick( function(){ createUI( editor.materials[ param[ key ].getValue() ] ) } );
  163. parent.add( param[ key ] );
  164. return;
  165. }
  166. if ( key == 'userData' ) {
  167. param[ key ] = new UI.ParamJson( key ).onChange( updateParam );
  168. parent.add( param[ key ] );
  169. return;
  170. }
  171. // Texture params
  172. for ( var i in textureParams ) {
  173. if ( key == textureParams[ i ] ) {
  174. param[ key ] = new UI.ParamSelect( key ).onChange( updateParam );
  175. param[ key ].name.setColor( '#0080f0' ).onClick( function(){
  176. var value = param[ key ].getValue();
  177. if ( value == 'new' ) {
  178. var texture = editor.createTexture();
  179. model[ key ] = texture;
  180. createUI( texture );
  181. } else createUI( editor.textures[ value ] )
  182. } );
  183. parent.add( param[ key ] );
  184. return;
  185. }
  186. }
  187. // Params by type
  188. if ( typeof model[ key ] === 'string' ) {
  189. param[ key ] = new UI.ParamString( key ).onChange( updateParam );
  190. parent.add( param[ key ] );
  191. } else if ( typeof model[ key ] === 'boolean' ) {
  192. param[ key ] = new UI.ParamBool( key ).onChange( updateParam );
  193. parent.add( param[ key ] );
  194. } else if ( typeof model[ key ] === 'number' ) {
  195. if ( integerParams.indexOf( key ) != -1 )
  196. param[ key ] = new UI.ParamInteger( key ).onChange( updateParam );
  197. else
  198. param[ key ] = new UI.ParamFloat( key ).onChange( updateParam );
  199. parent.add( param[ key ] );
  200. } else if ( model[ key ] instanceof THREE.Vector2 ) {
  201. param[ key ] = new UI.ParamVector2( key ).onChange( updateParam );
  202. parent.add( param[ key ] );
  203. } else if ( model[ key ] instanceof THREE.Vector3 ) {
  204. param[ key ] = new UI.ParamVector3( key ).onChange( updateParam );
  205. parent.add( param[ key ] );
  206. } else if ( model[ key ] instanceof THREE.Vector4 || model[ key ] instanceof THREE.Quaternion ) {
  207. param[ key ] = new UI.ParamVector4( key ).onChange( updateParam );
  208. parent.add( param[ key ] );
  209. } else if ( model[ key ] instanceof THREE.Color ) {
  210. param[ key ] = new UI.ParamColor( key ).onChange( updateParam );
  211. parent.add( param[ key ] );
  212. } else if ( model[ key ] instanceof Array ) {
  213. if ( model[ key ].length ) {
  214. param[ key ] = new UI.Text( key ).setColor( '#0080f0' ).onClick( function(){ createUI( model[ key ] ) } );
  215. parent.add( param[ key ], new UI.Break() );
  216. }
  217. } else if ( typeof model[ key ] !== 'function' ) {
  218. param[ key ] = new UI.Text( key ).setColor( '#0080f0' ).onClick( function(){ createUI( model[ key ] ) } );
  219. parent.add( param[ key ], new UI.Break() );
  220. }
  221. }
  222. }
  223. function updateUI() {
  224. if ( model ) {
  225. for ( var key in model ) {
  226. // Params from multiOptions
  227. for ( var i in multiOptions ) {
  228. if ( i == key ) {
  229. for ( var j in multiOptions[ i ] ) {
  230. var options = {};
  231. for ( var j in multiOptions[ i ] ) options[ multiOptions[ i ][ j ] ] = j;
  232. param[ key ].setOptions( options );
  233. param[ key ].setValue( model[ key ] );
  234. break;
  235. }
  236. }
  237. }
  238. // Special params
  239. if ( key === 'parent' ) {
  240. var options = {};
  241. for ( var id in editor.objects ) if ( model.id != id ) options[ id ] = editor.objects[ id ].name;
  242. param[ key ].setOptions( options );
  243. if ( model[ key ] !== undefined ) param[ key ].setValue( model[ key ].id );
  244. } else if ( key === 'geometry' ) {
  245. var options = {};
  246. for ( var id in editor.geometries ) options[ id ] = editor.geometries[ id ].name;
  247. param[ key ].setOptions( options );
  248. if ( model[ key ] !== undefined ) param[ key ].setValue( model[ key ].id );
  249. } else if ( key === 'material' ) {
  250. var options = {};
  251. for ( var id in editor.materials ) options[ id ] = editor.materials[ id ].name;
  252. param[ key ].setOptions( options );
  253. if ( model[ key ] !== undefined ) param[ key ].setValue( model[ key ].id );
  254. } else if ( key == 'userData' ) {
  255. try {
  256. param[ key ].setValue( JSON.stringify( model.userData, null, ' ' ) );
  257. } catch ( error ) {
  258. console.log( error );
  259. }
  260. // Texture params
  261. } else if ( textureParams.indexOf( key ) != -1 ) {
  262. var options = {};
  263. options[ 'new' ] = 'New texture';
  264. for ( var id in editor.textures ) options[ id ] = editor.textures[ id ].name;
  265. param[ key ].setOptions( options );
  266. param[ key ].setValue( 'new' );
  267. if ( model[ key ] ) param[ key ].setValue( model[ key ].id );
  268. }
  269. // Params by type
  270. else if ( typeof model[ key ] === 'string' ) param[ key ].setValue( model[ key ] );
  271. else if ( typeof model[ key ] === 'boolean' ) param[ key ].setValue( model[ key ] );
  272. else if ( typeof model[ key ] === 'number' ) param[ key ].setValue( model[ key ] );
  273. else if ( model[ key ] instanceof THREE.Vector3 ) param[ key ].setValue( model[ key ] );
  274. else if ( model[ key ] instanceof THREE.Color ) param[ key ].setValue( model[ key ] );
  275. }
  276. }
  277. }
  278. function updateParam( event ) {
  279. var key = event.srcElement.name;
  280. var value = ( param[ key ].getValue ) ? param[ key ].getValue() : null;
  281. // Special params
  282. if ( key === 'parent' ) editor.parent( object, editor.objects[ value ] );
  283. else if ( key === 'geometry' ) model[ key ] = editor.geometries[ value ];
  284. else if ( key === 'material' ) model[ key ] = editor.materials[ value ];
  285. else if ( key === 'userData' ) {
  286. try {
  287. model[ key ] = JSON.parse( value );
  288. } catch ( error ) {
  289. console.log( error );
  290. }
  291. } else if ( textureParams.indexOf( key ) != -1 ) {
  292. if ( value == 'new' ) {
  293. var texture = editor.createTexture();
  294. model[ key ] = texture;
  295. createUI( texture );
  296. } else model[ key ] = editor.textures[ value ];
  297. }
  298. // Params by type
  299. else if ( typeof model[ key ] === 'string' ) model[ key ] = value;
  300. else if ( typeof model[ key ] === 'boolean' ) model[ key ] = value;
  301. else if ( typeof model[ key ] === 'number' ) model[ key ] = parseFloat( value );
  302. else if ( model[ key ] instanceof THREE.Color ) model[ key ].setHex( value );
  303. else if ( model[ key ] instanceof THREE.Vector3 ) model[ key ].copy( value );
  304. // Post actions
  305. if ( model instanceof THREE.Object3D ) {
  306. signals.objectChanged.dispatch( model );
  307. } else if ( model instanceof THREE.Geometry ) {
  308. var geoParams = {};
  309. for ( var i in param )
  310. if ( param[ i ].getValue ) geoParams[ i ] = param[ i ].getValue();
  311. editor.updateGeometry( model, geoParams );
  312. } else if ( model instanceof THREE.Material ) {
  313. signals.materialChanged.dispatch( model );
  314. }
  315. signals.sceneChanged.dispatch( editor.scene );
  316. }
  317. return container;
  318. }