/* * Copyright 2013, kaj dijkstra , * Author, Kaj Dijkstra. * All rights reserved. * */ import mesh from './mesh.js'; import {vector2, vector3} from './math.js'; console.log(vector3.add([1,1,1], [1,1,1])); /** * primitive object **/ class primitives{ constructor( ) { } /** * set viewport * @param {(viewport)} viewport **/ setViewport( viewport ){ this.viewport = viewport; this.gl = viewport.gl; } /** * Create plane * @param {(int)} width * @param {(int)} depth * @param {(int)} subdivisionsDepth * @param {(int)} subdivisionsWidth * @param {(string)} type * @param {(int)} index_type **/ createPlane(width, depth, subdivisionsDepth, subdivisionsWidth, type, index_type) { var vertices = []; var indices = []; var normals = []; var textureCoordinates = []; switch(type) { case "triangleFan": vertices = getVertices(subdivisionsDepth, subdivisionsWidth); indices = getIndices(subdivisionsDepth, subdivisionsWidth); textureCoordinates = getTextCoord(subdivisionsDepth, subdivisionsWidth); break; case "triangleStrip": vertices = createPlaneTriangleStripVerts(subdivisionsDepth, subdivisionsWidth, width, depth, index_type); indices = createPlaneTriangleStripIndices(subdivisionsDepth, subdivisionsWidth, index_type); textureCoordinates = createPlaneTriangleStripTextCoords(subdivisionsDepth, subdivisionsWidth); break; default: for (var z = 0; z <= subdivisionsDepth; z++) { for (var x = 0; x <= subdivisionsWidth; x++) { var u = x / subdivisionsWidth; var v = z / subdivisionsDepth; var vertex = new vector3( width * u - width * 0.5, 0, depth * v - depth * 0.5); var normal = new vector3(0, 1, 0); var textCoord = new vector2(u , (1 - v )); vertices = vertices.concat(vertex); normals = normals.concat(normal); textureCoordinates = textureCoordinates.concat(textCoord); } } var numVertsAcross = subdivisionsWidth + 1; for (var z = 0; z < subdivisionsDepth; z++) { for (var x = 0; x < subdivisionsWidth; x++) { // triangle 1 of quad var triangle1 = new vector3( (z + 0) * numVertsAcross + x, (z + 1) * numVertsAcross + x, (z + 0) * numVertsAcross + x + 1 ); // triangle 2 of quad var triangle2 = new vector3( (z + 1) * numVertsAcross + x, (z + 1) * numVertsAcross + x + 1, (z + 0) * numVertsAcross + x + 1 ); indices = indices.concat(triangle1); indices = indices.concat(triangle2); } } var planeMesh = new mesh(); planeMesh.createMeshFromArrays( indices, vertices, normals, textureCoordinates); return planeMesh; } //console.log(this); //return this.createMesh(subMesh.indices, subMesh.vertices, subMesh.textcoords, subMesh.normals); } /** * Create Sphere * @param {(int)} radius * @param {(int)} subdivisionsHeight * @param {(int)} subdivisionsAxis **/ createSphere(radius, subdivisionsHeight, subdivisionsAxis) { var latitudeBands = subdivisionsHeight; var longitudeBands = subdivisionsAxis; var vertexPositionBuffer; var vertexNormalBuffer; var vertexTextureCoordBuffer; var vertexIndexBuffer; var vertexPositionData = []; var normalData = []; var textureCoordData = []; for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) { var theta = latNumber * Math.PI / latitudeBands; var sinTheta = Math.sin(theta); var cosTheta = Math.cos(theta); for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) { var phi = longNumber * 2 * Math.PI / longitudeBands; var sinPhi = Math.sin(phi); var cosPhi = Math.cos(phi); var x = cosPhi * sinTheta; var y = cosTheta; var z = sinPhi * sinTheta; var u = 1- (longNumber / longitudeBands); var v = latNumber / latitudeBands; normalData.push(x); normalData.push(y); normalData.push(z); textureCoordData.push(u); textureCoordData.push(v); vertexPositionData.push(radius * x); vertexPositionData.push(radius * y); vertexPositionData.push(radius * z); } } var indexData = []; for (var latNumber = 0; latNumber < latitudeBands; latNumber++) { for (var longNumber = 0; longNumber < longitudeBands; longNumber++) { var first = (latNumber * (longitudeBands + 1)) + longNumber; var second = first + longitudeBands + 1; indexData.push(first); indexData.push(second); indexData.push(first + 1); indexData.push(second); indexData.push(second + 1); indexData.push(first + 1); } } var newMesh = new mesh(); newMesh.setViewport(this.viewport); newMesh.createMeshFromArrays( indexData, vertexPositionData, normalData, textureCoordData ); return newMesh; } /** * lay out array * @param {(array)} array * @param {(string)} output **/ layoutArray(array) { var out = []; for(var c = 0; c 0.00001) { tangent = vector3.scale(tangent, 1 / tangentLength); } var binormalLength = vector3.size(binormal); if (binormalLength > 0.00001) { binormal = vector3.scale(binormal, 1 / binormalLength); } // Accumulate the tangent and binormal into the tangent frame map. for (var i = 0; i < 3; ++i) { addTangentFrame(positions[i], normals[i], tangent, binormal); } } // Add the tangent and binormal streams. var numVertices = positionArray.numItems; var tangents = []; var binormals = []; // Extract the tangent and binormal for each vertex. for (var vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex) { var position = this.getElement(positionArray,vertexIndex); var normal = this.getElement(normalArray, vertexIndex); var frame = getTangentFrame(position, normal); // Orthonormalize the tangent with respect to the normal. var tangent = frame[0]; tangent = vector3.sub( tangent, vector3.scale(normal, vector3.dot(normal, tangent))); var tangentLength = vector3.size(tangent); if (tangentLength > 0.00001) { tangent = vector3.scale(tangent, 1 / tangentLength); } // Orthonormalize the binormal with respect to the normal and the tangent. var binormal = frame[1]; binormal = vector3.sub( binormal, vector3.scale(tangent, vector3.dot(tangent, binormal))); binormal = vector3.sub( binormal, vector3.scale(normal, vector3.dot(normal, binormal))); var binormalLength = vector3.size(binormal); if (binormalLength > 0.00001) { binormal = vector3.scale(binormal, 1 / binormalLength); } tangents.push(tangent); binormals.push(binormal); } return {tangent: tangents, binormal: binormals }; } /** * Create sky sphere * @param {(int)} radius * @param {(int)} subdivisionsHeight * @param {(int)} subdivisionsAxis **/ createSkySphere(radius, subdivisionsHeight, subdivisionsAxis) { var positions = []; var normals = []; var texCoord = []; var indices = []; for (var y = 0; y <= subdivisionsHeight; y++) { for (var x = 0; x <= subdivisionsAxis; x++) { // Generate a vertex based on its spherical coordinates var u = x / subdivisionsAxis; var v = y / subdivisionsHeight; var theta = 2 * Math.PI * u; var phi = Math.PI * v; var sinTheta = Math.sin(theta); var cosTheta = Math.cos(theta); var sinPhi = Math.sin(phi); var cosPhi = Math.cos(phi ); var ux = cosTheta * sinPhi; var uy = cosPhi; var uz = sinTheta * sinPhi; positions.push(radius * ux, radius * uy, radius * uz); normals.push(ux, uy, uz); texCoord.push(1 - u, 1 - v); } } var numVertsAround = subdivisionsAxis + 1; for (var x = 0; x < subdivisionsAxis; x++) { for (var y = 0; y < subdivisionsHeight; y++) { // Make triangle 1 of quad. indices.push( (y + 0) * numVertsAround + x, (y + 0) * numVertsAround + x + 1, (y + 1) * numVertsAround + x); // Make triangle 2 of quad. indices.push( (y + 1) * numVertsAround + x, (y + 0) * numVertsAround + x + 1, (y + 1) * numVertsAround + x + 1); } } var subMesh = {}; subMesh.indices = indices; subMesh.vertices = positions; subMesh.textcoords = texCoord; subMesh.normals = normals; return subMesh; } /** * get the number of vertices * @param {(int)} width * @param {(int)} height **/ getVerticesCount( width, height ) { return width * height * 3; } /** * get the number of indices * @param {(int)} width * @param {(int)} height **/ getIndicesCount( width, height ) { return (width*height) + (width-1)*(height-2); } /** * get vertices * @param {(int)} width * @param {(int)} height **/ getVertices( width, height ) { var vertices = []; var i = 0; for ( var row=0; row0; col-- ) { indices[i++] = col + (row+1) * width; indices[i++] = col - 1 + row * width; } } } if ( (height&1) && height>2 ) { indices[i++] = (height-1) * width; } return indices; } /** * create plane (trianglestrip) indices * @param {(int)} width * @param {(int)} height **/ createPlaneTriangleStripIndices(width, height){ var indices = new Uint32Array( getIndicesCount( width, height ) ); var i = 0; for ( var row=0; row0; col-- ) { indices[i++] = col + (row+1) * width; indices[i++] = col - 1 + + row * width; } } } return indices; } /** * Create plane vertices (trianglestrip) * @param {(int)} subdivisionsDepth * @param {(int)} subdivisionsWidth * @param {(int)} width * @param {(int)} height **/ createPlaneTriangleStripVerts(subdivisionsDepth, subdivisionsWidth, width, height) { var vertices = new Float32Array(this.getVerticesCount( width, height )); var i = 0; for ( var row=0; row