aboutsummaryrefslogtreecommitdiff
path: root/js/lib/geom/shape-primitive.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/lib/geom/shape-primitive.js')
-rw-r--r--js/lib/geom/shape-primitive.js463
1 files changed, 321 insertions, 142 deletions
diff --git a/js/lib/geom/shape-primitive.js b/js/lib/geom/shape-primitive.js
index 34db60e8..e3ff9c06 100644
--- a/js/lib/geom/shape-primitive.js
+++ b/js/lib/geom/shape-primitive.js
@@ -32,106 +32,319 @@ POSSIBILITY OF SUCH DAMAGE.
32var ShapePrimitive = {}; 32var ShapePrimitive = {};
33 33
34ShapePrimitive.create = function(coords, normals, uvs, indices, primType, vertexCount) { 34ShapePrimitive.create = function(coords, normals, uvs, indices, primType, vertexCount) {
35 var renderer = RDGE.globals.engine.getContext().renderer; 35 var renderer = RDGE.globals.engine.getContext().renderer;
36 36
37 // to setup a primitive you must define it 37 // to setup a primitive you must define it
38 // create a new primitive definition here to then fill out 38 // create a new primitive definition here to then fill out
39 var prim = new RDGE.rdgePrimitiveDefinition(); 39 var prim = new RDGE.rdgePrimitiveDefinition();
40 40
41 // the vertex definition declares how the data will be delivered to the shader 41 // the vertex definition declares how the data will be delivered to the shader
42 // the position of an element in array determines which attribute in a shader the 42 // the position of an element in array determines which attribute in a shader the
43 // data is bound to 43 // data is bound to
44 prim.vertexDefinition = { 44 prim.vertexDefinition = {
45 // this shows two ways to map this data to an attribute 45 // this shows two ways to map this data to an attribute
46 "vert":{'type':renderer.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': renderer.BUFFER_STATIC}, 46 "vert":{'type':renderer.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': renderer.BUFFER_STATIC},
47 "a_pos":{'type':renderer.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': renderer.BUFFER_STATIC}, 47 "a_pos":{'type':renderer.VS_ELEMENT_POS, 'bufferIndex':0, 'bufferUsage': renderer.BUFFER_STATIC},
48 48
49 "normal":{'type':renderer.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': renderer.BUFFER_STATIC}, 49 "normal":{'type':renderer.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': renderer.BUFFER_STATIC},
50 "a_nrm":{'type':renderer.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': renderer.BUFFER_STATIC}, 50 "a_nrm":{'type':renderer.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': renderer.BUFFER_STATIC},
51 "a_normal":{'type':renderer.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': renderer.BUFFER_STATIC}, 51 "a_normal":{'type':renderer.VS_ELEMENT_FLOAT3, 'bufferIndex':1, 'bufferUsage': renderer.BUFFER_STATIC},
52 52
53 "texcoord":{'type':renderer.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': renderer.BUFFER_STATIC}, 53 "texcoord":{'type':renderer.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': renderer.BUFFER_STATIC},
54 "a_texcoord":{'type':renderer.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': renderer.BUFFER_STATIC} 54 "a_texcoord":{'type':renderer.VS_ELEMENT_FLOAT2, 'bufferIndex':2, 'bufferUsage': renderer.BUFFER_STATIC}
55 }; 55 };
56 56
57 // the actual data that correlates to the vertex definition 57 // the actual data that correlates to the vertex definition
58 prim.bufferStreams = [ coords, normals, uvs ]; 58 prim.bufferStreams = [ coords, normals, uvs ];
59 59
60 // what type of buffers the data resides in, static is the most common case 60 // what type of buffers the data resides in, static is the most common case
61 prim.streamUsage = [ renderer.BUFFER_STATIC, renderer.BUFFER_STATIC, renderer.BUFFER_STATIC ]; 61 prim.streamUsage = [ renderer.BUFFER_STATIC, renderer.BUFFER_STATIC, renderer.BUFFER_STATIC ];
62 62
63 // this tells the renderer to draw the primitive as a list of triangles 63 // this tells the renderer to draw the primitive as a list of triangles
64 prim.type = primType; 64 prim.type = primType;
65 65
66 prim.indexUsage = renderer.BUFFER_STREAM; 66 prim.indexUsage = renderer.BUFFER_STREAM;
67 prim.indexBuffer = indices; 67 prim.indexBuffer = indices;
68 68
69 // finally the primitive is created, buffers are generated and the system determines 69 // finally the primitive is created, buffers are generated and the system determines
70 // the data it needs to draw this primitive according to the previous definition 70 // the data it needs to draw this primitive according to the previous definition
71 renderer.createPrimitive(prim, vertexCount); 71 renderer.createPrimitive(prim, vertexCount);
72 72
73 return prim; 73 return prim;
74}; 74};
75 75
76ShapePrimitive.getMeshBounds = function( verts, nVerts ) 76ShapePrimitive.getMeshBounds = function( verts, nVerts )
77{ 77{
78 if (!verts || (nVerts <= 0)) return null; 78 if (!verts || (nVerts <= 0)) return null;
79
80 var bounds = [verts[0], verts[1], verts[2], verts[0], verts[1], verts[2]];
81 var index = 3;
82 for (var i=1; i<nVerts; i++)
83 {
84 var x = verts[index], y = verts[index+1], z = verts[index+2];
85 index += 3;
86
87 if (x < bounds[0]) bounds[0] = x;
88 else if (x > bounds[3]) bounds[3] = x;
89 if (y < bounds[1]) bounds[1] = y;
90 else if (y > bounds[4]) bounds[4] = y;
91 if (z < bounds[2]) bounds[2] = z;
92 else if (z > bounds[5]) bounds[5] = z;
93 }
94
95 return bounds;
96};
79 97
80 var bounds = [verts[0], verts[1], verts[2], verts[0], verts[1], verts[2]]; 98ShapePrimitive.getBounds = function( prim )
81 var index = 3; 99{
82 for (var i=1; i<nVerts; i++) 100 var verts = prim.bufferStreams[0];
83 { 101 var nVerts = verts.length;
84 var x = verts[index], y = verts[index+1], z = verts[index+2]; 102 var xMin = verts[0], xMax = verts[0],
85 index += 3; 103 yMin = verts[1], yMax = verts[1],
104 zMin = verts[2], zMax = verts[2];
105
106 for (var index=3; index<verts.length; )
107 {
108 if (verts[index] < xMin) xMin = verts[index];
109 else if (verts[index] > xMax) xMax = verts[index];
110
111 index++;
112 if (verts[index] < yMin) yMin = verts[index];
113 else if (verts[index] > yMax) yMax = verts[index];
114
115 index++;
116 if (verts[index] < zMin) zMin = verts[index];
117 else if (verts[index] > zMax) zMax = verts[index];
118
119 index++;
120 }
121
122 return [xMin, yMin, zMin, xMax, yMax, zMax];
123};
124
125ShapePrimitive.refineMesh = function( verts, norms, uvs, indices, nVertices, paramRange, tolerance )
126{
127 var oldVrtCount = nVertices;
128
129 // get the param range
130 var pUMin = paramRange[0], pVMin = paramRange[1],
131 pUMax = paramRange[2], pVMax = paramRange[3];
132 var iTriangle = 0;
133 var nTriangles = indices.length/3;
134 var index = 0;
135 while (iTriangle < nTriangles)
136 {
137 // get the indices of the 3 vertices
138 var i0 = indices[index],
139 i1 = indices[index+1],
140 i2 = indices[index+2];
141
142 // get the uv values
143 //var vrtIndex = 3*iTriangle;
144 var iuv0 = 2 * i0,
145 iuv1 = 2 * i1,
146 iuv2 = 2 * i2;
147 var u0 = uvs[iuv0], v0 = uvs[iuv0+1],
148 u1 = uvs[iuv1], v1 = uvs[iuv1+1],
149 u2 = uvs[iuv2], v2 = uvs[iuv2+1];
150
151 // find the u and v range
152 var uMin = u0, vMin = v0;
153 if (u1 < uMin) uMin = u1; if (v1 < vMin) vMin = v1;
154 if (u2 < uMin) uMin = u2; if (v2 < vMin) vMin = v2;
155 var uMax = u0, vMax = v0;
156 if (u1 > uMax) uMax = u1; if (v1 > vMax) vMax = v1;
157 if (u2 > uMax) uMax = u2; if (v2 > vMax) vMax = v2;
158
159 // if the parameter range of the triangle is outside the
160 // desired parameter range, advance to the next polygon and continue
161 if ((uMin > pUMax) || (uMax < pUMin) || (vMin > pVMax) || (vMax < pVMin))
162 {
163 // go to the next triangle
164 iTriangle++;
165 index += 3;
166 }
167 else
168 {
169 // check thesize of the triangle in uv space. If small enough, advance
170 // to the next triangle. If not small enough, split the triangle into 3;
171 var du = Math.abs(uMax) - uMin, dv = Math.abs(vMax - vMin);
172 if ((du < tolerance) && (dv < tolerance))
173 {
174 iTriangle++;
175 index += 3;
176 }
177 else // split the triangle into 4 parts
178 {
179 //calculate the position of the new vertex
180 var iPt0 = 3 * i0,
181 iPt1 = 3 * i1,
182 iPt2 = 3 * i2;
183 var x0 = verts[iPt0], y0 = verts[iPt0+1], z0 = verts[iPt0+2],
184 x1 = verts[iPt1], y1 = verts[iPt1+1], z1 = verts[iPt1+2],
185 x2 = verts[iPt2], y2 = verts[iPt2+1], z2 = verts[iPt2+2];
186
187 // calculate the midpoints of the edges
188 var xA = (x0 + x1)/2.0, yA = (y0 + y1)/2.0, zA = (z0 + z1)/2.0,
189 xB = (x1 + x2)/2.0, yB = (y1 + y2)/2.0, zB = (z1 + z2)/2.0,
190 xC = (x2 + x0)/2.0, yC = (y2 + y0)/2.0, zC = (z2 + z0)/2.0;
191
192 // calculate the uv values of the new coordinates
193 var uA = (u0 + u1)/2.0, vA = (v0 + v1)/2.0,
194 uB = (u1 + u2)/2.0, vB = (v1 + v2)/2.0,
195 uC = (u2 + u0)/2.0, vC = (v2 + v0)/2.0;
196
197 // calculate the normals for the new points
198 var nx0 = norms[iPt0], ny0 = norms[iPt0+1], nz0 = norms[iPt0+2],
199 nx1 = norms[iPt1], ny1 = norms[iPt1+1], nz1 = norms[iPt1+2],
200 nx2 = norms[iPt2], ny2 = norms[iPt2+1], nz2 = norms[iPt2+2];
201 var nxA = (nx0 + nx1), nyA = (ny0 + ny1), nzA = (nz0 + nz1); var nrmA = VecUtils.vecNormalize(3, [nxA, nyA, nzA], 1.0 ),
202 nxB = (nx1 + nx2), nyB = (ny1 + ny2), nzB = (nz1 + nz2); var nrmB = VecUtils.vecNormalize(3, [nxB, nyB, nzB], 1.0 ),
203 nxC = (nx2 + nx0), nyC = (ny2 + ny0), nzC = (nz2 + nz0); var nrmC = VecUtils.vecNormalize(3, [nxC, nyC, nzC], 1.0 );
204
205 // push everything
206 verts.push(xA); verts.push(yA); verts.push(zA);
207 verts.push(xB); verts.push(yB); verts.push(zB);
208 verts.push(xC); verts.push(yC); verts.push(zC);
209 uvs.push(uA), uvs.push(vA);
210 uvs.push(uB), uvs.push(vB);
211 uvs.push(uC), uvs.push(vC);
212 norms.push(nrmA[0]); norms.push(nrmA[1]); norms.push(nrmA[2]);
213 norms.push(nrmB[0]); norms.push(nrmB[1]); norms.push(nrmB[2]);
214 norms.push(nrmC[0]); norms.push(nrmC[1]); norms.push(nrmC[2]);
215
216 // split the current triangle into 4
217 indices[index+1] = nVertices; indices[index+2] = nVertices+2;
218 indices.push(nVertices); indices.push(i1); indices.push(nVertices+1); nTriangles++;
219 indices.push(nVertices+1); indices.push(i2); indices.push(nVertices+2); nTriangles++;
220 indices.push(nVertices); indices.push(nVertices+1); indices.push(nVertices+2); nTriangles++;
221 nVertices += 3;
222
223 // by not advancing 'index', we examine the first of the 3 triangles generated above