diff options
Diffstat (limited to 'js/lib/geom/shape-primitive.js')
-rw-r--r-- | js/lib/geom/shape-primitive.js | 128 |
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 | ||
52 | ShapePrimitive.getBounds = function( prim ) | 52 | ShapePrimitive.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 | |||
74 | ShapePrimitive.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 | |||
79 | if (typeof exports === "object") { | 207 | if (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 |