aboutsummaryrefslogtreecommitdiff
path: root/js/factory.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/factory.js')
-rw-r--r--js/factory.js420
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