/* <copyright> This file contains proprietary software owned by Motorola Mobility, Inc.<br/> No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. </copyright> */ renderUtils = {} /* * Creates an indexed box primitive * @return a rdge primitive */ renderUtils.createBox = function() { var renderer = g_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 rdgePrimitiveDefinition(); prim.vertexDefinition= { "vert":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_pos":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "normal":{'type':rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_nrm":{'type':rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "texcoord":{'type':rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_uv":{'type':rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': rdgeConstants.BUFFER_STATIC} }; prim.bufferStreams= [ coords, normals, uvs ]; prim.streamUsage= [ rdgeConstants.BUFFER_STATIC, rdgeConstants.BUFFER_STATIC, rdgeConstants.BUFFER_STATIC ]; prim.indexUsage = rdgeConstants.BUFFER_STREAM; prim.indexBuffer = indices; prim.type = 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 // function makeSphere(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. */ function createPlane( numCols, numRows, width, height, uTileCount, vTileCount, planeNormal ) { var renderer = g_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 rdgePrimitiveDefinition(); prim.vertexDefinition= { "vert":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_pos":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "normal":{'type':rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_nrm":{'type':rdgeConstants.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "texcoord":{'type':rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_uv":{'type':rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': rdgeConstants.BUFFER_STATIC} }; prim.bufferStreams= [ coords, normals, uvs ]; prim.streamUsage= [ rdgeConstants.BUFFER_STATIC, rdgeConstants.BUFFER_STATIC, rdgeConstants.BUFFER_STATIC ]; prim.indexUsage = rdgeConstants.BUFFER_STREAM; prim.indexBuffer = indices; prim.type = rdgeConstants.TRIANGLES; renderer.createPrimitive(prim); return prim; } // creates a cubic volume of points function createCubeVolume( numCols_x, numLayers_y, numRows_z, x_interval, y_interval, z_interval, optPointsOut ) { var renderer = g_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 rdgePrimitiveDefinition(); prim.vertexDefinition= { "a_pos":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC} }; prim.bufferStreams= [ coords ]; prim.streamUsage= [ rdgeConstants.BUFFER_DYNAMIC ]; prim.indexUsage = rdgeConstants.BUFFER_STREAM; prim.indexBuffer = indices; prim.type = rdgeConstants.POINTS; prim.useDoubleBuffer = true; renderer.createPrimitive(prim); return prim; } function createScreenAlignedQuad() { var renderer = g_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 rdgePrimitiveDefinition(); prim.vertexDefinition= { "vert":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_pos":{'type':rdgeConstants.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "texcoord":{'type':rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex':1, 'bufferUsage': rdgeConstants.BUFFER_STATIC}, "a_uv":{'type':rdgeConstants.VS_ELEMENT_FLOAT2, 'bufferIndex':1, 'bufferUsage': rdgeConstants.BUFFER_STATIC} }; prim.bufferStreams= [ coords, uvs ]; prim.streamUsage= [ rdgeConstants.BUFFER_STATIC, rdgeConstants.BUFFER_STATIC ]; prim.type = rdgeConstants.TRIANGLES; renderer.createPrimitive(prim); return prim; }