Fork me on GitHub

API Documentation


Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 215 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 215 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 247 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 247 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 253 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 253 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 282 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 282 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 314 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 366 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 367 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 369 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 369 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 406 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name in jsdoc/symbols/src/src_extra_glge_md2.js.html, line: 406 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
  1 /*
  2 GLGE WebGL Graphics Engine
  3 Copyright (c) 2010, Paul Brunt
  4 All rights reserved.
  5 
  6 Redistribution and use in source and binary forms, with or without
  7 modification, are permitted provided that the following conditions are met:
  8     * Redistributions of source code must retain the above copyright
  9       notice, this list of conditions and the following disclaimer.
 10     * Redistributions in binary form must reproduce the above copyright
 11       notice, this list of conditions and the following disclaimer in the
 12       documentation and/or other materials provided with the distribution.
 13     * Neither the name of GLGE nor the
 14       names of its contributors may be used to endorse or promote products
 15       derived from this software without specific prior written permission.
 16 
 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20 DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 */
 28 
 29 /**
 30  * @fileOverview
 31  * @name glge_md2.js
 32  * @author me@paulbrunt.co.uk
 33  */
 34 
 35 
 36 (function(GLGE){
 37 
 38 /**
 39  * @name GLGE.MD2#md2AnimFinished
 40  * @event fired when the the animation has finished
 41  * @param {object} data
 42  */
 43 
 44 /**
 45 * @class A quake MD2 model class
 46 * @augments GLGE.Object
 47 */
 48 GLGE.MD2=function(uid){
 49 	this.MD2Started=+new Date;
 50 	this.setAnimation(new GLGE.AnimationVector);
 51 	GLGE.Object.call(this,uid);
 52 }
 53 GLGE.augment(GLGE.Object,GLGE.MD2);
 54 GLGE.MD2.prototype.loadingCache={};
 55 GLGE.MD2.prototype.headersCache={};
 56 GLGE.MD2.prototype.meshCache={};
 57 GLGE.MD2.prototype.MD2Animations={};
 58 GLGE.MD2.prototype.MD2StartFrame=0;
 59 GLGE.MD2.prototype.MD2EndFrame=0;
 60 GLGE.MD2.prototype.MD2Loop=true;
 61 GLGE.MD2.prototype.MD2AnimFinished=false;
 62 
 63 GLGE.MD2.prototype.headerNames=[
 64 "ident",
 65 "version",
 66 "skinwidth",
 67 "skinheight",
 68 "framesize",
 69 "num_skins",
 70 "num_xyz",
 71 "num_st",
 72 "num_tris",
 73 "num_glcmds",
 74 "num_frames",
 75 "ofs_skins",
 76 "ofs_st",
 77 "ofs_tris",
 78 "ofs_frames",
 79 "ofs_glcmds",
 80 "ofs_end"];
 81 
 82 GLGE.MD2.prototype.preNormals = [
 83   [-0.525731,  0.000000,  0.850651], [-0.442863,  0.238856,  0.864188], [-0.295242,  0.000000,  0.955423], 
 84   [-0.309017,  0.500000,  0.809017], [-0.162460,  0.262866,  0.951056], [ 0.000000,  0.000000,  1.000000], 
 85   [ 0.000000,  0.850651,  0.525731], [-0.147621,  0.716567,  0.681718], [ 0.147621,  0.716567,  0.681718], 
 86   [ 0.000000,  0.525731,  0.850651], [ 0.309017,  0.500000,  0.809017], [ 0.525731,  0.000000,  0.850651], 
 87   [ 0.295242,  0.000000,  0.955423], [ 0.442863,  0.238856,  0.864188], [ 0.162460,  0.262866,  0.951056], 
 88   [-0.681718,  0.147621,  0.716567], [-0.809017,  0.309017,  0.500000], [-0.587785,  0.425325,  0.688191], 
 89   [-0.850651,  0.525731,  0.000000], [-0.864188,  0.442863,  0.238856], [-0.716567,  0.681718,  0.147621], 
 90   [-0.688191,  0.587785,  0.425325], [-0.500000,  0.809017,  0.309017], [-0.238856,  0.864188,  0.442863], 
 91   [-0.425325,  0.688191,  0.587785], [-0.716567,  0.681718, -0.147621], [-0.500000,  0.809017, -0.309017], 
 92   [-0.525731,  0.850651,  0.000000], [ 0.000000,  0.850651, -0.525731], [-0.238856,  0.864188, -0.442863], 
 93   [ 0.000000,  0.955423, -0.295242], [-0.262866,  0.951056, -0.162460], [ 0.000000,  1.000000,  0.000000], 
 94   [ 0.000000,  0.955423,  0.295242], [-0.262866,  0.951056,  0.162460], [ 0.238856,  0.864188,  0.442863], 
 95   [ 0.262866,  0.951056,  0.162460], [ 0.500000,  0.809017,  0.309017], [ 0.238856,  0.864188, -0.442863], 
 96   [ 0.262866,  0.951056, -0.162460], [ 0.500000,  0.809017, -0.309017], [ 0.850651,  0.525731,  0.000000], 
 97   [ 0.716567,  0.681718,  0.147621], [ 0.716567,  0.681718, -0.147621], [ 0.525731,  0.850651,  0.000000], 
 98   [ 0.425325,  0.688191,  0.587785], [ 0.864188,  0.442863,  0.238856], [ 0.688191,  0.587785,  0.425325], 
 99   [ 0.809017,  0.309017,  0.500000], [ 0.681718,  0.147621,  0.716567], [ 0.587785,  0.425325,  0.688191], 
100   [ 0.955423,  0.295242,  0.000000], [ 1.000000,  0.000000,  0.000000], [ 0.951056,  0.162460,  0.262866], 
101   [ 0.850651, -0.525731,  0.000000], [ 0.955423, -0.295242,  0.000000], [ 0.864188, -0.442863,  0.238856], 
102   [ 0.951056, -0.162460,  0.262866], [ 0.809017, -0.309017,  0.500000], [ 0.681718, -0.147621,  0.716567], 
103   [ 0.850651,  0.000000,  0.525731], [ 0.864188,  0.442863, -0.238856], [ 0.809017,  0.309017, -0.500000], 
104   [ 0.951056,  0.162460, -0.262866], [ 0.525731,  0.000000, -0.850651], [ 0.681718,  0.147621, -0.716567], 
105   [ 0.681718, -0.147621, -0.716567], [ 0.850651,  0.000000, -0.525731], [ 0.809017, -0.309017, -0.500000], 
106   [ 0.864188, -0.442863, -0.238856], [ 0.951056, -0.162460, -0.262866], [ 0.147621,  0.716567, -0.681718], 
107   [ 0.309017,  0.500000, -0.809017], [ 0.425325,  0.688191, -0.587785], [ 0.442863,  0.238856, -0.864188],
108   [ 0.587785,  0.425325, -0.688191], [ 0.688191,  0.587785, -0.425325], [-0.147621,  0.716567, -0.681718], 
109   [-0.309017,  0.500000, -0.809017], [ 0.000000,  0.525731, -0.850651], [-0.525731,  0.000000, -0.850651], 
110   [-0.442863,  0.238856, -0.864188], [-0.295242,  0.000000, -0.955423], [-0.162460,  0.262866, -0.951056], 
111   [ 0.000000,  0.000000, -1.000000], [ 0.295242,  0.000000, -0.955423], [ 0.162460,  0.262866, -0.951056], 
112   [-0.442863, -0.238856, -0.864188], [-0.309017, -0.500000, -0.809017], [-0.162460, -0.262866, -0.951056], 
113   [ 0.000000, -0.850651, -0.525731], [-0.147621, -0.716567, -0.681718], [ 0.147621, -0.716567, -0.681718], 
114   [ 0.000000, -0.525731, -0.850651], [ 0.309017, -0.500000, -0.809017], [ 0.442863, -0.238856, -0.864188], 
115   [ 0.162460, -0.262866, -0.951056], [ 0.238856, -0.864188, -0.442863], [ 0.500000, -0.809017, -0.309017], 
116   [ 0.425325, -0.688191, -0.587785], [ 0.716567, -0.681718, -0.147621], [ 0.688191, -0.587785, -0.425325], 
117   [ 0.587785, -0.425325, -0.688191], [ 0.000000, -0.955423, -0.295242], [ 0.000000, -1.000000,  0.000000], 
118   [ 0.262866, -0.951056, -0.162460], [ 0.000000, -0.850651,  0.525731], [ 0.000000, -0.955423,  0.295242], 
119   [ 0.238856, -0.864188,  0.442863], [ 0.262866, -0.951056,  0.162460], [ 0.500000, -0.809017,  0.309017], 
120   [ 0.716567, -0.681718,  0.147621], [ 0.525731, -0.850651,  0.000000], [-0.238856, -0.864188, -0.442863], 
121   [-0.500000, -0.809017, -0.309017], [-0.262866, -0.951056, -0.162460], [-0.850651, -0.525731,  0.000000], 
122   [-0.716567, -0.681718, -0.147621], [-0.716567, -0.681718,  0.147621], [-0.525731, -0.850651,  0.000000], 
123   [-0.500000, -0.809017,  0.309017], [-0.238856, -0.864188,  0.442863], [-0.262866, -0.951056,  0.162460], 
124   [-0.864188, -0.442863,  0.238856], [-0.809017, -0.309017,  0.500000], [-0.688191, -0.587785,  0.425325], 
125   [-0.681718, -0.147621,  0.716567], [-0.442863, -0.238856,  0.864188], [-0.587785, -0.425325,  0.688191], 
126   [-0.309017, -0.500000,  0.809017], [-0.147621, -0.716567,  0.681718], [-0.425325, -0.688191,  0.587785], 
127   [-0.162460, -0.262866,  0.951056], [ 0.442863, -0.238856,  0.864188], [ 0.162460, -0.262866,  0.951056], 
128   [ 0.309017, -0.500000,  0.809017], [ 0.147621, -0.716567,  0.681718], [ 0.000000, -0.525731,  0.850651], 
129   [ 0.425325, -0.688191,  0.587785], [ 0.587785, -0.425325,  0.688191], [ 0.688191, -0.587785,  0.425325], 
130   [-0.955423,  0.295242,  0.000000], [-0.951056,  0.162460,  0.262866], [-1.000000,  0.000000,  0.000000], 
131   [-0.850651,  0.000000,  0.525731], [-0.955423, -0.295242,  0.000000], [-0.951056, -0.162460,  0.262866], 
132   [-0.864188,  0.442863, -0.238856], [-0.951056,  0.162460, -0.262866], [-0.809017,  0.309017, -0.500000], 
133   [-0.864188, -0.442863, -0.238856], [-0.951056, -0.162460, -0.262866], [-0.809017, -0.309017, -0.500000], 
134   [-0.681718,  0.147621, -0.716567], [-0.681718, -0.147621, -0.716567], [-0.850651,  0.000000, -0.525731], 
135   [-0.688191,  0.587785, -0.425325], [-0.587785,  0.425325, -0.688191], [-0.425325,  0.688191, -0.587785], 
136   [-0.425325, -0.688191, -0.587785], [-0.587785, -0.425325, -0.688191], [-0.688191, -0.587785, -0.425325]
137 ];
138 
139 GLGE.MD2.prototype.MD2FrameRate=6;
140 
141 /**
142 * Gets the absolute path given an import path and the path it's relative to
143 * @param {string} path the path to get the absolute path for
144 * @param {string} relativeto the path the supplied path is relativeto
145 * @returns {string} absolute path
146 * @private
147 */
148 GLGE.MD2.prototype.getAbsolutePath=function(path,relativeto){
149 	if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://"  || path.substr(0,7)=="https://"){
150 		return path;
151 	}
152 	else
153 	{
154 		if(!relativeto){
155 			relativeto=window.location.href;
156 		}
157 		if (relativeto.indexOf("://")==-1){
158 			return relativeto.slice(0,relativeto.lastIndexOf("/"))+"/"+path;
159 		}
160 		//find the path compoents
161 		var bits=relativeto.split("/");
162 		var domain=bits[2];
163 		var proto=bits[0];
164 		var initpath=[];
165 		for(var i=3;i<bits.length-1;i++){
166 			initpath.push(bits[i]);
167 		}
168 		//relative to domain
169 		if(path.substr(0,1)=="/"){
170 			initpath=[];
171 		}
172 		var locpath=path.split("/");
173 		for(var i=0;i<locpath.length;i++){
174 			if(locpath[i]=="..") initpath.pop();
175 				else if(locpath[i]!="") initpath.push(locpath[i]);
176 		}
177 		return proto+"//"+domain+"/"+initpath.join("/");
178 	}
179 }
180 
181 /**
182 * Sets the MD2 framerate
183 * @param {string} framerate the MD2 files framerate
184 */
185 GLGE.MD2.prototype.setMD2FrameRate=function(framerate){
186 	this.MD2FrameRate=framerate;
187 	return this;
188 }
189 
190 /**
191 * Should GLGE Generate the tangents for the model
192 * @param {boolean} value tflag inidcating auto generation of tangents
193 */
194 GLGE.MD2.prototype.setAutoTangents=function(value){
195 	this.doTangents=value;
196 	return this;
197 }
198 
199 /**
200 * Sets the MD2 animation
201 * @param {string} framerate the MD2 files framerate
202 */
203 GLGE.MD2.prototype.setMD2Animation=function(anim,loop){
204 	this.MD2Anim=anim;
205 	this.MD2AnimFinished=false;
206 	if(loop!=undefined) this.MD2Loop=loop;
207 	this.MD2Started=+new Date;
208 	if(this.MD2Animations[this.url] && this.MD2Animations[this.url][anim]){
209 		this.MD2LastAnimFrame=this.lastMD2Frame;
210 		var a=this.MD2Animations[this.url][anim];
211 		this.MD2StartFrame=a[0];
212 		this.MD2EndFrame=a[1];
213 	}
214 	return this;
215 }
216 
217 /**
218 * Gets a list of availalbe animations
219 * @returns {array} array
220 */
221 GLGE.MD2.prototype.getAnimations=function(){
222 	var animations=[];
223 	for(var name in this.MD2Animations[this.url]) animations.push(name);
224 	return animations;
225 }
226 
227 /**
228 * Sets the MD2 frame number
229 * @param {string} frame the frame to display
230 */
231 GLGE.MD2.prototype.setMD2Frame=function(frame){
232 	var totalframes=this.MD2EndFrame-this.MD2StartFrame+1;
233 	if(totalframes==0) return;
234 	if(this.MD2Loop){
235 		frame=frame%totalframes;
236 		var frame2=((Math.floor(frame)+1)%totalframes);
237 	}else{
238 		frame=Math.min(totalframes,frame);
239 		frame2=Math.min(totalframes,Math.floor(frame)+1);
240 		if(frame==totalframes && !this.MD2AnimFinished){
241 			this.MD2AnimFinished=true;
242 			this.fireEvent("md2AnimFinished",{});
243 		}
244 	}
245 	var framefrac=frame%1;
246 	if(frame<1 && this.MD2LastAnimFrame){
247 		frame=this.MD2LastAnimFrame-this.MD2StartFrame;
248 	}else{
249 		this.MD2LastAnimFrame=null;
250 		this.lastMD2Frame=Math.floor(frame)+this.MD2StartFrame;
251 	}
252 	this.setMeshFrame1(Math.floor(frame)+this.MD2StartFrame);
253 	this.setMeshFrame2(frame2+this.MD2StartFrame);
254 	this.setMeshBlendFactor(framefrac);
255 }
256 
257 GLGE.MD2.prototype.animate=function(now,nocache){
258 	if(!now) now=+new Date;
259 	if(this.header){
260 		var frame=(now-this.MD2Started)/1000*this.MD2FrameRate;
261 		this.setMD2Frame(frame);
262 	}
263 	GLGE.Object.prototype.animate.call(this,now,nocache);
264 }
265 
266 /**
267 * Sets the url of the MD2 model
268 * @param {string} url the url to the MD2 file
269 */
270 GLGE.MD2.prototype.setSrc=function(url,relativeTo){
271 	if(relativeTo) url=this.getAbsolutePath(url,relativeTo);
272 	this.url=url;
273 	
274 	//prevent the same model parsing multiple times
275 	if(this.loadingCache[this.url] && !this.headersCache[url]){
276 		var that=this;
277 		setTimeout(function(){that.setSrc(url)},15);
278 		return;
279 	}
280 	
281 	this.loadingCache[this.url]=true;
282 	if(this.headersCache[url]){
283 		this.header=this.headersCache[url];
284 		this.setMesh(this.meshCache[url]);
285 		if(this.MD2Anim) this.setMD2Animation(this.MD2Anim);
286 		this.fireEvent("loaded",{url:this.url});
287 		return;
288 	}
289 	
290 	var that=this;
291 	var xhr = new XMLHttpRequest();
292 	xhr.overrideMimeType('text/plain; charset=x-user-defined');
293 	xhr.open("GET", url, true);
294 	xhr.send(null);
295 	this.verts=[];
296 	this.normals=[];
297 	
298 	xhr.onreadystatechange = function (aEvt) {
299 		if (xhr.readyState == 4) {
300 			if(xhr.status == 200){
301 				response = xhr.responseText;
302 				if (response) {
303 					var buffer = new ArrayBuffer(response.length);
304 					var byteArray = new Uint8Array(buffer);
305 					var byteArray = [];
306 					for(var i=0;i<response.length;i++){
307 						byteArray[i]=response.charCodeAt(i) & 0xff;
308 					}
309 					that.bufferLoaded(byteArray);
310 				}
311 			}else{
312 				alert("Error loading page\n");
313 			}
314 		}
315 	};
316 }
317 
318 /**
319 * Called when the model has loaded
320 * @private
321 */
322 GLGE.MD2.prototype.bufferLoaded=function(byteArray){
323 	this.byteArray=byteArray;
324 	this.parseHeader();
325 	this.parseFrames();
326 	this.parseUVs();
327 	this.parseFaces();
328 	if(this.MD2Anim) this.setMD2Animation(this.MD2Anim,this.MD2Loop);
329 }
330 
331 /**
332 * Extract header info
333 * @private
334 */
335 GLGE.MD2.prototype.parseHeader=function(){
336 	this.header={};
337 	for (var i=0; i<this.headerNames.length; i++) {
338 		this.header[this.headerNames[i]]=this.getUint16At(i*4);
339 	}
340 	this.headersCache[this.url]=this.header;
341 }
342 /**
343 * get 16 bit int at location
344 345 * @private
346 */
347 GLGE.MD2.prototype.getUint16At=function(index){
348 	return this.byteArray[index]+this.byteArray[index+1]*256;
349 }
350 /**
351 * get 32 bit float at location
352 * @private
353 */
354 GLGE.MD2.prototype.getFloat32At=function(index){
355 	var b3=this.byteArray[index];
356 	var b2=this.byteArray[index+1];
357 	var b1=this.byteArray[index+2];
358 	var b0=this.byteArray[index+3];
359 	sign = 1 - (2 * (b0 >> 7)),
360 	exponent = (((b0 << 1) & 0xff) | (b1 >> 7)) - 127,
361 	mantissa = ((b1 & 0x7f) << 16) | (b2 << 8) | b3;
362 
363 	if (mantissa == 0 && exponent == -127) {
364 		return 0.0;
365 	}
366 
367 	if (exponent == -127) { // Denormalized
368 		return sign * mantissa * Math.pow(2, -126 - 23);
369 	}
370 
371 	return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
372 }
373 /**
374 * process the frame data
375 * @private
376 */
377 GLGE.MD2.prototype.parseFrames=function(){
378 	
379 	var vertsArray = this.byteArray;
380 	var startFrame=0;
381 	var MD2Animations={};
382 	for(var j=0;j<this.header.num_frames;j++){
383 		var scaleTrans=[
384 			this.getFloat32At(this.header.ofs_frames+j*this.header.framesize),
385 			this.getFloat32At(this.header.ofs_frames+4+j*this.header.framesize),
386 			this.getFloat32At(this.header.ofs_frames+8+j*this.header.framesize),
387 			this.getFloat32At(this.header.ofs_frames+12+j*this.header.framesize),
388 			this.getFloat32At(this.header.ofs_frames+16+j*this.header.framesize),
389 			this.getFloat32At(this.header.ofs_frames+20+j*this.header.framesize)
390 		];	
391 		var verts=[];
392 		var normals=[];
393 		var start=this.header.ofs_frames+24+j*this.header.framesize;
394 		var frameName="";
395 		for(var i=start;i<start+16;i++){
396 			if(vertsArray[i]==0) break;
397 			frameName+=String.fromCharCode(vertsArray[i]);
398 		}
399 		frameName=frameName.replace(/[0-9]/g,'');
400 		if(lastFrameName && frameName!=lastFrameName){
401 			MD2Animations[lastFrameName]=[startFrame,j-1];
402 			startFrame=j;
403 		}
404 		var lastFrameName=frameName;
405 		start=this.header.ofs_frames+40+j*this.header.framesize;
406 		for(var i=start;i<start+this.header.framesize-40;i=i+12){
407 			verts.push(vertsArray[i]*scaleTrans[0]+scaleTrans[3]);
408 			verts.push(vertsArray[i+1]*scaleTrans[1]+scaleTrans[4]);
409 			verts.push(vertsArray[i+2]*scaleTrans[2]+scaleTrans[5]);
410 			verts.push(vertsArray[i+4]*scaleTrans[0]+scaleTrans[3]);
411 			verts.push(vertsArray[i+5]*scaleTrans[1]+scaleTrans[4]);
412 			verts.push(vertsArray[i+6]*scaleTrans[2]+scaleTrans[5]);
413 			verts.push(vertsArray[i+8]*scaleTrans[0]+scaleTrans[3]);
414 			verts.push(vertsArray[i+9]*scaleTrans[1]+scaleTrans[4]);
415 			verts.push(vertsArray[i+10]*scaleTrans[2]+scaleTrans[5]);
416 			var n=this.preNormals[vertsArray[i+3]];
417 			if(!n) n=[0,0,1]; //sanity check
418 			normals.push(n[0]);normals.push(n[1]);normals.push(n[2]);
419 			n=this.preNormals[vertsArray[i+7]];
420 			if(!n) n=[0,0,1]; //sanity check
421 			normals.push(n[0]);normals.push(n[1]);normals.push(-n[2]);
422 			n=this.preNormals[vertsArray[i+11]];
423 			if(!n) n=[0,0,1]; //sanity check
424 			normals.push(n[0]);normals.push(n[1]);normals.push(n[2]);
425 		}
426 		this.verts[j]=verts;
427 		this.normals[j]=normals;
428 	}
429 	MD2Animations[lastFrameName]=[startFrame,j-2];
430 	this.MD2Animations[this.url]=MD2Animations;
431 }
432 /**
433 * Process the UV data
434 * @private
435 */
436 GLGE.MD2.prototype.parseUVs=function(){
437 	var uvs=[];
438 	var byteArray=this.byteArray;
439 	var start=this.header.ofs_st;
440 	for(var i=start;i<start+this.header.num_st*4;i=i+4){
441 		uvs.push(this.getUint16At(i)/this.header.skinwidth);
442 		uvs.push(1-this.getUint16At(i+2)/this.header.skinheight);
443 	}
444 	this.globaluvs=uvs;
445 }
446 /**
447 * parses the face data in the md2 file
448 * @private
449 */
450 GLGE.MD2.prototype.parseFaces=function(){
451 	var start=this.header.ofs_tris;
452 	var len=start+this.header.num_tris*12;
453 	var faces=[];
454 	var uvs=[];
455 	var verts=[];
456 	var normals=[];
457 	var idx=0;
458 	for(var i=start;i<len;i=i+12){
459 		faces.push(idx++);
460 		faces.push(idx++);
461 		faces.push(idx++);
462 		var n1=this.getUint16At(i);
463 		var n2=this.getUint16At(i+2);
464 		var	n3=this.getUint16At(i+4);
465 		for(var j=0;j<this.verts.length;j++){
466 			if(!verts[j]){verts[j]=[];normals[j]=[];}
467 			var v=this.verts[j];
468 			var n=this.normals[j];
469 			verts[j].push(v[n1*3]);
470 			verts[j].push(v[n1*3+1]);
471 			verts[j].push(v[n1*3+2]);
472 			normals[j].push(n[n1*3]);
473 			normals[j].push(n[n1*3+1]);
474 			normals[j].push(n[n1*3+2]);
475 			verts[j].push(v[n2*3]);
476 			verts[j].push(v[n2*3+1]);
477 			verts[j].push(v[n2*3+2]);
478 			normals[j].push(n[n2*3]);
479 			normals[j].push(n[n2*3+1]);
480 			normals[j].push(n[n2*3+2]);
481 			verts[j].push(v[n3*3]);
482 			verts[j].push(v[n3*3+1]);
483 			verts[j].push(v[n3*3+2]);
484 			normals[j].push(n[n3*3]);
485 			normals[j].push(n[n3*3+1]);
486 			normals[j].push(n[n3*3+2]);
487 		}
488 		uvs.push(this.globaluvs[this.getUint16At(i+6)*2]);
489 		uvs.push(this.globaluvs[this.getUint16At(i+6)*2+1]);
490 		uvs.push(this.globaluvs[this.getUint16At(i+8)*2]);
491 		uvs.push(this.globaluvs[this.getUint16At(i+8)*2+1]);
492 		uvs.push(this.globaluvs[this.getUint16At(i+10)*2]);
493 		uvs.push(this.globaluvs[this.getUint16At(i+10)*2+1]);
494 	}
495 	this.normals=normals;
496 	this.verts=verts;
497 	this.uvs=uvs;
498 	this.faces=faces;
499 	this.createMesh()
500 }
501 
502 /**
503 * creates the mesh
504 * @private
505 */
506 GLGE.MD2.prototype.createMesh=function(){
507 	var m=new GLGE.Mesh;
508 	var verts=this.verts;
509 	var normals=this.normals;
510 	var uvs=this.uvs;
511 	var faces=this.faces;
512 	for(var i=0;i<verts.length;i++){
513 		m.setPositions(verts[i],i).setNormals(normals[i],i);
514 	}
515 	if(this.doTangents){
516 		m.setUV(uvs).setFaces(faces);
517 	}else{
518 		m.setFaces(faces).setUV(uvs);
519 	}
520 	this.setMesh(m);
521 	this.meshCache[this.url]=m;
522 	this.fireEvent("loaded",{url:this.url});
523 }
524 
525 GLGE.Group.prototype.addMD2=GLGE.Group.prototype.addObject;
526 GLGE.Scene.prototype.addMD2=GLGE.Scene.prototype.addObject;
527 
528 
529 })(GLGE);