diff options
| author | Yann Granjon <[email protected]> | 2013-06-05 16:13:15 +0200 |
|---|---|---|
| committer | Yann Granjon <[email protected]> | 2013-06-05 16:13:15 +0200 |
| commit | 1ef133c52d12daf3fdad1d979e5a71cb39fa0d2e (patch) | |
| tree | 31e2cd5c6b0497f58762a63e3536dab76654324a /js/factory.js | |
| download | Chess3D-1ef133c52d12daf3fdad1d979e5a71cb39fa0d2e.tar.xz Chess3D-1ef133c52d12daf3fdad1d979e5a71cb39fa0d2e.zip | |
Initial Commit
Diffstat (limited to 'js/factory.js')
| -rw-r--r-- | js/factory.js | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/js/factory.js b/js/factory.js new file mode 100644 index 0000000..2ff37eb --- /dev/null +++ b/js/factory.js @@ -0,0 +1,420 @@ +// ECMAScript 5 strict mode +/* jshint globalstrict: true*/ +/* global THREE, $, document, window, console */ +/* global LOADING_BAR_SCALE,ROWS,COLS,PIECE_SIZE, BOARD_SIZE, FLOOR_SIZE, WIREFRAME, DEBUG, Cell, WHITE, BLACK, FEEDBACK, SHADOW */ +/* global createCell */ + +/* + * initPieceFactory and initCellFactory need to be called after + * all ressources are loaded (geometry and texture) + * + * they will create the createPiece and createCell function + * and keep some texture/material objects in a closure to avoid + * unnecessary cloning + */ + +"use strict"; +var geometries = {}; +var textures = {}; +function initPieceFactory () { + + // common textures + var tiling = 4; + var colors = []; + for(var c = 0; c<2; c++) { + colors[c] = textures['texture/wood-'+c+'.jpg'].clone(); + colors[c].tile(tiling); + } + var norm = textures['texture/wood_N.jpg'].clone(); + norm.tile(tiling); + var spec = textures['texture/wood_S.jpg'].clone(); + spec.tile(tiling); + + function createPiece(name,color) { + var size = BOARD_SIZE/COLS * PIECE_SIZE; + // container for the piece and its reflexion + var piece = new THREE.Object3D(); + // base material for all the piece (only lightmap changes) + var material = new THREE.MeshPhongMaterial({ + color:0xffffff, + specular:0xaaaaaa, + shininess:60.0, + map:colors[color], + normalMap:norm, + specularMap:spec, + wireframe:WIREFRAME + }); + material.normalScale.set(0.3,0.3); + + // urls of geometry and lightmap + var urlJson = '3D/json/'+name+'.json'; + var urlAO = 'texture/'+name+'-ao.jpg'; + + var geo = geometries[urlJson]; + // no need to clone this texture + // since its pretty specific + var light = textures[urlAO]; + light.format = THREE.LuminanceFormat; + + material.lightMap = light; + + var mesh = new THREE.Mesh(geo,material); + if (SHADOW) { + mesh.castShadow = true; + mesh.receiveShadow = true; + } + mesh.scale.set(size,size,size); + // we rotate pieces so they face each other (mostly relevant for knight) + mesh.rotation.y += (color == WHITE) ? -Math.PI/2 : Math.PI/2; + + // we create the reflection + // it's a cloned with a negative scale on the Y axis + var reflexion = mesh.clone(); + reflexion.scale.y *= -1; + reflexion.material = reflexion.material.clone(); + reflexion.material.side = THREE.BackSide; + + piece.add(mesh); + piece.add(reflexion); + + piece.name = name; + piece.color = color; + + return piece; + } + + // make it global + window.createPiece = createPiece; +} + +function initCellFactory() { + + var materials = []; + var tiling = 2; + + + // common textures + var diff; + var norm = textures['texture/wood_N.jpg'].clone(); + norm.tile(tiling); + var spec = textures['texture/wood_S.jpg'].clone(); + spec.tile(tiling); + + for(var c = 0; c<2; c++) { + + diff = textures['texture/wood-'+c+'.jpg'].clone(); + diff.tile(tiling); + + //common material + materials[c] = new THREE.MeshPhongMaterial({ + color:0xffffff, + specular:[0xAAAAAA,0x444444][c], + shininess:30.0, + wireframe:WIREFRAME, + transparent:true, + map:diff, + specularMap:spec, + normalMap:norm, + //blending: THREE.AdditiveBlending, + opacity:0.5 + }); + //materials[c].normalScale.set(0.5,0.5); + } + + function createCell(size,color) { + // container for the cell and its reflexion + var geo = new THREE.PlaneGeometry(size,size); + + // randomize uv offset to ad a bit of variety + var randU = Math.random(); + var randV = Math.random(); + + var uvs = geo.faceVertexUvs[0][0]; + for (var j = 0; j < uvs.length; j++) { + uvs[j].x += randU; + uvs[j].y += randV; + } + + var cell = new THREE.Mesh(geo,materials[color]); + + if (SHADOW) { + cell.receiveShadow = true; + } + + // by default PlaneGeometry is vertical + cell.rotation.x = -Math.PI/2; + cell.color = color; + return cell; + } + + // make it global + window.createCell = createCell; +} + + +function createChessBoard(size) { + // contains everything that makes the board + var lChessBoard = new THREE.Object3D(); + + var cellSize = size/COLS; + var square,cell; + + for(var i=0; i< ROWS*COLS; i++) { + + var col = i%COLS; + var row = Math.floor(i/COLS); + + cell = new Cell(i); + square = createCell(cellSize,1-(i+row)%2); + square.position = cell.getWorldPosition(); + square.name = cell.position; + + lChessBoard.add(square); + } + + // some fake inner environment color for reflexion + var innerBoard = new THREE.Mesh ( + geometries['3D/json/innerBoard.json'], + new THREE.MeshBasicMaterial({ + color:0x783e12 + }) + ); + innerBoard.scale.set(size,size,size); + + /// board borders + var tiling = 6; + var wood = textures['texture/wood-0.jpg'].clone(); + var spec = textures['texture/wood_S.jpg'].clone(); + var norm = textures['texture/wood_N.jpg'].clone(); + wood.tile(tiling); + spec.tile(tiling); + norm.tile(tiling); + + var geo = geometries['3D/json/board.json']; + geo.computeBoundingBox(); + + var board = new THREE.Mesh ( + geo, + new THREE.MeshPhongMaterial({ + color:0xffffff, + map:wood, + specular: 0xffffff, + specularMap: spec, + normalMap: norm, + shininess: 60, + normalScale: new THREE.Vector2(0.2,0.2) + }) + ); + var hCorrection = 0.62; // yeah I should just create a better geometry + board.scale.set(size,size*hCorrection,size); + lChessBoard.height = geo.boundingBox.min.y * board.scale.y; + + if (SHADOW) { + board.receiveShadow = true; + board.castShadow = true; + } + + lChessBoard.add(innerBoard); + lChessBoard.add(board); + + lChessBoard.name = "chessboard"; + return lChessBoard; +} + +function createFloor(size,chessboardSize) { + // The floor is a fake plane with a hole in it to allow + // for the fake reflexion trick to work + // so we build it vertices by vertices + + // material + var tiling = 30*size/1000; + var material = new THREE.MeshPhongMaterial({ + color:0xffffff, + wireframe:WIREFRAME , + specular:0xaaaaaa, + shininess:30 + + }); + var diff = textures['texture/floor.jpg']; + var spec = textures['texture/floor_S.jpg']; + var norm = textures['texture/floor_N.jpg']; + var light = textures['texture/fakeShadow.jpg']; + + diff.tile(tiling); + spec.tile(tiling); + norm.tile(tiling); + light.format = THREE.RGBFormat; + + material.map = diff; + material.normalMap = norm; + material.normalScale.set(0.6,0.6); + material.specularMap = spec; + material.lightMap = light; + + // geometry + var halfBoard = chessboardSize/2; + var halfSize = size/2; + + var floorGeo = new THREE.Geometry(); + // outter vertices + floorGeo.vertices.push(new THREE.Vector3(-halfSize,0,-halfSize)); + floorGeo.vertices.push(new THREE.Vector3( halfSize,0,-halfSize)); + floorGeo.vertices.push(new THREE.Vector3( halfSize,0, halfSize)); + floorGeo.vertices.push(new THREE.Vector3(-halfSize,0, halfSize)); + // hole vertices + floorGeo.vertices.push(new THREE.Vector3(-halfBoard,0,-halfBoard)); + floorGeo.vertices.push(new THREE.Vector3( halfBoard,0,-halfBoard)); + floorGeo.vertices.push(new THREE.Vector3( halfBoard,0, halfBoard)); + floorGeo.vertices.push(new THREE.Vector3(-halfBoard,0, halfBoard)); + + floorGeo.faceVertexUvs[ 0 ] = []; + floorGeo.faceVertexUvs[ 1 ] = []; + + /* + * vertices uvs-lightmap + * 0-----------1 80-----------80 + * |\ /| |\ /| + * | \ / | | \ / | + * | \ / | | \ / | + * | 4---5 | | 0---0 | + * | | | | | | | | + * | 7---6 | | 0---0 | + * | / \ | | / \ | + * | / \ | | / \ | + * |/ \| |/ \| + * 3-----------2 80-----------80 + */ + + // all normals just points upward + var normal = new THREE.Vector3( 0, 1, 0 ); + + // list of vertex index for each face + var faces = [ + [0,4,5,1], + [1,5,6,2], + [2,6,7,3], + [3,7,4,0] + ]; + + faces.forEach( function(f) { + var uvs1 = []; + var uvs2 = []; + var lightU,lightV; + f.forEach(function(v,i) { + // we linearily transform positions + // from a -halfSize-halfSize space + // to a 0-1 space + uvs1.push(new THREE.Vector2( + (floorGeo.vertices[v].x+halfSize)/size, + (floorGeo.vertices[v].z+halfSize)/size + )); + lightU = (v < 4) ? 80 : 0; + lightV = (i < 2) ? 0 : 1; + uvs2.push(new THREE.Vector2(lightU,lightV)); + }); + + // we create a new face folowing the faces list + var face = new THREE.Face4( + f[0],f[1],f[2],f[3] + ); + + // and apply normals (without this, no proper lighting) + face.normal.copy( normal ); + face.vertexNormals.push( + normal.clone(), + normal.clone(), + normal.clone(), + normal.clone() + ); + + // add the face to the geometry's faces list + floorGeo.faces.push(face); + + // add uv coordinates to uv channels. + floorGeo.faceVertexUvs[ 0 ].push(uvs1); // for diffuse/normal + floorGeo.faceVertexUvs[ 1 ].push(uvs2); // for lightmap + + }); + + // not sure it's needed but since it's in THREE.PlaneGeometry... + floorGeo.computeCentroids(); + + var floor = new THREE.Mesh(floorGeo,material); + + if(SHADOW) { + floor.receiveShadow = true; + } + + + floor.name = "floor"; + return floor; +} + +// special highlighting materials +var validCellMaterial = null; +function createValidCellMaterial () { + validCellMaterial = []; + var tiling = 2; + + + // common textures + var diff; + var norm = textures['texture/wood_N.jpg'].clone(); + norm.tile(tiling); + var spec = textures['texture/wood_S.jpg'].clone(); + spec.tile(tiling); + + for(var c = 0; c<2; c++) { + + diff = textures['texture/wood-1.jpg'].clone(); + diff.tile(tiling); + + //common material + validCellMaterial[c] = new THREE.MeshPhongMaterial({ + color:0x00ff00, + specular:0x999999, + shininess:60.0, + wireframe:WIREFRAME, + map:diff, + specularMap:spec, + normalMap:norm + }); + //materials[c].normalScale.set(0.5,0.5); + } +} + +var selectedMaterial = null; +function createSelectedMaterial() { + selectedMaterial = []; + var tiling = 4; + + + // common textures + var diff; + var norm = textures['texture/wood_N.jpg'].clone(); + norm.tile(tiling); + var spec = textures['texture/wood_S.jpg'].clone(); + spec.tile(tiling); + + for(var c = 0; c<2; c++) { + + diff = textures['texture/wood-1.jpg'].clone(); + diff.tile(tiling); + + //common material + selectedMaterial[c] = new THREE.MeshPhongMaterial({ + color:0x00ff00, + emissive:0x009900, + specular:0x999999, + shininess:60.0, + wireframe:WIREFRAME, + transparent:false, + map:diff, + specularMap:spec, + normalMap:norm + //opacity:0.4 + }); + selectedMaterial[c].normalScale.set(0.3,0.3); + } + +}
\ No newline at end of file |
