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