974 lines
24 KiB
JavaScript
974 lines
24 KiB
JavaScript
|
|
/*
|
||
|
|
* 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<array.length; c++) {
|
||
|
|
var a = array[c];
|
||
|
|
|
||
|
|
if(a)
|
||
|
|
for(var g = 0; g<a.length; g++) {
|
||
|
|
|
||
|
|
out.push(a[g]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create mesh
|
||
|
|
* @param {(array)} indexData
|
||
|
|
* @param {(array)} vertexPositionData
|
||
|
|
* @param {(array)} textureCoordData
|
||
|
|
* @param {(array)} normalData
|
||
|
|
**/
|
||
|
|
createMesh(indexData, vertexPositionData, textureCoordData, normalData) {
|
||
|
|
var mesh = {};
|
||
|
|
|
||
|
|
if(normalData) {
|
||
|
|
var vertexNormalBuffer = this.gl.createBuffer();
|
||
|
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexNormalBuffer);
|
||
|
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(normalData), this.gl.STATIC_DRAW);
|
||
|
|
vertexNormalBuffer.itemSize = 3;
|
||
|
|
vertexNormalBuffer.numItems = normalData.length / 3;
|
||
|
|
vertexNormalBuffer.data = normalData;
|
||
|
|
mesh.normalBuffer = vertexNormalBuffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(textureCoordData) {
|
||
|
|
var vertexTextureCoordBuffer = this.gl.createBuffer();
|
||
|
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexTextureCoordBuffer);
|
||
|
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this.gl.STATIC_DRAW);
|
||
|
|
vertexTextureCoordBuffer.itemSize = 2;
|
||
|
|
vertexTextureCoordBuffer.numItems = textureCoordData.length / 2;
|
||
|
|
vertexTextureCoordBuffer.data = textureCoordData;
|
||
|
|
|
||
|
|
mesh.uvBuffer = vertexTextureCoordBuffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
var vertexPositionBuffer = this.gl.createBuffer();
|
||
|
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexPositionBuffer);
|
||
|
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), this.gl.STATIC_DRAW);
|
||
|
|
vertexPositionBuffer.itemSize = 3;
|
||
|
|
vertexPositionBuffer.numItems = vertexPositionData.length / 3;
|
||
|
|
vertexPositionBuffer.data = vertexPositionData;
|
||
|
|
|
||
|
|
|
||
|
|
var vertexIndexBuffer = this.gl.createBuffer();
|
||
|
|
if(indexData) {
|
||
|
|
|
||
|
|
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
||
|
|
|
||
|
|
//if(kepler.extensions.elementIndexUint)
|
||
|
|
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indexData), this.gl.STATIC_DRAW);
|
||
|
|
//else
|
||
|
|
// this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), this.gl.STATIC_DRAW);
|
||
|
|
|
||
|
|
vertexIndexBuffer.itemSize = 3;
|
||
|
|
vertexIndexBuffer.numItems = indexData.length;
|
||
|
|
vertexIndexBuffer.data = indexData;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if(normalData) {
|
||
|
|
var bn = this.createTangentsAndBinormals( vertexPositionBuffer,
|
||
|
|
vertexNormalBuffer,
|
||
|
|
vertexTextureCoordBuffer,
|
||
|
|
vertexIndexBuffer);
|
||
|
|
|
||
|
|
var binormalArray = this.viewport.primitives.layoutArray(bn.binormal);
|
||
|
|
var binormalBuffer = this.gl.createBuffer();
|
||
|
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, binormalBuffer);
|
||
|
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(binormalArray), this.gl.STATIC_DRAW);
|
||
|
|
binormalBuffer.itemSize = 3;
|
||
|
|
binormalBuffer.numItems = binormalArray.length / 3;
|
||
|
|
binormalBuffer.data = binormalArray;
|
||
|
|
|
||
|
|
var tangentArray = this.viewport.primitives.layoutArray(bn.tangent);
|
||
|
|
var tangentBuffer = this.gl.createBuffer();
|
||
|
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, tangentBuffer);
|
||
|
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(tangentArray), this.gl.STATIC_DRAW);
|
||
|
|
tangentBuffer.itemSize = 3;
|
||
|
|
tangentBuffer.numItems = tangentArray.length / 3;
|
||
|
|
tangentBuffer.data = tangentArray;
|
||
|
|
|
||
|
|
mesh.binormalBuffer = binormalBuffer;
|
||
|
|
mesh.tangentBuffer = tangentBuffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
mesh.vertexBuffer = vertexPositionBuffer;
|
||
|
|
mesh.indexBuffer = vertexIndexBuffer;
|
||
|
|
|
||
|
|
return mesh;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get element
|
||
|
|
* @param {(array)} buffer
|
||
|
|
* @param {(int)} vertexIndex
|
||
|
|
* @return {(array)} out
|
||
|
|
**/
|
||
|
|
getElement(buffer, vertexIndex) {
|
||
|
|
var startId = buffer.itemSize * vertexIndex;
|
||
|
|
var out = [];
|
||
|
|
|
||
|
|
for(var c = 0; c<buffer.itemSize; c++) {
|
||
|
|
out.push(buffer.data[c+startId]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create Tangent and Binormal vectors
|
||
|
|
* @param {(array)} positionArray
|
||
|
|
* @param {(array)} normalArray
|
||
|
|
* @param {(array)} normalMapUVArray
|
||
|
|
* @param {(array)} triangles
|
||
|
|
* @return {(array)} primitive object
|
||
|
|
**/
|
||
|
|
createTangentsAndBinormals( positionArray, normalArray, normalMapUVArray, triangles) {
|
||
|
|
|
||
|
|
// Maps from position, normal key to tangent and binormal matrix.
|
||
|
|
var tangentFrames = {};
|
||
|
|
|
||
|
|
// Rounds a vector to integer components.
|
||
|
|
function roundVector(v) {
|
||
|
|
return [Math.round(v[0]), Math.round(v[1]), Math.round(v[2])];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Generates a key for the tangentFrames map from a position and normal
|
||
|
|
// vector. Rounds position and normal to allow some tolerance.
|
||
|
|
function tangentFrameKey(position, normal) {
|
||
|
|
return roundVector(vector3.scale(position, 100)) + ',' +
|
||
|
|
roundVector(vector3.scale(normal, 100));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Accumulates into the tangent and binormal matrix at the approximate
|
||
|
|
// position and normal.
|
||
|
|
function addTangentFrame(position, normal, tangent, binormal) {
|
||
|
|
var key = tangentFrameKey(position, normal);
|
||
|
|
var frame = tangentFrames[key];
|
||
|
|
if (!frame) {
|
||
|
|
frame = [[0, 0, 0], [0, 0, 0]];
|
||
|
|
}
|
||
|
|
frame[0] = vector3.add(frame[0], tangent);
|
||
|
|
frame[1] = vector3.add(frame[1], binormal);
|
||
|
|
tangentFrames[key] = frame;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get the tangent and binormal matrix at the approximate position and
|
||
|
|
// normal.
|
||
|
|
function getTangentFrame(position, normal) {
|
||
|
|
var key = tangentFrameKey(position, normal);
|
||
|
|
return tangentFrames[key];
|
||
|
|
}
|
||
|
|
|
||
|
|
var numTriangles = triangles.numItems;
|
||
|
|
for (var triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex) {
|
||
|
|
|
||
|
|
// Get the vertex indices, uvs and positions for the triangle.
|
||
|
|
var vertexIndices = this.getElement(triangles, triangleIndex);
|
||
|
|
var uvs = [];
|
||
|
|
var positions = [];
|
||
|
|
var normals = [];
|
||
|
|
|
||
|
|
for (var i = 0; i < 3; ++i) {
|
||
|
|
var vertexIndex = vertexIndices[i];
|
||
|
|
uvs[i] = this.getElement(normalMapUVArray, vertexIndex);
|
||
|
|
positions[i] = this.getElement(positionArray,vertexIndex);
|
||
|
|
normals[i] = this.getElement(normalArray,vertexIndex);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Calculate the tangent and binormal for the triangle using method
|
||
|
|
// described in Maya documentation appendix A: tangent and binormal
|
||
|
|
// vectors.
|
||
|
|
var tangent = [0, 0, 0];
|
||
|
|
var binormal = [0, 0, 0];
|
||
|
|
for (var axis = 0; axis < 3; ++axis) {
|
||
|
|
var edge1 = [positions[1][axis] - positions[0][axis],
|
||
|
|
uvs[1][0] - uvs[0][0], uvs[1][1] - uvs[0][1]];
|
||
|
|
var edge2 = [positions[2][axis] - positions[0][axis],
|
||
|
|
uvs[2][0] - uvs[0][0], uvs[2][1] - uvs[0][1]];
|
||
|
|
var edgeCross = vector3.normalize( vector3.cross(edge1, edge2) );
|
||
|
|
if (edgeCross[0] == 0) {
|
||
|
|
edgeCross[0] = 1;
|
||
|
|
}
|
||
|
|
tangent[axis] = -edgeCross[1] / edgeCross[0];
|
||
|
|
binormal[axis] = -edgeCross[2] / edgeCross[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Normalize the tangent and binornmal.
|
||
|
|
var tangentLength = vector3.size(tangent);
|
||
|
|
if (tangentLength > 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; row<height; row++ ) {
|
||
|
|
for ( var col=0; col<width; col++ ) {
|
||
|
|
vertices[i++] = col / width;
|
||
|
|
vertices[i++] = 0.0;
|
||
|
|
vertices[i++] = row / height;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return vertices;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get texture coordinates
|
||
|
|
* @param {(int)} width
|
||
|
|
* @param {(int)} height
|
||
|
|
**/
|
||
|
|
getTextCoord( width, height ) {
|
||
|
|
var uv = [];
|
||
|
|
var i = 0;
|
||
|
|
for ( var row=0; row<height; row++ ) {
|
||
|
|
for ( var col=0; col<width; col++ ) {
|
||
|
|
uv[i++] = col / width;
|
||
|
|
uv[i++] = row / height;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return uv;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get indices
|
||
|
|
* @param {(int)} width
|
||
|
|
* @param {(int)} height
|
||
|
|
**/
|
||
|
|
getIndices( width, height ) {
|
||
|
|
|
||
|
|
indices = [];
|
||
|
|
var i = 0;
|
||
|
|
|
||
|
|
for ( var row=0; row<height-1; row++ ) {
|
||
|
|
if ( (row&1)==0 ) { // even rows
|
||
|
|
for ( var col=0; col<width; col++ ) {
|
||
|
|
indices[i++] = col + row * width;
|
||
|
|
indices[i++] = col + (row+1) * width;
|
||
|
|
}
|
||
|
|
} else { // odd rows
|
||
|
|
for ( var col=width-1; col>0; 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; row<height-1; row++ ) {
|
||
|
|
if ( (row&1)==0 ) { // even rows
|
||
|
|
for ( var col=0; col<width; col++ ) {
|
||
|
|
indices[i++] = col + row * width;
|
||
|
|
indices[i++] = col + (row+1) * width;
|
||
|
|
}
|
||
|
|
} else { // odd rows
|
||
|
|
for ( var col=width-1; col>0; 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<height; row++ ) {
|
||
|
|
for ( var col=0; col<width; col++ ) {
|
||
|
|
vertices[i++] = col;
|
||
|
|
vertices[i++] = 0.0;
|
||
|
|
vertices[i++] = row;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return vertices;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create plane texture coordinates (Trianglestrip)
|
||
|
|
* @param {(int)} subdivisionsWidth
|
||
|
|
* @param {(int)} subdivisionsDepth
|
||
|
|
**/
|
||
|
|
createPlaneTriangleStripTextCoords(subdivisionsWidth, subdivisionsDepth){
|
||
|
|
var textCoords = new Float32Array(subdivisionsWidth * subdivisionsDepth * 2);
|
||
|
|
var index = 0;
|
||
|
|
|
||
|
|
for(var y=0; y<subdivisionsDepth; y++) {
|
||
|
|
for(var x=0; x<subdivisionsWidth; x++) {
|
||
|
|
var u = x / subdivisionsWidth;
|
||
|
|
var v = y / subdivisionsDepth;
|
||
|
|
|
||
|
|
textCoords[index++] = u;
|
||
|
|
textCoords[index++] = v;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return textCoords;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create cube
|
||
|
|
* @param {(int)} size
|
||
|
|
**/
|
||
|
|
createCube(size) {
|
||
|
|
|
||
|
|
var vertices = [
|
||
|
|
// Front face
|
||
|
|
-size, -size, size,
|
||
|
|
size, -size, size,
|
||
|
|
size, size, size,
|
||
|
|
-size, size, size,
|
||
|
|
|
||
|
|
// Back face
|
||
|
|
-size, -size, -size,
|
||
|
|
-size, size, -size,
|
||
|
|
size, size, -size,
|
||
|
|
size, -size, -size,
|
||
|
|
|
||
|
|
// Top face
|
||
|
|
-size, size, -size,
|
||
|
|
-size, size, size,
|
||
|
|
size, size, size,
|
||
|
|
size, size, -size,
|
||
|
|
|
||
|
|
// Bottom face
|
||
|
|
-size, -size, -size,
|
||
|
|
size, -size, -size,
|
||
|
|
size, -size, size,
|
||
|
|
-size, -size, size,
|
||
|
|
|
||
|
|
// Right face
|
||
|
|
size, -size, -size,
|
||
|
|
size, size, -size,
|
||
|
|
size, size, size,
|
||
|
|
size, -size, size,
|
||
|
|
|
||
|
|
// Left face
|
||
|
|
-size, -size, -size,
|
||
|
|
-size, -size, size,
|
||
|
|
-size, size, size,
|
||
|
|
-size, size, -size,
|
||
|
|
];
|
||
|
|
|
||
|
|
var normals = [
|
||
|
|
// Front face
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
|
||
|
|
// Back face
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
|
||
|
|
// Top face
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
|
||
|
|
// Bottom face
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
|
||
|
|
// Right face
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
|
||
|
|
// Left face
|
||
|
|
-1.0, 0.0, 0.0,
|
||
|
|
-1.0, 0.0, 0.0,
|
||
|
|
-1.0, 0.0, 0.0,
|
||
|
|
-1.0, 0.0, 0.0
|
||
|
|
];
|
||
|
|
|
||
|
|
var texturecoords = [
|
||
|
|
// Front face
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
|
||
|
|
// Back face
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
|
||
|
|
// Top face
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
|
||
|
|
// Bottom face
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
|
||
|
|
// Right face
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
|
||
|
|
// Left face
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0
|
||
|
|
];
|
||
|
|
|
||
|
|
var indices = [
|
||
|
|
0, 1, 2, 0, 2, 3, // Front face
|
||
|
|
4, 5, 6, 4, 6, 7, // Back face
|
||
|
|
8, 9, 10, 8, 10, 11, // Top face
|
||
|
|
12, 13, 14, 12, 14, 15, // Bottom face
|
||
|
|
16, 17, 18, 16, 18, 19, // Right face
|
||
|
|
20, 21, 22, 20, 22, 23 // Left face
|
||
|
|
];
|
||
|
|
|
||
|
|
|
||
|
|
var currentMesh = new mesh( );
|
||
|
|
|
||
|
|
currentMesh.setViewport(this.viewport);
|
||
|
|
|
||
|
|
currentMesh.createMeshFromArrays( indices, vertices, normals, texturecoords );
|
||
|
|
|
||
|
|
|
||
|
|
return currentMesh;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create cube
|
||
|
|
* @param {(int)} size
|
||
|
|
**/
|
||
|
|
createCubeFromBoundingbox( boundingbox, size ) {
|
||
|
|
console.log(boundingbox, "omg");
|
||
|
|
|
||
|
|
var maxExtend = boundingbox.maxExtent;
|
||
|
|
var minExtend = boundingbox.minExtent;
|
||
|
|
|
||
|
|
var vertices = [
|
||
|
|
// Front face
|
||
|
|
minExtend[0], minExtend[1], maxExtend[2],
|
||
|
|
maxExtend[0], minExtend[1], maxExtend[2],
|
||
|
|
maxExtend[0], maxExtend[1], maxExtend[2],
|
||
|
|
minExtend[0], maxExtend[1], maxExtend[2],
|
||
|
|
|
||
|
|
// Back face
|
||
|
|
minExtend[0], minExtend[1], minExtend[2],
|
||
|
|
minExtend[0], maxExtend[1], minExtend[2],
|
||
|
|
maxExtend[0], maxExtend[1], minExtend[2],
|
||
|
|
maxExtend[0], minExtend[1], minExtend[2],
|
||
|
|
|
||
|
|
// Top face
|
||
|
|
minExtend[0], maxExtend[1], minExtend[2],
|
||
|
|
minExtend[0], maxExtend[1], maxExtend[2],
|
||
|
|
maxExtend[0], maxExtend[1], maxExtend[2],
|
||
|
|
maxExtend[0], maxExtend[1], minExtend[2],
|
||
|
|
|
||
|
|
// Bottom face
|
||
|
|
minExtend[0], minExtend[1], minExtend[2],
|
||
|
|
maxExtend[0], minExtend[1], minExtend[2],
|
||
|
|
maxExtend[0], minExtend[1], maxExtend[2],
|
||
|
|
minExtend[0], minExtend[1], maxExtend[2],
|
||
|
|
|
||
|
|
// Right face
|
||
|
|
maxExtend[0], minExtend[1], minExtend[2],
|
||
|
|
maxExtend[0], maxExtend[1], minExtend[2],
|
||
|
|
maxExtend[0], maxExtend[1], maxExtend[2],
|
||
|
|
maxExtend[0], minExtend[1], maxExtend[2],
|
||
|
|
|
||
|
|
// Left face
|
||
|
|
minExtend[0], minExtend[1], minExtend[2],
|
||
|
|
minExtend[0], minExtend[1], maxExtend[2],
|
||
|
|
minExtend[0], maxExtend[1], maxExtend[2],
|
||
|
|
minExtend[0], maxExtend[1], minExtend[2],
|
||
|
|
];
|
||
|
|
|
||
|
|
var normals = [
|
||
|
|
// Front face
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
0.0, 0.0, 1.0,
|
||
|
|
|
||
|
|
// Back face
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
0.0, 0.0, -1.0,
|
||
|
|
|
||
|
|
// Top face
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
0.0, 1.0, 0.0,
|
||
|
|
|
||
|
|
// Bottom face
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
0.0, -1.0, 0.0,
|
||
|
|
|
||
|
|
// Right face
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
1.0, 0.0, 0.0,
|
||
|
|
|
||
|
|
// Left face
|
||
|
|
-1.0, 0.0, 0.0,
|
||
|
|
-1.0, 0.0, 0.0,
|
||
|
|
-1.0, 0.0, 0.0,
|
||
|
|
-1.0, 0.0, 0.0
|
||
|
|
];
|
||
|
|
|
||
|
|
var texturecoords = [
|
||
|
|
// Front face
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
|
||
|
|
// Back face
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
|
||
|
|
// Top face
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
|
||
|
|
// Bottom face
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
|
||
|
|
// Right face
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
|
||
|
|
// Left face
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0
|
||
|
|
];
|
||
|
|
|
||
|
|
var indices = [
|
||
|
|
0, 1, 2, 0, 2, 3, // Front face
|
||
|
|
4, 5, 6, 4, 6, 7, // Back face
|
||
|
|
8, 9, 10, 8, 10, 11, // Top face
|
||
|
|
12, 13, 14, 12, 14, 15, // Bottom face
|
||
|
|
16, 17, 18, 16, 18, 19, // Right face
|
||
|
|
20, 21, 22, 20, 22, 23 // Left face
|
||
|
|
];
|
||
|
|
|
||
|
|
|
||
|
|
var mesh = new mesh();
|
||
|
|
|
||
|
|
mesh.createMeshFromArrays( indices, vertices, normals, texturecoords );
|
||
|
|
|
||
|
|
|
||
|
|
return mesh;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export {primitives as default};
|