/* This file contains proprietary software owned by Motorola Mobility, Inc.
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
*/ var RDGE = RDGE || {}; RDGE.renderUtils = RDGE.renderUtils || {}; /* * Creates an indexed box primitive * @return a rdge primitive */ RDGE.renderUtils.createBox = function () { var renderer = RDGE.globals.engine.getContext().renderer; var coords = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // front 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // right 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // top -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // left -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // bottom 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1]; // back var normals = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // right 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // top -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // left 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // bottom 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1]; // back var uvs = [1, 1, 0, 1, 0, 0, 1, 0, // front 0, 1, 0, 0, 1, 0, 1, 1, // right 1, 0, 1, 1, 0, 1, 0, 0, // top 1, 1, 0, 1, 0, 0, 1, 0, // left 0, 0, 1, 0, 1, 1, 0, 1, // bottom 0, 0, 1, 0, 1, 1, 0, 1]; // back var indices = [0, 1, 2, 0, 2, 3, // front 4, 5, 6, 4, 6, 7, // right 8, 9, 10, 8, 10, 11, // top 12, 13, 14, 12, 14, 15, // left 16, 17, 18, 16, 18, 19, // bottom 20, 21, 22, 20, 22, 23]; // back var prim = new RDGE.rdgePrimitiveDefinition(); prim.vertexDefinition = { "vert": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_pos": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "normal": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex': 1, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_nrm": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex': 1, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "texcoord": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex': 2, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_uv": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex': 2, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC } }; prim.bufferStreams = [ coords, normals, uvs ]; prim.streamUsage = [ RDGE.rdgeConstants.BUFFER_STATIC, RDGE.rdgeConstants.BUFFER_STATIC, RDGE.rdgeConstants.BUFFER_STATIC ]; prim.indexUsage = RDGE.rdgeConstants.BUFFER_STREAM; prim.indexBuffer = indices; prim.type = RDGE.rdgeConstants.TRIANGLES; renderer.createPrimitive(prim); return prim; }; // // makeSphere // // Create a sphere with the passed number of latitude and longitude bands and the passed radius. // Sphere has vertices, normals and texCoords. Create VBOs for each as well as the index array. // Return an object with the following properties: // // normalObject WebGLBuffer object for normals // texCoordObject WebGLBuffer object for texCoords // vertexObject WebGLBuffer object for vertices // indexObject WebGLBuffer object for indices // numIndices The number of indices in the indexObject // RDGE.renderUtils.makeSphere = function (ctx, radius, lats, longs) { var geometryData = []; var normalData = []; var texCoordData = []; var indexData = []; for (var latNumber = 0; latNumber <= lats; ++latNumber) { for (var longNumber = 0; longNumber <= longs; ++longNumber) { var theta = latNumber * Math.PI / lats; var phi = longNumber * 2 * Math.PI / longs; var sinTheta = Math.sin(theta); var sinPhi = Math.sin(phi); var cosTheta = Math.cos(theta); var cosPhi = Math.cos(phi); var x = cosPhi * sinTheta; var y = cosTheta; var z = sinPhi * sinTheta; var u = 1 - (longNumber / longs); var v = latNumber / lats; normalData.push(x); normalData.push(y); normalData.push(z); texCoordData.push(u); texCoordData.push(v); geometryData.push(radius * x); geometryData.push(radius * y); geometryData.push(radius * z); } } for (var latNumber = 0; latNumber < lats; ++latNumber) { for (var longNumber = 0; longNumber < longs; ++longNumber) { var first = (latNumber * (longs + 1)) + longNumber; var second = first + longs + 1; indexData.push(first); indexData.push(second); indexData.push(first + 1); indexData.push(second); indexData.push(second + 1); indexData.push(first + 1); } } var retval = {}; retval.normalObject = ctx.createBuffer(); ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject); ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(normalData), ctx.STATIC_DRAW); retval.texCoordObject = ctx.createBuffer(); ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject); ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(texCoordData), ctx.STATIC_DRAW); retval.vertexObject = ctx.createBuffer(); ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject); ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(geometryData), ctx.STATIC_DRAW); retval.numIndices = indexData.length; retval.indexObject = ctx.createBuffer(); ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject); ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), ctx.STREAM_DRAW); return retval; }; /* * Creates a plane as a grid of triangles/quads, orients the plane according the the plane normal * note: the center of the plane is always assumed to be the origin. */ RDGE.renderUtils.createPlane = function (numCols, numRows, width, height, uTileCount, vTileCount, planeNormal) { var renderer = RDGE.globals.engine.getContext().renderer; var pn = [0, 1, 0]; if (!planeNormal) pn = planeNormal; var coords = new Array(numCols * numRows * 3); var normals = new Array(numCols * numRows * 3); var uvs = new Array(numCols * numRows * 2); var indices = new Array(numCols * numRows); // setup the vertices's in a grid and on the plane var coordIdx = 0; var uvIdx = 0; for (var row = 0; row < numRows; ++row) { for (var col = 0; col < numCols; ++col) { coords[coordIdx] = col * width - (numCols - 1) * width * 0.5; coords[coordIdx + 1] = 0; coords[coordIdx + 2] = row * height - (numRows - 1) * height * 0.5; normals[coordIdx] = planeNormal[0]; normals[coordIdx + 1] = planeNormal[1]; normals[coordIdx + 2] = planeNormal[2]; uvs[uvIdx] = col / numCols * uTileCount; uvs[uvIdx + 1] = row / numRows * vTileCount; coordIdx += 3; uvIdx += 2; } } // take the grid of vertices's and create triangles var k = 0; for (var row = 0; row < numRows; ++row) { for (var col = 0; col < numCols; ++col) { // layout both triangles of the quad indices[k + 2] = row * numCols + col; indices[k + 1] = row * numCols + (col + 1); indices[k] = (row + 1) * numCols + col; indices[k + 5] = (row + 1) * numCols + col; indices[k + 4] = row * numCols + (col + 1); indices[k + 3] = (row + 1) * numCols + (col + 1); k += 6; } } // reorient to plane normal var prim = new RDGE.rdgePrimitiveDefinition(); prim.vertexDefinition = { "vert": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_pos": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "normal": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex': 1, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_nrm": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex': 1, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "texcoord": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex': 2, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_uv": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex': 2, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC } }; prim.bufferStreams = [ coords, normals, uvs ]; prim.streamUsage = [ RDGE.rdgeConstants.BUFFER_STATIC, RDGE.rdgeConstants.BUFFER_STATIC, RDGE.rdgeConstants.BUFFER_STATIC ]; prim.indexUsage = RDGE.rdgeConstants.BUFFER_STREAM; prim.indexBuffer = indices; prim.type = RDGE.rdgeConstants.TRIANGLES; renderer.createPrimitive(prim); return prim; }; // creates a cubic volume of points RDGE.renderUtils.createCubeVolume = function (numCols_x, numLayers_y, numRows_z, x_interval, y_interval, z_interval, optPointsOut) { var renderer = RDGE.globals.engine.getContext().renderer; var coords = new Array(numCols_x * numRows_z * numLayers_y * 3); var indices = new Array(numCols_x * numRows_z * numLayers_y); var layerSize = numCols_x * numRows_z * 3; var coordIdx = 0; var idx = 0; for (var layer = 0; layer < numLayers_y; ++layer) { for (var row = 0; row < numRows_z; ++row) { for (var col = 0; col < numCols_x; ++col) { coords[coordIdx] = col * x_interval - (numCols_x - 1) * x_interval * 0.5; coords[coordIdx + 1] = layer * y_interval - (numLayers_y - 1) * y_interval * 0.5; coords[coordIdx + 2] = row * z_interval - (numRows_z - 1) * z_interval * 0.5; coordIdx += 3; indices.push(idx++); } } } if (optPointsOut) { optPointsOut = coords.slice(); } var prim = new RDGE.rdgePrimitiveDefinition(); prim.vertexDefinition = { "a_pos": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC } }; prim.bufferStreams = [ coords ]; prim.streamUsage = [ RDGE.rdgeConstants.BUFFER_DYNAMIC ]; prim.indexUsage = RDGE.rdgeConstants.BUFFER_STREAM; prim.indexBuffer = indices; prim.type = RDGE.rdgeConstants.POINTS; prim.useDoubleBuffer = true; renderer.createPrimitive(prim); return prim; }; RDGE.renderUtils.createScreenAlignedQuad = function () { var renderer = RDGE.globals.engine.getContext().renderer; // Screen aligned quad var coords = [ -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0 ]; var uvs = [0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]; var prim = new RDGE.rdgePrimitiveDefinition(); prim.vertexDefinition = { "vert": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_pos": { 'type': RDGE.rdgeConstants.VS_ELEMENT_POS, 'bufferIndex': 0, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "texcoord": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex': 1, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC }, "a_uv": { 'type': RDGE.rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex': 1, 'bufferUsage': RDGE.rdgeConstants.BUFFER_STATIC } }; prim.bufferStreams = [ coords, uvs ]; prim.streamUsage = [ RDGE.rdgeConstants.BUFFER_STATIC, RDGE.rdgeConstants.BUFFER_STATIC ]; prim.type = RDGE.rdgeConstants.TRIANGLES; renderer.createPrimitive(prim); return prim; };