1 tQuery.registerStatic('createMinecraftChar', function(opts){
  2 	return new tQuery.MinecraftChar(opts);
  3 });
  4 
  5 /**
  6  * original demo - http://djazz.mine.nu/lab/minecraft_items/
  7  * http://danielmcgraw.com/2010/10/06/How-To-Skin-Your-Minecraft-Character/
  8  * http://www.minecraftskins.com/
  9  * http://www.minecraftskins.info/
 10  * http://www.minecraftwiki.net/wiki/Anvil_file_format
 11  * 
 12  * http://www.minecraftwiki.net/wiki/File:Skintemplate.png
 13  * http://www.minershoes.com/
 14 */
 15 tQuery.registerStatic('MinecraftChar', function(opts){
 16 	opts	= tQuery.extend(opts, {
 17 		skinUrl	: tQuery.MinecraftChar.baseUrl + "examples/images/char.png"
 18 	});
 19 	
 20 	var tTexture	= THREE.ImageUtils.loadTexture( opts.skinUrl );
 21 	tTexture.magFilter	= THREE.NearestFilter;
 22 	tTexture.minFilter	= THREE.NearestFilter;
 23 	this._tTexture	= tTexture
 24 
 25 	var tMaterial	= new THREE.MeshBasicMaterial({
 26 		map	: tTexture
 27 	});
 28 	var tMaterialt	= new THREE.MeshBasicMaterial({
 29 		map		: tTexture,
 30 		transparent	: true,
 31 		side		: THREE.DoubleSide
 32 	});
 33 	//tMaterial.overdraw	= true;
 34 
 35 	//////////////////////////////////////////////////////////////////////////
 36 	// define size constant
 37 	var sizes	= {};
 38 	sizes.charH	= 1;
 39 	sizes.pixRatio	= 1/32;
 40 
 41 	sizes.headH	= 8  * sizes.pixRatio;
 42 	sizes.headW	= 8  * sizes.pixRatio;
 43 	sizes.headD	= 8  * sizes.pixRatio;
 44 
 45 	sizes.helmetH	= 9  * sizes.pixRatio;
 46 	sizes.helmetW	= 9  * sizes.pixRatio;
 47 	sizes.helmetD	= 9  * sizes.pixRatio;
 48 
 49 	sizes.bodyH	= 12 * sizes.pixRatio;
 50 	sizes.bodyW	=  8 * sizes.pixRatio;
 51 	sizes.bodyD	=  4 * sizes.pixRatio;
 52 
 53 	sizes.legH	= 12 * sizes.pixRatio;
 54 	sizes.legW	=  4 * sizes.pixRatio;
 55 	sizes.legD	=  4 * sizes.pixRatio;
 56 
 57 	sizes.armH	= 12 * sizes.pixRatio;
 58 	sizes.armW	=  4 * sizes.pixRatio;
 59 	sizes.armD	=  4 * sizes.pixRatio;
 60 
 61 
 62 	// build model core hierachy
 63 	// - origin between 2 feet
 64 	// - height of full character is 1
 65 	var model	= {}
 66 	model.root	= tQuery.createObject3D();
 67 	model.headGroup	= tQuery.createObject3D().addTo(model.root)
 68 				.translateY(sizes.charH - sizes.headH);
 69 	
 70 
 71 	// visualize the texture - good for debug
 72 	if( false ){
 73 		tQuery.createPlane(64/32, 32/32, tMaterial).addTo(model.root)
 74 			.translateX(1.5)
 75 	}
 76 
 77 
 78 	// build model.head
 79 	model.head	= tQuery.createCube(sizes.headW, sizes.headH, sizes.headD, tMaterial)
 80 				.addTo(model.headGroup)
 81 				.geometry()
 82 					.translateY(sizes.headH/2)
 83 					.back()
 84 	var tGeometry	= model.head.geometry().get(0);
 85 	mapUv(tGeometry, 0, 16, 24, 24, 16)	// left
 86 	mapUv(tGeometry, 1,  0, 24,  8, 16)	// right
 87 	mapUv(tGeometry, 2,  8, 32, 16, 24)	// top
 88 	mapUv(tGeometry, 3, 16, 32, 24, 24)	// bottom
 89 	mapUv(tGeometry, 4,  8, 24, 16, 16)	// front
 90 	mapUv(tGeometry, 5, 24, 24, 32, 16)	// back
 91 	
 92 	// // build model.helmet
 93 	model.helmet	= tQuery.createCube(sizes.helmetH, sizes.helmetH, sizes.helmetH, tMaterialt)
 94 				.addTo(model.headGroup)
 95 				.geometry()
 96 					.translateY(sizes.headH/2)
 97 					.back()
 98 	var tGeometry	= model.helmet.geometry().get(0);
 99 	mapUv(tGeometry, 0, 48, 24, 56, 16)	// left
100 	mapUv(tGeometry, 1, 32, 24, 40, 16)	// right
101 	mapUv(tGeometry, 2, 40, 32, 48, 24)	// top
102 	mapUv(tGeometry, 3, 48, 32, 56, 24)	// bottom
103 	mapUv(tGeometry, 4, 40, 24, 48, 16)	// front
104 	mapUv(tGeometry, 5, 56, 24, 64, 16)	// back
105 	
106 	
107 	// build model.body
108 	model.body	= tQuery.createCube(sizes.bodyW, sizes.bodyH, sizes.bodyD, tMaterial)
109 				.addTo(model.root) 
110 				.translateY(sizes.legH + sizes.bodyH/2);
111 	var tGeometry	= model.body.geometry().get(0);
112 	mapUv(tGeometry, 0, 28, 12, 32,  0)	// left
113 	mapUv(tGeometry, 1, 16, 12, 20,  0)	// right
114 	mapUv(tGeometry, 2, 20, 16, 28, 12)	// top
115 	mapUv(tGeometry, 3, 28, 16, 32, 12)	// bottom
116 	mapUv(tGeometry, 4, 20, 12, 28,  0)	// front
117 	mapUv(tGeometry, 5, 32, 12, 40,  0)	// back
118 
119 	// build model.armR
120 	model.armR	= tQuery.createCube(sizes.armW, sizes.armH, sizes.armD, tMaterial)
121 				.addTo(model.root)
122 				.geometry()
123 					.translateY(-sizes.armH/2 + sizes.armW/2)
124 					.back()
125 				.translateX(-sizes.bodyW/2 - sizes.armW/2)
126 				.translateY(sizes.legH + sizes.bodyH - sizes.armW/2)
127 	var tGeometry	= model.armR.geometry().get(0);
128 	mapUv(tGeometry, 0, 48, 12, 52,  0)	// right
129 	mapUv(tGeometry, 1, 40, 12, 44,  0)	// left
130 	mapUv(tGeometry, 2, 44, 16, 48, 12)	// top
131 	mapUv(tGeometry, 3, 48, 16, 52, 12)	// bottom
132 	mapUv(tGeometry, 4, 44, 12, 48,  0)	// front
133 	mapUv(tGeometry, 5, 52, 12, 56,  0)	// back
134 	
135 	// build model.armL
136 	model.armL	= tQuery.createCube(sizes.armW, sizes.armH, sizes.armD, tMaterial)
137 				.addTo(model.root)
138 				.geometry()
139 					.translateY(-sizes.armH/2 + sizes.armW/2)
140 					.back()
141 				.translateX(sizes.bodyW/2 + sizes.armW/2)
142 				.translateY(sizes.legH + sizes.bodyH - sizes.armW/2)
143 	var tGeometry	= model.armL.geometry().get(0);
144 	mapUv(tGeometry, 0, 44, 12, 40,  0)	// right
145 	mapUv(tGeometry, 1, 52, 12, 48,  0)	// left
146 	mapUv(tGeometry, 2, 44, 16, 48, 12)	// top
147 	mapUv(tGeometry, 3, 48, 16, 52, 12)	// bottom
148 	mapUv(tGeometry, 4, 48, 12, 44,  0)	// front
149 	mapUv(tGeometry, 5, 56, 12, 52,  0)	// back
150 
151 	// build model.legR
152 	model.legR	= tQuery.createCube(sizes.legW, sizes.legH, sizes.legD, tMaterial)
153 				.addTo(model.root)
154 				.geometry()
155 					.translateY(-sizes.legH/2)
156 					.back()
157 				.translateX(-sizes.legW/2)
158 				.translateY( sizes.legH)
159 	var tGeometry	= model.legR.geometry().get(0);
160 	mapUv(tGeometry, 0,  8, 12, 12,  0)	// right
161 	mapUv(tGeometry, 1,  0, 12,  4,  0)	// left
162 	mapUv(tGeometry, 2,  4, 16,  8, 12)	// top
163 	mapUv(tGeometry, 3,  8, 16, 12, 12)	// bottom
164 	mapUv(tGeometry, 4,  4, 12,  8,  0)	// front
165 	mapUv(tGeometry, 5, 12, 12, 16,  0)	// back
166 
167 	// build model.legL
168 	model.legL	= tQuery.createCube(sizes.legW, sizes.legH, sizes.legD, tMaterial)
169 				.addTo(model.root)
170 				.geometry()
171 					.translateY(-sizes.legH/2)
172 					.back()
173 				.translateX(sizes.legW/2)
174 				.translateY(sizes.legH)
175 	var tGeometry	= model.legL.geometry().get(0);
176 	mapUv(tGeometry, 0,  4, 12,  0,  0)	// left
177 	mapUv(tGeometry, 1, 12, 12,  8,  0)	// right
178 	mapUv(tGeometry, 2,  8, 16,  4, 12)	// top
179 	mapUv(tGeometry, 3, 12, 16,  8, 12)	// bottom
180 	mapUv(tGeometry, 4,  8, 12,  4,  0)	// front
181 	mapUv(tGeometry, 5, 16, 12, 12,  0)	// back
182 
183 
184 	this._model	= model;
185 	
186 	// backward compatibility only
187 	if( true ){
188 		this.model	= model.root;
189 		this.parts	= {
190 			headGroup	: model.headGroup.get(0),
191 			upperBody	: model.body.get(0),
192 			legL		: model.legL.get(0),
193 			legR		: model.legR.get(0),
194 			armR		: model.armR.get(0),
195 			armL		: model.armL.get(0)
196 		};		
197 	}
198 
199 	
200 	return;
201 
202 
203 	function mapUv(tGeometry, faceIdx, x1, y1, x2, y2){
204 		var tileUvW	= 1/64;
205 		var tileUvH	= 1/32;
206 		var UVs		= tGeometry.faceVertexUvs[0][faceIdx];
207 		UVs[0].u = x1 * tileUvW;	UVs[0].v = y1 * tileUvH;
208 		UVs[1].u = x1 * tileUvW;	UVs[1].v = y2 * tileUvH;
209 		UVs[2].u = x2 * tileUvW;	UVs[2].v = y2 * tileUvH;
210 		UVs[3].u = x2 * tileUvW;	UVs[3].v = y1 * tileUvH;		
211 	}
212 });
213 
214 // make it pluginable
215 tQuery.pluginsInstanceOn(tQuery.MinecraftChar);
216 
217 
218 tQuery.MinecraftChar.baseUrl	= "../../../plugins/minecraft/";
219 
220 /**
221  * Load a skin
222  *
223  * @param {string} url the url of the skin image
224 */
225 tQuery.MinecraftChar.prototype.loadSkin	= function(url){
226 	var image	= new Image();
227 	image.onload	= function () {
228 		this._tTexture.image		= image;
229 		this._tTexture.needsUpdate	= true;
230 	}.bind(this);
231 	image.src = url;
232 	return this;	// for chained API
233 }
234 
235 /**
236  * getter/setter on objects3d
237  *
238  * @param {string} name the name of the object3d to get
239 */
240 tQuery.MinecraftChar.prototype.object3D	= function(name){
241 	// name default to 'root'
242 	name	= name	|| 'root';
243 	// sanity check
244 	console.assert( this._model[name] !== undefined );
245 	// handle getter case
246 	return this._model[name];
247 }
248 
249 //////////////////////////////////////////////////////////////////////////////////
250 //										//
251 //////////////////////////////////////////////////////////////////////////////////
252 
253 /**
254  * Emulate tQuery.Object3D.addTo
255 */
256 tQuery.MinecraftChar.prototype.addTo	= function(object3D){
257 	this._model.root.addTo(object3D);
258 	return this;
259 }
260 
261 /**
262  * Emulate tQuery.Object3D.removeFrom
263 */
264 tQuery.MinecraftChar.prototype.removeFrom	= function(object3D){
265 	this.object3D('root').removeFrom(object3D);
266 	return this;
267 };
268 
269