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.js128
1 files changed, 128 insertions, 0 deletions
diff --git a/js/lib/geom/shape-primitive.js b/js/lib/geom/shape-primitive.js
index 9864a8e9..858f38c8 100644
--- a/js/lib/geom/shape-primitive.js
+++ b/js/lib/geom/shape-primitive.js
@@ -51,6 +51,31 @@ ShapePrimitive.create = function(coords, normals, uvs, indices, primType, ver
51 51
52ShapePrimitive.getBounds = function( prim ) 52ShapePrimitive.getBounds = function( prim )
53{ 53{
54 if (!verts || (nVerts <= 0)) return null;
55
56 var bounds = [verts[0], verts[1], verts[2], verts[0], verts[1], verts[2]];
57 var index = 3;
58 for (var i=1; i<nVerts; i++)
59 {
60 var x = verts[index], y = verts[index+1], z = verts[index+2];
61 index += 3;
62
63 if (x < bounds[0]) bounds[0] = x;
64 else if (x > bounds[3]) bounds[3] = x;
65 if (y < bounds[1]) bounds[1] = y;
66 else if (y > bounds[4]) bounds[4] = y;
67 if (z < bounds[2]) bounds[2] = z;
68 else if (z > bounds[5]) bounds[5] = z;
69 }
70
71 return bounds;
72};
73
74ShapePrimitive.refineMesh = function( verts, norms, uvs, indices, nVertices, paramRange, tolerance )
75{
76 var oldVrtCount = nVertices;
77
78 // get the param range
54 var verts = prim.bufferStreams[0]; 79 var verts = prim.bufferStreams[0];
55 var nVerts = verts.length; 80 var nVerts = verts.length;
56 var xMin = verts[0], xMax = verts[0], 81 var xMin = verts[0], xMax = verts[0],
@@ -76,6 +101,109 @@ ShapePrimitive.getBounds = function( prim )
76 return [xMin, yMin, zMin, xMax, yMax, zMax]; 101 return [xMin, yMin, zMin, xMax, yMax, zMax];
77}; 102};
78 103
104 var pUMin = paramRange[0], pVMin = paramRange[1],
105 pUMax = paramRange[2], pVMax = paramRange[3];
106 var iTriangle = 0;
107 var nTriangles = indices.length/3;
108 var index = 0;
109 while (iTriangle < nTriangles)
110 {
111 // get the indices of the 3 vertices
112 var i0 = indices[index],
113 i1 = indices[index+1],
114 i2 = indices[index+2];
115
116 // get the uv values
117 //var vrtIndex = 3*iTriangle;
118 var iuv0 = 2 * i0,
119 iuv1 = 2 * i1,
120 iuv2 = 2 * i2;
121 var u0 = uvs[iuv0], v0 = uvs[iuv0+1],
122 u1 = uvs[iuv1], v1 = uvs[iuv1+1],
123 u2 = uvs[iuv2], v2 = uvs[iuv2+1];
124
125 // find the u and v range
126 var uMin = u0, vMin = v0;
127 if (u1 < uMin) uMin = u1; if (v1 < vMin) vMin = v1;
128 if (u2 < uMin) uMin = u2; if (v2 < vMin) vMin = v2;
129 var uMax = u0, vMax = v0;
130 if (u1 > uMax) uMax = u1; if (v1 > vMax) vMax = v1;
131 if (u2 > uMax) uMax = u2; if (v2 > vMax) vMax = v2;
132
133 // if the parameter range of the triangle is outside the
134 // desired parameter range, advance to the next polygon and continue
135 if ((uMin > pUMax) || (uMax < pUMin) || (vMin > pVMax) || (vMax < pVMin))
136 {
137 // go to the next triangle
138 iTriangle++;
139 index += 3;
140 }
141 else
142 {
143 // check thesize of the triangle in uv space. If small enough, advance
144 // to the next triangle. If not small enough, split the triangle into 3;
145 var du = uMax - uMin, dv = vMax - vMin;
146 if ((du < tolerance) && (dv < tolerance))
147 {
148 iTriangle++;
149 index += 3;
150 }
151 else // split the triangle into 4 parts
152 {
153 //calculate the position of the new vertex
154 var iPt0 = 3 * i0,
155 iPt1 = 3 * i1,
156 iPt2 = 3 * i2;
157 var x0 = verts[iPt0], y0 = verts[iPt0+1], z0 = verts[iPt0+2],
158 x1 = verts[iPt1], y1 = verts[iPt1+1], z1 = verts[iPt1+2],
159 x2 = verts[iPt2], y2 = verts[iPt2+1], z2 = verts[iPt2+2];
160
161 // calculate the midpoints of the edges
162 var xA = (x0 + x1)/2.0, yA = (y0 + y1)/2.0, zA = (z0 + z1)/2.0,
163 xB = (x1 + x2)/2.0, yB = (y1 + y2)/2.0, zB = (z1 + z2)/2.0,
164 xC = (x2 + x0)/2.0, yC = (y2 + y0)/2.0, zC = (z2 + z0)/2.0;
165
166 // calculate the uv values of the new coordinates
167 var uA = (u0 + u1)/2.0, vA = (v0 + v1)/2.0,
168 uB = (u1 + u2)/2.0, vB = (v1 + v2)/2.0,
169 uC = (u2 + u0)/2.0, vC = (v2 + v0)/2.0;
170
171 // calculate the normals for the new points
172 var nx0 = norms[iPt0], ny0 = norms[iPt0+1], nz0 = norms[iPt0+2],
173 nx1 = norms[iPt1], ny1 = norms[iPt1+1], nz1 = norms[iPt1+2],
174 nx2 = norms[iPt2], ny2 = norms[iPt2+1], nz2 = norms[iPt2+2];
175 var nxA = (nx0 + nx1), nyA = (ny0 + ny1), nzA = (nz0 + nz1); var nrmA = VecUtils.vecNormalize(3, [nxA, nyA, nzA], 1.0 ),
176 nxB = (nx1 + nx2), nyB = (ny1 + ny2), nzB = (nz1 + nz2); var nrmB = VecUtils.vecNormalize(3, [nxB, nyB, nzB], 1.0 ),
177 nxC = (nx2 + nx0), nyC = (ny2 + ny0), nzC = (nz2 + nz0); var nrmC = VecUtils.vecNormalize(3, [nxC, nyC, nzC], 1.0 );
178
179 // push everything
180 verts.push(xA); verts.push(yA); verts.push(zA);
181 verts.push(xB); verts.push(yB); verts.push(zB);
182 verts.push(xC); verts.push(yC); verts.push(zC);
183 uvs.push(uA), uvs.push(vA);
184 uvs.push(uB), uvs.push(vB);
185 uvs.push(uC), uvs.push(vC);
186 norms.push(nrmA[0]); norms.push(nrmA[1]); norms.push(nrmA[2]);
187 norms.push(nrmB[0]); norms.push(nrmB[1]); norms.push(nrmB[2]);
188 norms.push(nrmC[0]); norms.push(nrmC[1]); norms.push(nrmC[2]);
189
190 // split the current triangle into 4
191 indices[index+1] = nVertices; indices[index+2] = nVertices+2;
192 indices.push(nVertices); indices.push(i1); indices.push(nVertices+1); nTriangles++;
193 indices.push(nVertices+1); indices.push(i2); indices.push(nVertices+2); nTriangles++;
194 indices.push(nVertices); indices.push(nVertices+1); indices.push(nVertices+2); nTriangles++;
195 nVertices += 3;
196
197 // by not advancing 'index', we examine the first of the 3 triangles generated above
198 }
199 }
200 }
201
202 console.log( "refine mesh vertex count " + oldVrtCount + " => " + nVertices );
203 return nVertices;
204};
205
206
79if (typeof exports === "object") { 207if (typeof exports === "object") {
80 exports.ShapePrimitive = ShapePrimitive; 208 exports.ShapePrimitive = ShapePrimitive;
81} \ No newline at end of file 209} \ No newline at end of file