Skip to content

Commit 6ec29cb

Browse files
Evan LissoosEvan Lissoos
Evan Lissoos
authored and
Evan Lissoos
committed
Files
0 parents  commit 6ec29cb

13 files changed

+4865
-0
lines changed

TriMesh.js

+317
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
/**
2+
* @fileoverview TriMesh - A simple 3D surface mesh for use with WebGL
3+
* @author Eric Shaffer
4+
*/
5+
6+
/** Class implementing triangle surface mesh. */
7+
class TriMesh{
8+
/**
9+
* Initialize members of a TriMesh object
10+
*/
11+
constructor(){
12+
this.isLoaded = false;
13+
this.minXYZ=[0,0,0];
14+
this.maxXYZ=[0,0,0];
15+
16+
this.numFaces=0;
17+
this.numVertices=0;
18+
19+
// Allocate vertex array
20+
this.vBuffer = [];
21+
// Allocate triangle array
22+
this.fBuffer = [];
23+
// Allocate normal array
24+
this.nBuffer = [];
25+
// Allocate array for edges so we can draw wireframe
26+
this.eBuffer = [];
27+
// Allocate array for texture coordinates
28+
this.texcoordBuffer = [];
29+
30+
console.log("TriMesh: Allocated buffers");
31+
32+
// Get extension for 4 byte integer indices for drawElements
33+
var ext = gl.getExtension('OES_element_index_uint');
34+
if (ext ==null){
35+
alert("OES_element_index_uint is unsupported by your browser and terrain generation cannot proceed.");
36+
}
37+
else{
38+
console.log("OES_element_index_uint is supported!");
39+
}
40+
}
41+
42+
/**
43+
* Return if the JS arrays have been populated with mesh data
44+
*/
45+
loaded(){
46+
return this.isLoaded;
47+
}
48+
49+
/**
50+
* Populate the JS arrays by parsing a string containing an OBJ file
51+
* @param {string} text of an OBJ file
52+
*/
53+
loadFromOBJ(fileText)
54+
{
55+
56+
//Your code here
57+
//console.log(fileText);
58+
var line_split = fileText.split('\n');
59+
for(var i = 0; i < line_split.length; i++) {
60+
if(line_split[i] == 0)
61+
continue;
62+
else if(line_split[i][0] == '#')
63+
continue;
64+
else if(line_split[i][0] == 'v') {
65+
// Handle vertex
66+
var v_data = line_split[i].substring(2, line_split[i].length);
67+
var v_floats = v_data.split(' ');
68+
for(var j = 0; j < v_floats.length; j++) {
69+
var float = parseFloat(v_floats[j]);
70+
//console.log(float);
71+
this.vBuffer.push(float);
72+
}
73+
this.numVertices++;
74+
}
75+
else if(line_split[i][0] == 'f') {
76+
// Handle face
77+
var f_data = line_split[i].substring(2, line_split[i].length);
78+
var f_ints = f_data.split(' ');
79+
//console.log(f_ints);
80+
for(var j = 0; j < f_ints.length; j++) {
81+
var int = parseInt(f_ints[j]-1);
82+
//console.log(int);
83+
this.fBuffer.push(int);
84+
}
85+
this.numFaces++;
86+
}
87+
88+
}
89+
90+
91+
//----------------
92+
console.log("TriMesh: Loaded ", this.numFaces, " triangles.");
93+
console.log("TriMesh: Loaded ", this.numVertices, " vertices.");
94+
95+
this.generateNormals();
96+
console.log("TriMesh: Generated normals");
97+
98+
this.generateLines();
99+
console.log("TriMesh: Generated lines");
100+
101+
myMesh.loadBuffers();
102+
this.isLoaded = true;
103+
}
104+
105+
106+
/**
107+
* Send the buffer objects to WebGL for rendering
108+
*/
109+
loadBuffers()
110+
{
111+
// Specify the vertex coordinates
112+
this.VertexPositionBuffer = gl.createBuffer();
113+
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexPositionBuffer);
114+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.vBuffer), gl.STATIC_DRAW);
115+
this.VertexPositionBuffer.itemSize = 3;
116+
this.VertexPositionBuffer.numItems = this.numVertices;
117+
console.log("Loaded ", this.VertexPositionBuffer.numItems, " vertices");
118+
119+
// Specify normals to be able to do lighting calculations
120+
this.VertexNormalBuffer = gl.createBuffer();
121+
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexNormalBuffer);
122+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.nBuffer),
123+
gl.STATIC_DRAW);
124+
this.VertexNormalBuffer.itemSize = 3;
125+
this.VertexNormalBuffer.numItems = this.numVertices;
126+
console.log("Loaded ", this.VertexNormalBuffer.numItems, " normals");
127+
128+
// Specify faces of the terrain
129+
this.IndexTriBuffer = gl.createBuffer();
130+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexTriBuffer);
131+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(this.fBuffer),
132+
gl.STATIC_DRAW);
133+
this.IndexTriBuffer.itemSize = 1;
134+
this.IndexTriBuffer.numItems = this.fBuffer.length;
135+
console.log("Loaded ", this.IndexTriBuffer.numItems/3, " triangles");
136+
137+
//Setup Edges
138+
this.IndexEdgeBuffer = gl.createBuffer();
139+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexEdgeBuffer);
140+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(this.eBuffer),
141+
gl.STATIC_DRAW);
142+
this.IndexEdgeBuffer.itemSize = 1;
143+
this.IndexEdgeBuffer.numItems = this.eBuffer.length;
144+
}
145+
146+
/**
147+
* Render the triangles
148+
*/
149+
drawTriangles(){
150+
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexPositionBuffer);
151+
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, this.VertexPositionBuffer.itemSize,
152+
gl.FLOAT, false, 0, 0);
153+
154+
// Bind normal buffer
155+
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexNormalBuffer);
156+
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
157+
this.VertexNormalBuffer.itemSize,
158+
gl.FLOAT, false, 0, 0);
159+
160+
gl.activeTexture(gl.TEXTURE0);
161+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeMap);
162+
gl.uniform1i(gl.getUniformLocation(shaderProgram, "uCubeSampler"), 0);
163+
164+
//Draw
165+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexTriBuffer);
166+
gl.drawElements(gl.TRIANGLES, this.IndexTriBuffer.numItems, gl.UNSIGNED_INT,0);
167+
}
168+
169+
/**
170+
* Render the triangle edges wireframe style
171+
*/
172+
drawEdges(){
173+
174+
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexPositionBuffer);
175+
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, this.VertexPositionBuffer.itemSize,
176+
gl.FLOAT, false, 0, 0);
177+
178+
// Bind normal buffer
179+
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexNormalBuffer);
180+
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
181+
this.VertexNormalBuffer.itemSize,
182+
gl.FLOAT, false, 0, 0);
183+
184+
//Draw
185+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexEdgeBuffer);
186+
gl.drawElements(gl.LINES, this.IndexEdgeBuffer.numItems, gl.UNSIGNED_INT,0);
187+
}
188+
189+
190+
/**
191+
* Print vertices and triangles to console for debugging
192+
*/
193+
printBuffers()
194+
{
195+
196+
for(var i=0;i<this.numVertices;i++)
197+
{
198+
console.log("v ", this.vBuffer[i*3], " ",
199+
this.vBuffer[i*3 + 1], " ",
200+
this.vBuffer[i*3 + 2], " ");
201+
202+
}
203+
204+
for(var i=0;i<this.numFaces;i++)
205+
{
206+
console.log("f ", this.fBuffer[i*3], " ",
207+
this.fBuffer[i*3 + 1], " ",
208+
this.fBuffer[i*3 + 2], " ");
209+
210+
}
211+
212+
}
213+
214+
/**
215+
* Generates line values from faces in faceArray
216+
* to enable wireframe rendering
217+
*/
218+
generateLines()
219+
{
220+
var numTris=this.fBuffer.length/3;
221+
for(var f=0;f<numTris;f++)
222+
{
223+
var fid=f*3;
224+
this.eBuffer.push(this.fBuffer[fid]);
225+
this.eBuffer.push(this.fBuffer[fid+1]);
226+
227+
this.eBuffer.push(this.fBuffer[fid+1]);
228+
this.eBuffer.push(this.fBuffer[fid+2]);
229+
230+
this.eBuffer.push(this.fBuffer[fid+2]);
231+
this.eBuffer.push(this.fBuffer[fid]);
232+
}
233+
234+
}
235+
236+
237+
/**
238+
* Set the x,y,z coords of a vertex at location id
239+
* @param {number} the index of the vertex to set
240+
* @param {number} x coordinate
241+
* @param {number} y coordinate
242+
* @param {number} z coordinate
243+
*/
244+
setVertex(id,x,y,z){
245+
var vid = 3*id;
246+
this.vBuffer[vid]=x;
247+
this.vBuffer[vid+1]=y;
248+
this.vBuffer[vid+2]=z;
249+
}
250+
251+
/**
252+
* Return the x,y,z coords of a vertex at location id
253+
* @param {number} the index of the vertex to return
254+
* @param {Object} a length 3 array to populate withx,y,z coords
255+
*/
256+
getVertex(id, v){
257+
var vid = 3*id;
258+
v[0] = this.vBuffer[vid];
259+
v[1] = this.vBuffer[vid+1];
260+
v[2] = this.vBuffer[vid+2];
261+
}
262+
263+
/**
264+
* Compute per-vertex normals for a mesh
265+
*/
266+
generateNormals(){
267+
//per vertex normals
268+
this.numNormals = this.numVertices;
269+
this.nBuffer = new Array(this.numNormals*3);
270+
271+
for(var i=0;i<this.nBuffer.length;i++)
272+
{
273+
this.nBuffer[i]=0;
274+
}
275+
276+
for(var i=0;i<this.numFaces;i++)
277+
{
278+
// Get vertex coodinates
279+
var v1 = this.fBuffer[3*i];
280+
var v1Vec = vec3.fromValues(this.vBuffer[3*v1], this.vBuffer[3*v1+1], this.vBuffer[3*v1+2]);
281+
var v2 = this.fBuffer[3*i+1];
282+
var v2Vec = vec3.fromValues(this.vBuffer[3*v2], this.vBuffer[3*v2+1], this.vBuffer[3*v2+2]);
283+
var v3 = this.fBuffer[3*i+2];
284+
var v3Vec = vec3.fromValues(this.vBuffer[3*v3], this.vBuffer[3*v3+1], this.vBuffer[3*v3+2]);
285+
286+
// Create edge vectors
287+
var e1=vec3.create();
288+
vec3.subtract(e1,v2Vec,v1Vec);
289+
var e2=vec3.create();
290+
vec3.subtract(e2,v3Vec,v1Vec);
291+
292+
// Compute normal
293+
var n = vec3.fromValues(0,0,0);
294+
vec3.cross(n,e1,e2);
295+
296+
// Accumulate
297+
for(var j=0;j<3;j++){
298+
this.nBuffer[3*v1+j]+=n[j];
299+
this.nBuffer[3*v2+j]+=n[j];
300+
this.nBuffer[3*v3+j]+=n[j];
301+
}
302+
303+
}
304+
for(var i=0;i<this.numNormals;i++)
305+
{
306+
var n = vec3.fromValues(this.nBuffer[3*i],
307+
this.nBuffer[3*i+1],
308+
this.nBuffer[3*i+2]);
309+
vec3.normalize(n,n);
310+
this.nBuffer[3*i] = n[0];
311+
this.nBuffer[3*i+1]=n[1];
312+
this.nBuffer[3*i+2]=n[2];
313+
}
314+
}
315+
316+
317+
}

gl-matrix-min.js

+28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)