MMDLoader.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046
  1. /**
  2. * @author takahiro / https://github.com/takahirox
  3. *
  4. * Dependencies
  5. * charset-encoder-js https://github.com/takahirox/charset-encoder-js
  6. *
  7. *
  8. * This loader loads and parses PMD/PMX and VMD binary files
  9. * then creates mesh for Three.js.
  10. *
  11. * PMD/PMX is a model data format and VMD is a motion data format
  12. * used in MMD(Miku Miku Dance).
  13. *
  14. * MMD is a 3D CG animation tool which is popular in Japan.
  15. *
  16. *
  17. * MMD official site
  18. * http://www.geocities.jp/higuchuu4/index_e.htm
  19. *
  20. * PMD, VMD format
  21. * http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
  22. *
  23. * PMX format
  24. * http://gulshan-i-raz.geo.jp/labs/2012/10/17/pmx-format1/
  25. *
  26. * Model data requirements
  27. * convert .tga files to .png files if exist. (Should I use THREE.TGALoader?)
  28. * resize the texture image files to power_of_2*power_of_2
  29. *
  30. *
  31. * TODO
  32. * separate model/vmd loaders.
  33. * multi vmd files support.
  34. * edge(outline) support.
  35. * culling support.
  36. * toon(cel) shadering support.
  37. * add-sphere-mapping support.
  38. * physics support.
  39. * camera motion in vmd support.
  40. * light motion in vmd support.
  41. * music support.
  42. * make own shader for the performance and functionarity.
  43. * SDEF support.
  44. * uv/material/bone morphing support.
  45. * tga file loading support.
  46. * supply skinning support.
  47. * shadow support.
  48. */
  49. THREE.MMDLoader = function ( showStatus, manager ) {
  50. THREE.Loader.call( this, showStatus );
  51. this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
  52. };
  53. THREE.MMDLoader.prototype = Object.create( THREE.Loader.prototype );
  54. THREE.MMDLoader.prototype.constructor = THREE.MMDLoader;
  55. THREE.MMDLoader.prototype.extractExtension = function ( url ) {
  56. var index = url.lastIndexOf( '.' );
  57. if ( index < 0 ) {
  58. return null;
  59. }
  60. return url.slice( index + 1 );
  61. };
  62. THREE.MMDLoader.prototype.load = function ( modelUrl, vmdUrl, callback, onProgress, onError ) {
  63. var texturePath = this.extractUrlBase( modelUrl );
  64. var modelExtension = this.extractExtension( modelUrl );
  65. this.loadModelFile( modelUrl, vmdUrl, texturePath, modelExtension, callback, onProgress, onError );
  66. };
  67. THREE.MMDLoader.prototype.loadFileAsBuffer = function ( url, onLoad, onProgress, onError ) {
  68. var loader = new THREE.XHRLoader( this.manager );
  69. loader.setResponseType( 'arraybuffer' );
  70. loader.load( url, function ( buffer ) {
  71. onLoad( buffer );
  72. }, onProgress, onError );
  73. };
  74. THREE.MMDLoader.prototype.loadModelFile = function ( modelUrl, vmdUrl, texturePath, modelExtension, callback, onProgress, onError ) {
  75. var scope = this;
  76. this.loadFileAsBuffer( modelUrl, function ( buffer ) {
  77. scope.loadVmdFile( buffer, vmdUrl, texturePath, modelExtension, callback, onProgress, onError );
  78. }, onProgress, onError );
  79. };
  80. THREE.MMDLoader.prototype.loadVmdFile = function ( modelBuffer, vmdUrl, texturePath, modelExtension, callback, onProgress, onError ) {
  81. var scope = this;
  82. if ( ! vmdUrl ) {
  83. scope.parse( modelBuffer, null, texturePath, modelExtension, callback );
  84. return;
  85. }
  86. this.loadFileAsBuffer( vmdUrl, function ( buffer ) {
  87. scope.parse( modelBuffer, buffer, texturePath, modelExtension, callback );
  88. }, onProgress, onError );
  89. };
  90. THREE.MMDLoader.prototype.parse = function ( modelBuffer, vmdBuffer, texturePath, modelExtension, callback ) {
  91. var model = this.parseModel( modelBuffer, modelExtension );
  92. var vmd = vmdBuffer !== null ? this.parseVmd( vmdBuffer ) : null;
  93. var mesh = this.createMesh( model, vmd, texturePath );
  94. callback( mesh );
  95. };
  96. THREE.MMDLoader.prototype.parseModel = function ( buffer, modelExtension ) {
  97. // Should I judge from model data header?
  98. switch( modelExtension.toLowerCase() ) {
  99. case 'pmd':
  100. return this.parsePmd( buffer );
  101. case 'pmx':
  102. return this.parsePmx( buffer );
  103. default:
  104. throw 'extension ' + modelExtension + ' is not supported.';
  105. }
  106. };
  107. THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
  108. var scope = this;
  109. var pmd = {};
  110. var dv = new THREE.MMDLoader.DataView( buffer );
  111. pmd.metadata = {};
  112. pmd.metadata.format = 'pmd';
  113. var parseHeader = function () {
  114. var metadata = pmd.metadata;
  115. metadata.magic = dv.getChars( 3 );
  116. if ( metadata.magic !== 'Pmd' ) {
  117. throw 'PMD file magic is not Pmd, but ' + metadata.magic;
  118. }
  119. metadata.version = dv.getFloat32();
  120. metadata.modelName = dv.getSjisStringsAsUnicode( 20 );
  121. metadata.comment = dv.getSjisStringsAsUnicode( 256 );
  122. };
  123. var parseVertices = function () {
  124. var parseVertex = function () {
  125. var p = {};
  126. p.position = dv.getFloat32Array( 3 );
  127. p.normal = dv.getFloat32Array( 3 );
  128. p.uv = dv.getFloat32Array( 2 );
  129. p.skinIndices = dv.getUint16Array( 2 );
  130. p.skinWeights = [ dv.getUint8() / 100 ];
  131. p.skinWeights.push( 1.0 - p.skinWeights[ 0 ] );
  132. p.edgeFlag = dv.getUint8();
  133. return p;
  134. };
  135. var metadata = pmd.metadata;
  136. metadata.vertexCount = dv.getUint32();
  137. pmd.vertices = [];
  138. for ( var i = 0; i < metadata.vertexCount; i++ ) {
  139. pmd.vertices.push( parseVertex() );
  140. }
  141. };
  142. var parseFaces = function () {
  143. var parseFace = function () {
  144. var p = {};
  145. p.indices = dv.getUint16Array( 3 );
  146. return p;
  147. };
  148. var metadata = pmd.metadata;
  149. metadata.faceCount = dv.getUint32() / 3;
  150. pmd.faces = [];
  151. for ( var i = 0; i < metadata.faceCount; i++ ) {
  152. pmd.faces.push( parseFace() );
  153. }
  154. };
  155. var parseMaterials = function () {
  156. var parseMaterial = function () {
  157. var p = {};
  158. p.diffuse = dv.getFloat32Array( 4 );
  159. p.shiness = dv.getFloat32();
  160. p.specular = dv.getFloat32Array( 3 );
  161. p.emissive = dv.getFloat32Array( 3 );
  162. p.toonIndex = dv.getUint8();
  163. p.edgeFlag = dv.getUint8();
  164. p.faceCount = dv.getUint32() / 3;
  165. p.fileName = dv.getChars( 20 );
  166. return p;
  167. };
  168. var metadata = pmd.metadata;
  169. metadata.materialCount = dv.getUint32();
  170. pmd.materials = [];
  171. for ( var i = 0; i < metadata.materialCount; i++ ) {
  172. pmd.materials.push( parseMaterial() );
  173. }
  174. };
  175. var parseBones = function () {
  176. var parseBone = function () {
  177. var p = {};
  178. // Skinning animation doesn't work when bone name is Japanese Unicode in r73.
  179. // So using charcode strings as workaround and keep original strings in .originalName.
  180. p.originalName = dv.getSjisStringsAsUnicode( 20 );
  181. p.name = dv.toCharcodeStrings( p.originalName );
  182. p.parentIndex = dv.getUint16();
  183. p.tailIndex = dv.getUint16();
  184. p.type = dv.getUint8();
  185. p.ikIndex = dv.getUint16();
  186. p.position = dv.getFloat32Array( 3 );
  187. return p;
  188. };
  189. var metadata = pmd.metadata;
  190. metadata.boneCount = dv.getUint16();
  191. pmd.bones = [];
  192. for ( var i = 0; i < metadata.boneCount; i++ ) {
  193. pmd.bones.push( parseBone() );
  194. }
  195. };
  196. var parseIks = function () {
  197. var parseIk = function () {
  198. var p = {};
  199. p.target = dv.getUint16();
  200. p.effector = dv.getUint16();
  201. p.linkCount = dv.getUint8();
  202. p.iteration = dv.getUint16();
  203. p.maxAngle = dv.getFloat32();
  204. p.links = [];
  205. for ( var i = 0; i < p.linkCount; i++ ) {
  206. var link = {}
  207. link.index = dv.getUint16();
  208. p.links.push( link );
  209. }
  210. return p;
  211. };
  212. var metadata = pmd.metadata;
  213. metadata.ikCount = dv.getUint16();
  214. pmd.iks = [];
  215. for ( var i = 0; i < metadata.ikCount; i++ ) {
  216. pmd.iks.push( parseIk() );
  217. }
  218. };
  219. var parseMorphs = function () {
  220. var parseMorph = function () {
  221. var p = {};
  222. p.name = dv.getSjisStringsAsUnicode( 20 );
  223. p.elementCount = dv.getUint32();
  224. p.type = dv.getUint8();
  225. p.elements = [];
  226. for ( var i = 0; i < p.elementCount; i++ ) {
  227. p.elements.push( {
  228. index: dv.getUint32(),
  229. position: dv.getFloat32Array( 3 )
  230. } ) ;
  231. }
  232. return p;
  233. };
  234. var metadata = pmd.metadata;
  235. metadata.morphCount = dv.getUint16();
  236. pmd.morphs = [];
  237. for ( var i = 0; i < metadata.morphCount; i++ ) {
  238. pmd.morphs.push( parseMorph() );
  239. }
  240. };
  241. parseHeader();
  242. parseVertices();
  243. parseFaces();
  244. parseMaterials();
  245. parseBones();
  246. parseIks();
  247. parseMorphs();
  248. return pmd;
  249. };
  250. THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
  251. var scope = this;
  252. var pmx = {};
  253. var dv = new THREE.MMDLoader.DataView( buffer );
  254. pmx.metadata = {};
  255. pmx.metadata.format = 'pmx';
  256. var parseHeader = function () {
  257. var metadata = pmx.metadata;
  258. metadata.magic = dv.getChars( 4 );
  259. // Note: don't remove the last blank space.
  260. if ( metadata.magic !== 'PMX ' ) {
  261. throw 'PMX file magic is not PMX , but ' + metadata.magic;
  262. }
  263. metadata.version = dv.getFloat32();
  264. if ( metadata.version !== 2.0 && metadata.version !== 2.1 ) {
  265. throw 'PMX version ' + metadata.version + ' is not supported.';
  266. }
  267. metadata.headerSize = dv.getUint8();
  268. metadata.encoding = dv.getUint8();
  269. metadata.additionalUvNum = dv.getUint8();
  270. metadata.vertexIndexSize = dv.getUint8();
  271. metadata.textureIndexSize = dv.getUint8();
  272. metadata.materialIndexSize = dv.getUint8();
  273. metadata.boneIndexSize = dv.getUint8();
  274. metadata.morphIndexSize = dv.getUint8();
  275. metadata.rigidbodyIndexSize = dv.getUint8();
  276. metadata.modelName = dv.getTextBuffer();
  277. metadata.englishModelName = dv.getTextBuffer();
  278. metadata.comment = dv.getTextBuffer();
  279. metadata.englishComment = dv.getTextBuffer();
  280. };
  281. var parseVertices = function () {
  282. var parseVertex = function () {
  283. var p = {};
  284. p.position = dv.getFloat32Array( 3 );
  285. p.normal = dv.getFloat32Array( 3 );
  286. p.uv = dv.getFloat32Array( 2 );
  287. p.auvs = [];
  288. for ( var i = 0; i < pmx.metadata.additionalUvNum; i++ ) {
  289. p.auvs.push( dv.getFloat32Array( 4 ) );
  290. }
  291. p.type = dv.getUint8();
  292. var indexSize = metadata.vertexIndexSize;
  293. if ( p.type === 0 ) { // BDEF1
  294. p.skinIndices = dv.getNumberArray( indexSize, 1 );
  295. p.skinWeights = [ 1.0 ];
  296. } else if ( p.type === 1 ) { // BDEF2
  297. p.skinIndices = dv.getNumberArray( indexSize, 2 );
  298. p.skinWeights = dv.getFloat32Array( 1 );
  299. p.skinWeights.push( 1.0 - p.skinWeights[ 0 ] );
  300. } else if ( p.type === 2 ) { // BDEF4
  301. p.skinIndices = dv.getNumberArray( indexSize, 4 );
  302. p.skinWeights = dv.getFloat32Array( 4 );
  303. } else if ( p.type === 3 ) { // SDEF
  304. p.skinIndices = dv.getNumberArray( indexSize, 2 );
  305. p.skinWeights = dv.getFloat32Array( 1 );
  306. p.skinWeights.push( 1.0 - p.skinWeights[ 0 ] );
  307. p.skinC = dv.getFloat32Array( 3 );
  308. p.skinR0 = dv.getFloat32Array( 3 );
  309. p.skinR1 = dv.getFloat32Array( 3 );
  310. // SDEF is not supported yet and is handled as BDEF2 so far.
  311. // TODO: SDEF support
  312. p.type = 1;
  313. } else {
  314. throw 'unsupport bone type ' + p.type + ' exception.';
  315. }
  316. p.edgeRatio = dv.getFloat32();
  317. return p;
  318. };
  319. var metadata = pmx.metadata;
  320. metadata.vertexCount = dv.getUint32();
  321. pmx.vertices = [];
  322. for ( var i = 0; i < metadata.vertexCount; i++ ) {
  323. pmx.vertices.push( parseVertex() );
  324. }
  325. };
  326. var parseFaces = function () {
  327. var parseFace = function () {
  328. var p = {};
  329. p.indices = dv.getNumberArray( metadata.vertexIndexSize, 3 );
  330. return p;
  331. };
  332. var metadata = pmx.metadata;
  333. metadata.faceCount = dv.getUint32() / 3;
  334. pmx.faces = [];
  335. for ( var i = 0; i < metadata.faceCount; i++ ) {
  336. pmx.faces.push( parseFace() );
  337. }
  338. };
  339. var parseTextures = function () {
  340. var parseTexture = function () {
  341. return dv.getTextBuffer();
  342. };
  343. var metadata = pmx.metadata;
  344. metadata.textureCount = dv.getUint32();
  345. pmx.textures = [];
  346. for ( var i = 0; i < metadata.textureCount; i++ ) {
  347. pmx.textures.push( parseTexture() );
  348. }
  349. };
  350. var parseMaterials = function () {
  351. var parseMaterial = function () {
  352. var p = {};
  353. p.name = dv.getTextBuffer();
  354. p.englishName = dv.getTextBuffer();
  355. p.diffuse = dv.getFloat32Array( 4 );
  356. p.specular = dv.getFloat32Array( 3 );
  357. p.shiness = dv.getFloat32();
  358. p.emissive = dv.getFloat32Array( 3 );
  359. p.flag = dv.getUint8();
  360. p.edgeColor = dv.getFloat32Array( 4 );
  361. p.edgeSize = dv.getFloat32();
  362. p.textureIndex = dv.getNumber( pmx.metadata.textureIndexSize );
  363. p.envTextureIndex = dv.getNumber( pmx.metadata.textureIndexSize );
  364. p.envFlag = dv.getUint8();
  365. p.toonFlag = dv.getUint8();
  366. if ( p.toonFlag === 0 ) {
  367. p.toonTextureIndex = dv.getNumber( pmx.metadata.textureIndexSize );
  368. } else if ( p.toonFlag === 1 ) {
  369. p.toonTextureIndex = dv.getUint8();
  370. } else {
  371. throw 'unknown toon flag ' + p.toonFlag + ' exception.';
  372. }
  373. p.comment = dv.getTextBuffer();
  374. p.faceCount = dv.getUint32() / 3;
  375. return p;
  376. };
  377. var metadata = pmx.metadata;
  378. metadata.materialCount = dv.getUint32();
  379. pmx.materials = [];
  380. for ( var i = 0; i < metadata.materialCount; i++ ) {
  381. pmx.materials.push( parseMaterial() );
  382. }
  383. };
  384. var parseBones = function () {
  385. var parseBone = function () {
  386. var p = {};
  387. // Skinning animation doesn't work when bone name is Japanese Unicode in r73.
  388. // So using charcode strings as workaround and keep original strings in .originalName.
  389. p.originalName = dv.getTextBuffer();
  390. p.name = dv.toCharcodeStrings( p.originalName );
  391. p.englishName = dv.getTextBuffer();
  392. p.position = dv.getFloat32Array( 3 );
  393. p.parentIndex = dv.getNumber( pmx.metadata.boneIndexSize );
  394. p.transformationClass = dv.getUint32();
  395. p.flag = dv.getUint16();
  396. if ( p.flag & 0x1 ) {
  397. p.connectIndex = dv.getNumber( pmx.metadata.boneIndexSize );
  398. } else {
  399. p.offsetPosition = dv.getFloat32Array( 3 );
  400. }
  401. if ( p.flag & 0x100 || p.flag & 0x200 ) {
  402. p.supplyParentIndex = dv.getNumber( pmx.metadata.boneIndexSize );
  403. p.supplyRatio = dv.getFloat32();
  404. }
  405. if ( p.flag & 0x400 ) {
  406. p.fixAxis = dv.getFloat32Array( 3 );
  407. }
  408. if ( p.flag & 0x800 ) {
  409. p.localXVector = dv.getFloat32Array( 3 );
  410. p.localZVector = dv.getFloat32Array( 3 );
  411. }
  412. if ( p.flag & 0x2000 ) {
  413. p.key = dv.getUint32();
  414. }
  415. if ( p.flag & 0x20 ) {
  416. var ik = {};
  417. ik.effector = dv.getNumber( pmx.metadata.boneIndexSize );
  418. ik.target = null;
  419. ik.iteration = dv.getUint32();
  420. ik.maxAngle = dv.getFloat32();
  421. ik.linkCount = dv.getUint32();
  422. ik.links = [];
  423. for ( var i = 0; i < ik.linkCount; i++ ) {
  424. var link = {};
  425. link.index = dv.getNumber( pmx.metadata.boneIndexSize );
  426. link.angleLimitation = dv.getUint8();
  427. if ( link.angleLimitation === 1 ) {
  428. link.lowerLimitationAngle = dv.getFloat32Array( 3 );
  429. link.upperLimitationAngle = dv.getFloat32Array( 3 );
  430. }
  431. ik.links.push( link );
  432. }
  433. p.ik = ik;
  434. }
  435. return p;
  436. };
  437. var metadata = pmx.metadata;
  438. metadata.boneCount = dv.getUint32();
  439. pmx.bones = [];
  440. for ( var i = 0; i < metadata.boneCount; i++ ) {
  441. pmx.bones.push( parseBone() );
  442. }
  443. };
  444. var parseMorphs = function () {
  445. var parseMorph = function () {
  446. var p = {};
  447. p.name = dv.getTextBuffer();
  448. p.englishName = dv.getTextBuffer();
  449. p.panel = dv.getUint8();
  450. p.type = dv.getUint8();
  451. p.elementCount = dv.getUint32();
  452. p.elements = [];
  453. for ( var i = 0; i < p.elementCount; i++ ) {
  454. if ( p.type === 0 ) { // group morph
  455. var m = {};
  456. m.index = dv.getNumber( pmx.metadata.morphIndexSize );
  457. m.ratio = dv.getFloat32();
  458. p.elements.push( m );
  459. } else if ( p.type === 1 ) { // vertex morph
  460. var m = {};
  461. m.index = dv.getNumber( pmx.metadata.vertexIndexSize );
  462. m.position = dv.getFloat32Array( 3 );
  463. p.elements.push( m );
  464. } else if ( p.type === 2 ) { // bone morph
  465. var m = {};
  466. m.index = dv.getNumber( pmx.metadata.boneIndexSize );
  467. m.position = dv.getFloat32Array( 3 );
  468. m.rotation = dv.getFloat32Array( 4 );
  469. p.elements.push( m );
  470. } else if ( p.type === 3 ) { // uv morph
  471. var m = {};
  472. m.index = dv.getNumber( pmx.metadata.vertexIndexSize );
  473. m.uv = dv.getFloat32Array( 4 );
  474. p.elements.push( m );
  475. } else if ( p.type === 8 ) { // material morph
  476. var m = {};
  477. m.index = dv.getNumber( pmx.metadata.materialIndexSize );
  478. m.type = dv.getUint8();
  479. m.diffuse = dv.getFloat32Array( 4 );
  480. m.specular = dv.getFloat32Array( 3 );
  481. m.shiness = dv.getFloat32();
  482. m.emissive = dv.getFloat32Array( 3 );
  483. m.edgeColor = dv.getFloat32Array( 4 );
  484. m.edgeSize = dv.getFloat32();
  485. m.textureColor = dv.getFloat32Array( 4 );
  486. m.sphereTextureColor = dv.getFloat32Array( 4 );
  487. m.toonColor = dv.getFloat32Array( 4 );
  488. p.elements.push( m );
  489. }
  490. }
  491. return p;
  492. };
  493. var metadata = pmx.metadata;
  494. metadata.morphCount = dv.getUint32();
  495. pmx.morphs = [];
  496. for ( var i = 0; i < metadata.morphCount; i++ ) {
  497. pmx.morphs.push( parseMorph() );
  498. }
  499. };
  500. parseHeader();
  501. parseVertices();
  502. parseFaces();
  503. parseTextures();
  504. parseMaterials();
  505. parseBones();
  506. parseMorphs();
  507. // console.log( pmx ); // for console debug
  508. return pmx;
  509. };
  510. THREE.MMDLoader.prototype.parseVmd = function ( buffer ) {
  511. var scope = this;
  512. var vmd = {};
  513. var dv = new THREE.MMDLoader.DataView( buffer );
  514. vmd.metadata = {};
  515. var parseHeader = function () {
  516. var metadata = vmd.metadata;
  517. metadata.magic = dv.getChars( 30 );
  518. if ( metadata.magic !== 'Vocaloid Motion Data 0002' ) {
  519. throw 'VMD file magic is not Vocaloid Motion Data 0002, but ' + metadata.magic;
  520. }
  521. metadata.name = dv.getSjisStringsAsUnicode( 20 );
  522. };
  523. var parseMotions = function () {
  524. var parseMotion = function () {
  525. var p = {};
  526. // Skinning animation doesn't work when bone name is Japanese Unicode in r73.
  527. // So using charcode strings as workaround and keep original strings in .originalName.
  528. p.originalBoneName = dv.getSjisStringsAsUnicode( 15 );
  529. p.boneName = dv.toCharcodeStrings( p.originalBoneName );
  530. p.frameNum = dv.getUint32();
  531. p.position = dv.getFloat32Array( 3 );
  532. p.rotation = dv.getFloat32Array( 4 );
  533. p.interpolation = dv.getUint8Array( 64 );
  534. return p;
  535. };
  536. var metadata = vmd.metadata;
  537. metadata.motionCount = dv.getUint32();
  538. vmd.motions = [];
  539. for ( var i = 0; i < metadata.motionCount; i++ ) {
  540. vmd.motions.push( parseMotion() );
  541. }
  542. };
  543. var parseMorphs = function () {
  544. var parseMorph = function () {
  545. var p = {};
  546. p.morphName = dv.getSjisStringsAsUnicode( 15 );
  547. p.frameNum = dv.getUint32();
  548. p.weight = dv.getFloat32();
  549. return p;
  550. };
  551. var metadata = vmd.metadata;
  552. metadata.morphCount = dv.getUint32();
  553. vmd.morphs = [];
  554. for ( var i = 0; i < metadata.morphCount; i++ ) {
  555. vmd.morphs.push( parseMorph() );
  556. }
  557. };
  558. parseHeader();
  559. parseMotions();
  560. parseMorphs();
  561. return vmd;
  562. };
  563. // maybe better to create json and then use JSONLoader...
  564. THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onProgress, onError ) {
  565. var scope = this;
  566. var geometry = new THREE.Geometry();
  567. var material = new THREE.MeshFaceMaterial();
  568. var leftToRight = function() {
  569. var convertVector = function ( v ) {
  570. v[ 2 ] = -v[ 2 ];
  571. };
  572. var convertQuaternion = function ( q ) {
  573. q[ 0 ] = -q[ 0 ];
  574. q[ 1 ] = -q[ 1 ];
  575. };
  576. var convertIndexOrder = function ( p ) {
  577. var tmp = p[ 2 ];
  578. p[ 2 ] = p[ 0 ];
  579. p[ 0 ] = tmp;
  580. };
  581. for ( var i = 0; i < model.metadata.vertexCount; i++ ) {
  582. convertVector( model.vertices[ i ].position );
  583. convertVector( model.vertices[ i ].normal );
  584. }
  585. for ( var i = 0; i < model.metadata.faceCount; i++ ) {
  586. convertIndexOrder( model.faces[ i ].indices );
  587. }
  588. for ( var i = 0; i < model.metadata.boneCount; i++ ) {
  589. convertVector( model.bones[ i ].position );
  590. }
  591. // TODO: support other morph for PMX
  592. for ( var i = 0; i < model.metadata.morphCount; i++ ) {
  593. var m = model.morphs[ i ];
  594. if ( model.metadata.format === 'pmx' ) {
  595. if ( m.type === 1 ) {
  596. m = m.elements;
  597. } else {
  598. continue;
  599. }
  600. }
  601. for ( var j = 0; j < m.elementCount; j++ ) {
  602. convertVector( m.elements[ j ].position );
  603. }
  604. }
  605. if ( vmd === null ) {
  606. return;
  607. }
  608. for ( var i = 0; i < vmd.metadata.motionCount; i++ ) {
  609. convertVector( vmd.motions[ i ].position );
  610. convertQuaternion( vmd.motions[ i ].rotation );
  611. }
  612. };
  613. var initVartices = function () {
  614. for ( var i = 0; i < model.metadata.vertexCount; i++ ) {
  615. var v = model.vertices[ i ];
  616. geometry.vertices.push(
  617. new THREE.Vector3(
  618. v.position[ 0 ],
  619. v.position[ 1 ],
  620. v.position[ 2 ]
  621. )
  622. );
  623. geometry.skinIndices.push(
  624. new THREE.Vector4(
  625. v.skinIndices.length >= 1 ? v.skinIndices[ 0 ] : 0.0,
  626. v.skinIndices.length >= 2 ? v.skinIndices[ 1 ] : 0.0,
  627. v.skinIndices.length >= 3 ? v.skinIndices[ 2 ] : 0.0,
  628. v.skinIndices.length >= 4 ? v.skinIndices[ 3 ] : 0.0
  629. )
  630. );
  631. geometry.skinWeights.push(
  632. new THREE.Vector4(
  633. v.skinWeights.length >= 1 ? v.skinWeights[ 0 ] : 0.0,
  634. v.skinWeights.length >= 2 ? v.skinWeights[ 1 ] : 0.0,
  635. v.skinWeights.length >= 3 ? v.skinWeights[ 2 ] : 0.0,
  636. v.skinWeights.length >= 4 ? v.skinWeights[ 3 ] : 0.0
  637. )
  638. );
  639. }
  640. };
  641. var initFaces = function () {
  642. for ( var i = 0; i < model.metadata.faceCount; i++ ) {
  643. geometry.faces.push(
  644. new THREE.Face3(
  645. model.faces[ i ].indices[ 0 ],
  646. model.faces[ i ].indices[ 1 ],
  647. model.faces[ i ].indices[ 2 ]
  648. )
  649. );
  650. for ( var j = 0; j < 3; j++ ) {
  651. geometry.faces[ i ].vertexNormals[ j ] =
  652. new THREE.Vector3(
  653. model.vertices[ model.faces[ i ].indices[ j ] ].normal[ 0 ],
  654. model.vertices[ model.faces[ i ].indices[ j ] ].normal[ 1 ],
  655. model.vertices[ model.faces[ i ].indices[ j ] ].normal[ 2 ]
  656. );
  657. }
  658. }
  659. };
  660. var initBones = function () {
  661. var bones = [];
  662. for ( var i = 0; i < model.metadata.boneCount; i++ ) {
  663. var bone = {};
  664. var b = model.bones[ i ];
  665. bone.parent = b.parentIndex;
  666. if ( model.metadata.format === 'pmd' ) {
  667. bone.parent = ( b.parentIndex === 0xFFFF ) ? -1 : b.parentIndex;
  668. }
  669. bone.name = b.name;
  670. bone.pos = [ b.position[ 0 ], b.position[ 1 ], b.position[ 2 ] ];
  671. bone.rotq = [ 0, 0, 0, 1 ];
  672. bone.scl = [ 1, 1, 1 ];
  673. if ( bone.parent !== -1 ) {
  674. bone.pos[ 0 ] -= model.bones[ bone.parent ].position[ 0 ];
  675. bone.pos[ 1 ] -= model.bones[ bone.parent ].position[ 1 ];
  676. bone.pos[ 2 ] -= model.bones[ bone.parent ].position[ 2 ];
  677. }
  678. bones.push( bone );
  679. }
  680. geometry.bones = bones;
  681. };
  682. var initIKs = function () {
  683. var iks = [];
  684. // TODO: remove duplicated codes between PMD and PMX
  685. if ( model.metadata.format === 'pmd' ) {
  686. for ( var i = 0; i < model.metadata.ikCount; i++ ) {
  687. var ik = model.iks[i];
  688. var param = {};
  689. param.target = ik.target;
  690. param.effector = ik.effector;
  691. param.iteration = ik.iteration;
  692. param.maxAngle = ik.maxAngle * 4;
  693. param.links = [];
  694. for ( var j = 0; j < ik.links.length; j++ ) {
  695. var link = {};
  696. link.index = ik.links[ j ].index;
  697. // Checking with .originalName, not .name.
  698. // See parseBone() for the detail.
  699. if ( model.bones[ link.index ].originalName.indexOf( 'ひざ' ) >= 0 ) {
  700. link.limitation = new THREE.Vector3( 1.0, 0.0, 0.0 );
  701. }
  702. param.links.push( link );
  703. }
  704. iks.push( param );
  705. }
  706. } else {
  707. for ( var i = 0; i < model.metadata.boneCount; i++ ) {
  708. var b = model.bones[ i ];
  709. var ik = b.ik;
  710. if ( ik === undefined ) {
  711. continue;
  712. }
  713. var param = {};
  714. param.target = i;
  715. param.effector = ik.effector;
  716. param.iteration = ik.iteration;
  717. param.maxAngle = ik.maxAngle;
  718. param.links = [];
  719. for ( var j = 0; j < ik.links.length; j++ ) {
  720. var link = {};
  721. link.index = ik.links[ j ].index;
  722. if ( ik.links[ j ].angleLimitation === 1 ) {
  723. link.limitation = new THREE.Vector3( 1.0, 0.0, 0.0 );
  724. // TODO: use limitation angles
  725. // link.lowerLimitationAngle;
  726. // link.upperLimitationAngle;
  727. }
  728. param.links.push( link );
  729. }
  730. iks.push( param );
  731. }
  732. }
  733. geometry.iks = iks;
  734. };
  735. var initMorphs = function () {
  736. function updateVertex ( params, index, v, ratio ) {
  737. params.vertices[ index ].x += v.position[ 0 ] * ratio;
  738. params.vertices[ index ].y += v.position[ 1 ] * ratio;
  739. params.vertices[ index ].z += v.position[ 2 ] * ratio;
  740. };
  741. function updateVertices ( params, m, ratio ) {
  742. for ( var i = 0; i < m.elementCount; i++ ) {
  743. var v = m.elements[ i ];
  744. var index;
  745. if ( model.metadata.format === 'pmd' ) {
  746. index = model.morphs[ 0 ].elements[ v.index ].index;
  747. } else {
  748. index = v.index;
  749. }
  750. updateVertex( params, index, v, ratio );
  751. }
  752. };
  753. for ( var i = 0; i < model.metadata.morphCount; i++ ) {
  754. var m = model.morphs[ i ];
  755. var params = {};
  756. params.name = m.name;
  757. params.vertices = [];
  758. for ( var j = 0; j < model.metadata.vertexCount; j++ ) {
  759. params.vertices[ j ] = new THREE.Vector3( 0, 0, 0 );
  760. params.vertices[ j ].x = geometry.vertices[ j ].x;
  761. params.vertices[ j ].y = geometry.vertices[ j ].y;
  762. params.vertices[ j ].z = geometry.vertices[ j ].z;
  763. }
  764. if ( model.metadata.format === 'pmd' ) {
  765. if ( i !== 0 ) {
  766. updateVertices( params, m, 1.0 );
  767. }
  768. } else {
  769. if ( m.type === 0 ) {
  770. for ( var j = 0; j < m.elementCount; j++ ) {
  771. var m2 = model.morphs[ m.elements[ j ].index ];
  772. var ratio = m.elements[ j ].ratio;
  773. if ( m2.type === 1 ) {
  774. updateVertices( params, m2, ratio );
  775. }
  776. }
  777. } else if ( m.type === 1 ) {
  778. updateVertices( params, m, 1.0 );
  779. }
  780. }
  781. // TODO: skip if this's non-vertex morphing of PMX to reduce CPU/Memory use
  782. geometry.morphTargets.push( params );
  783. }
  784. };
  785. var initMaterials = function () {
  786. var offset = 0;
  787. var materialParams = [];
  788. for ( var i = 1; i < model.metadata.materialCount; i++ ) {
  789. geometry.faceVertexUvs.push( [] );
  790. }
  791. for ( var i = 0; i < model.metadata.materialCount; i++ ) {
  792. var m = model.materials[ i ];
  793. var params = {};
  794. for ( var j = 0; j < m.faceCount; j++ ) {
  795. geometry.faces[ offset ].materialIndex = i;
  796. var uvs = [];
  797. for ( var k = 0; k < 3; k++ ) {
  798. var v = model.vertices[ model.faces[ offset ].indices[ k ] ];
  799. uvs.push( new THREE.Vector2( v.uv[ 0 ], v.uv[ 1 ] ) );
  800. }
  801. geometry.faceVertexUvs[ 0 ].push( uvs );
  802. offset++;
  803. }
  804. params.shading = 'phong';
  805. params.colorDiffuse = [ m.diffuse[ 0 ], m.diffuse[ 1 ], m.diffuse[ 2 ] ];
  806. params.opacity = m.diffuse[ 3 ];
  807. params.colorSpecular = [ m.specular[ 0 ], m.specular[ 1 ], m.specular[ 2 ] ];
  808. params.specularCoef = m.shiness;
  809. // temporal workaround
  810. // TODO: implement correctly
  811. params.doubleSided = true;
  812. if ( model.metadata.format === 'pmd' ) {
  813. if ( m.fileName ) {
  814. var fileName = m.fileName;
  815. var fileNames = [];
  816. // temporal workaround, disable sphere mapping so far
  817. // TODO: sphere mapping support
  818. var index = fileName.lastIndexOf( '*' );
  819. if ( index >= 0 ) {
  820. fileNames.push( fileName.slice( 0, index ) );
  821. fileNames.push( fileName.slice( index + 1 ) );
  822. } else {
  823. fileNames.push( fileName );
  824. }
  825. for ( var j = 0; j < fileNames.length; j++ ) {
  826. var n = fileNames[ j ];
  827. // TODO: support spa
  828. if ( /* n.indexOf( '.spa' ) >= 0 || */ n.indexOf( '.sph' ) >= 0 ) {
  829. params.mapEnv = n;
  830. } else {
  831. // temporal workaround, use .png instead of .tga
  832. // TODO: tga file support
  833. params.mapDiffuse = n.replace( '.tga', '.png' );
  834. }
  835. }
  836. }
  837. } else {
  838. if ( m.textureIndex !== -1 ) {
  839. var n = model.textures[ m.textureIndex ];
  840. // temporal workaround, use .png instead of .tga
  841. // TODO: tga file support
  842. params.mapDiffuse = n.replace( '.tga', '.png' );
  843. }
  844. // TODO: support m.envFlag === 0, 2, 3
  845. if ( m.envTextureIndex !== -1 && m.envFlag === 1 ) {
  846. var n = model.textures[ m.envTextureIndex ];
  847. params.mapEnv = n;
  848. }
  849. }
  850. if ( params.mapDiffuse === undefined ) {
  851. params.colorEmissive = [ m.emissive[ 0 ], m.emissive[ 1 ], m.emissive[ 2 ] ];
  852. }
  853. materialParams.push( params );
  854. }
  855. var materials = scope.initMaterials( materialParams, texturePath );
  856. for ( var i = 0; i < materials.length; i++ ) {
  857. var m = materials[ i ];
  858. var p = materialParams[ i ];
  859. if ( m.map ) {
  860. m.map.flipY = false;
  861. }
  862. // this should be in THREE.Loader.createMaterial.
  863. // remove this if it supports.
  864. // TODO: make patch of THREE.Loader.createMaterial?
  865. if ( p.mapEnv !== undefined ) {
  866. var fullPath = texturePath + p.mapEnv;
  867. var loader = THREE.Loader.Handlers.get( fullPath );
  868. if ( loader === null ) {
  869. loader = new THREE.TextureLoader( this.manager );
  870. }
  871. var texture = loader.load( fullPath );
  872. // currently only support multiply-sphere-mapping
  873. // TODO: support add-sphere-mapping
  874. texture.mapping = THREE.SphericalReflectionMapping;
  875. m.envMap = texture;
  876. }
  877. m.skinning = true;
  878. m.morphTargets = true;
  879. material.materials.push( m );
  880. }
  881. };
  882. var initMotionAnimations = function () {
  883. var orderedMotions = [];
  884. var boneTable = {};
  885. for ( var i = 0; i < model.metadata.boneCount; i++ ) {
  886. var b = model.bones[ i ];
  887. boneTable[ b.name ] = i;
  888. orderedMotions[ i ] = [];
  889. }
  890. for ( var i = 0; i < vmd.motions.length; i++ ) {
  891. var m = vmd.motions[ i ];
  892. var num = boneTable[ m.boneName ];
  893. if ( num === undefined )
  894. continue;
  895. orderedMotions[ num ].push( m );
  896. }
  897. for ( var i = 0; i < orderedMotions.length; i++ ) {
  898. orderedMotions[ i ].sort( function ( a, b ) {
  899. return a.frameNum - b.frameNum;
  900. } ) ;
  901. }
  902. var animation = {
  903. name: 'Action',
  904. fps: 30,
  905. length: 0.0,
  906. hierarchy: []
  907. };
  908. for ( var i = 0; i < geometry.bones.length; i++ ) {
  909. animation.hierarchy.push(
  910. {
  911. parent: geometry.bones[ i ].parent,
  912. keys: []
  913. }
  914. );
  915. }
  916. var maxTime = 0.0;
  917. for ( var i = 0; i < orderedMotions.length; i++ ) {
  918. var array = orderedMotions[ i ];
  919. for ( var j = 0; j < array.length; j++ ) {
  920. var t = array[ j ].frameNum / 30;
  921. var p = array[ j ].position;
  922. var r = array[ j ].rotation;
  923. animation.hierarchy[ i ].keys.push(
  924. {
  925. time: t,
  926. pos: [ geometry.bones[ i ].pos[ 0 ] + p[ 0 ],
  927. geometry.bones[ i ].pos[ 1 ] + p[ 1 ],
  928. geometry.bones[ i ].pos[ 2 ] + p[ 2 ] ],
  929. rot: [ r[ 0 ], r[ 1 ], r[ 2 ], r[ 3 ] ],
  930. scl: [ 1, 1, 1 ]
  931. }
  932. );
  933. if ( t > maxTime )
  934. maxTime = t;
  935. }
  936. }
  937. // add 2 secs as afterglow
  938. maxTime += 2.0;
  939. animation.length = maxTime;
  940. for ( var i = 0; i < orderedMotions.length; i++ ) {
  941. var keys = animation.hierarchy[ i ].keys;
  942. if ( keys.length === 0 ) {
  943. keys.push( { time: 0.0,
  944. pos: [ geometry.bones[ i ].pos[ 0 ],
  945. geometry.bones[ i ].pos[ 1 ],
  946. geometry.bones[ i ].pos[ 2 ] ],
  947. rot: [ 0, 0, 0, 1 ],
  948. scl: [ 1, 1, 1 ]
  949. } );
  950. }
  951. var k = keys[ 0 ];
  952. if ( k.time !== 0.0 ) {
  953. keys.unshift( { time: 0.0,
  954. pos: [ k.pos[ 0 ], k.pos[ 1 ], k.pos[ 2 ] ],
  955. rot: [ k.rot[ 0 ], k.rot[ 1 ], k.rot[ 2 ], k.rot[ 3 ] ],
  956. scl: [ 1, 1, 1 ]
  957. } );
  958. }
  959. k = keys[ keys.length - 1 ];
  960. if ( k.time < maxTime ) {
  961. keys.push( { time: maxTime,
  962. pos: [ k.pos[ 0 ], k.pos[ 1 ], k.pos[ 2 ] ],
  963. rot: [ k.rot[ 0 ], k.rot[ 1 ], k.rot[ 2 ], k.rot[ 3 ] ],
  964. scl: [ 1, 1, 1 ]
  965. } );
  966. }
  967. }
  968. // geometry.animation = animation;
  969. geometry.animations = [];
  970. geometry.animations.push( THREE.AnimationClip.parseAnimation( animation, geometry.bones ) );
  971. };
  972. var initMorphAnimations = function () {
  973. var orderedMorphs = [];
  974. var morphTable = {}
  975. for ( var i = 0; i < model.metadata.morphCount; i++ ) {
  976. var m = model.morphs[ i ];
  977. morphTable[ m.name ] = i;
  978. orderedMorphs[ i ] = [];
  979. }
  980. for ( var i = 0; i < vmd.morphs.length; i++ ) {
  981. var m = vmd.morphs[ i ];
  982. var num = morphTable[ m.morphName ];
  983. if ( num === undefined )
  984. continue;
  985. orderedMorphs[ num ].push( m );
  986. }
  987. for ( var i = 0; i < orderedMorphs.length; i++ ) {
  988. orderedMorphs[ i ].sort( function ( a, b ) {
  989. return a.frameNum - b.frameNum;
  990. } ) ;
  991. }
  992. var morphAnimation = {
  993. fps: 30,
  994. length: 0.0,
  995. hierarchy: []
  996. };
  997. for ( var i = 0; i < model.metadata.morphCount; i++ ) {
  998. morphAnimation.hierarchy.push( { keys: [] } );
  999. }
  1000. var maxTime = 0.0;
  1001. for ( var i = 0; i < orderedMorphs.length; i++ ) {
  1002. var array = orderedMorphs[ i ];
  1003. for ( var j = 0; j < array.length; j++ ) {
  1004. var t = array[ j ].frameNum / 30;
  1005. var w = array[ j ].weight;
  1006. morphAnimation.hierarchy[ i ].keys.push( { time: t, value: w } );
  1007. if ( t > maxTime ) {
  1008. maxTime = t;
  1009. }
  1010. }
  1011. }
  1012. // add 2 secs as afterglow
  1013. maxTime += 2.0;
  1014. // use animation's length if exists. animation is master.
  1015. maxTime = ( geometry.animation !== undefined &&
  1016. geometry.animation.length > 0.0 )
  1017. ? geometry.animation.length : maxTime;
  1018. morphAnimation.length = maxTime;
  1019. for ( var i = 0; i < orderedMorphs.length; i++ ) {
  1020. var keys = morphAnimation.hierarchy[ i ].keys;
  1021. if ( keys.length === 0 ) {
  1022. keys.push( { time: 0.0, value: 0.0 } );
  1023. }
  1024. var k = keys[ 0 ];
  1025. if ( k.time !== 0.0 ) {
  1026. keys.unshift( { time: 0.0, value: k.value } );
  1027. }
  1028. k = keys[ keys.length - 1 ];
  1029. if ( k.time < maxTime ) {
  1030. keys.push( { time: maxTime, value: k.value } );
  1031. }
  1032. }
  1033. // geometry.morphAnimation = morphAnimation;
  1034. var tracks = [];
  1035. for ( var i = 1; i < orderedMorphs.length; i++ ) {
  1036. var keys = morphAnimation.hierarchy[ i ].keys;
  1037. var times = [];
  1038. var values = [];
  1039. for ( var j = 0; j < keys.length; j++ ) {
  1040. var key = keys[ j ];
  1041. times.push( key.time );
  1042. values.push( key.value );
  1043. }
  1044. tracks.push( new THREE.NumberKeyframeTrack( '.morphTargetInfluences[' + i + ']', times, values ) );
  1045. }
  1046. geometry.morphAnimations = [];
  1047. geometry.morphAnimations.push( new THREE.AnimationClip( 'morphAnimation', -1, tracks ) );
  1048. };
  1049. leftToRight();
  1050. initVartices();
  1051. initFaces();
  1052. initBones();
  1053. initIKs();
  1054. initMorphs();
  1055. initMaterials();
  1056. if ( vmd !== null ) {
  1057. initMotionAnimations();
  1058. initMorphAnimations();
  1059. }
  1060. geometry.computeFaceNormals();
  1061. geometry.verticesNeedUpdate = true;
  1062. geometry.normalsNeedUpdate = true;
  1063. geometry.uvsNeedUpdate = true;
  1064. geometry.mmdFormat = model.metadata.format;
  1065. var mesh = new THREE.SkinnedMesh( geometry, material );
  1066. // console.log( mesh ); // for console debug
  1067. return mesh;
  1068. };
  1069. THREE.MMDLoader.DataView = function ( buffer, littleEndian ) {
  1070. this.dv = new DataView( buffer );
  1071. this.offset = 0;
  1072. this.littleEndian = ( littleEndian !== undefined ) ? littleEndian : true;
  1073. this.encoder = new CharsetEncoder();
  1074. };
  1075. THREE.MMDLoader.DataView.prototype = {
  1076. constructor: THREE.MMDLoader.DataView,
  1077. getInt8: function () {
  1078. var value = this.dv.getInt8( this.offset );
  1079. this.offset += 1;
  1080. return value;
  1081. },
  1082. getInt8Array: function ( size ) {
  1083. var a = [];
  1084. for ( var i = 0; i < size; i++ ) {
  1085. a.push( this.getInt8() );
  1086. }
  1087. return a;
  1088. },
  1089. getUint8: function () {
  1090. var value = this.dv.getUint8( this.offset );
  1091. this.offset += 1;
  1092. return value;
  1093. },
  1094. getUint8Array: function ( size ) {
  1095. var a = [];
  1096. for ( var i = 0; i < size; i++ ) {
  1097. a.push( this.getUint8() );
  1098. }
  1099. return a;
  1100. },
  1101. getInt16: function () {
  1102. var value = this.dv.getInt16( this.offset, this.littleEndian );
  1103. this.offset += 2;
  1104. return value;
  1105. },
  1106. getInt16Array: function ( size ) {
  1107. var a = [];
  1108. for ( var i = 0; i < size; i++ ) {
  1109. a.push( this.getInt16() );
  1110. }
  1111. return a;
  1112. },
  1113. getUint16: function () {
  1114. var value = this.dv.getUint16( this.offset, this.littleEndian );
  1115. this.offset += 2;
  1116. return value;
  1117. },
  1118. getUint16Array: function ( size ) {
  1119. var a = [];
  1120. for ( var i = 0; i < size; i++ ) {
  1121. a.push( this.getUint16() );
  1122. }
  1123. return a;
  1124. },
  1125. getInt32: function () {
  1126. var value = this.dv.getInt32( this.offset, this.littleEndian );
  1127. this.offset += 4;
  1128. return value;
  1129. },
  1130. getInt32Array: function ( size ) {
  1131. var a = [];
  1132. for ( var i = 0; i < size; i++ ) {
  1133. a.push( this.getInt32() );
  1134. }
  1135. return a;
  1136. },
  1137. getUint32: function () {
  1138. var value = this.dv.getUint32( this.offset, this.littleEndian );
  1139. this.offset += 4;
  1140. return value;
  1141. },
  1142. getUint32Array: function ( size ) {
  1143. var a = [];
  1144. for ( var i = 0; i < size; i++ ) {
  1145. a.push( this.getUint32() );
  1146. }
  1147. return a;
  1148. },
  1149. getFloat32: function () {
  1150. var value = this.dv.getFloat32( this.offset, this.littleEndian );
  1151. this.offset += 4;
  1152. return value;
  1153. },
  1154. getFloat32Array: function( size ) {
  1155. var a = [];
  1156. for ( var i = 0; i < size; i++ ) {
  1157. a.push( this.getFloat32() );
  1158. }
  1159. return a;
  1160. },
  1161. getFloat64: function () {
  1162. var value = this.dv.getFloat64( this.offset, this.littleEndian );
  1163. this.offset += 8;
  1164. return value;
  1165. },
  1166. getFloat64Array: function( size ) {
  1167. var a = [];
  1168. for ( var i = 0; i < size; i++ ) {
  1169. a.push( this.getFloat64() );
  1170. }
  1171. return a;
  1172. },
  1173. getNumber: function ( type ) {
  1174. switch ( type ) {
  1175. case 1:
  1176. return this.getInt8();
  1177. case 2:
  1178. return this.getInt16();
  1179. case 4:
  1180. return this.getInt32();
  1181. default:
  1182. throw 'unknown number type ' + type + ' exception.';
  1183. }
  1184. },
  1185. getNumberArray: function ( type, size ) {
  1186. var a = [];
  1187. for ( var i = 0; i < size; i++ ) {
  1188. a.push( this.getNumber( type ) );
  1189. }
  1190. return a;
  1191. },
  1192. getChars: function ( size ) {
  1193. var str = '';
  1194. while ( size > 0 ) {
  1195. var value = this.getUint8();
  1196. size--;
  1197. if ( value === 0 ) {
  1198. break;
  1199. }
  1200. str += String.fromCharCode( value );
  1201. }
  1202. while ( size > 0 ) {
  1203. this.getUint8();
  1204. size--;
  1205. }
  1206. return str;
  1207. },
  1208. getSjisStringsAsUnicode: function ( size ) {
  1209. var a = [];
  1210. while ( size > 0 ) {
  1211. var value = this.getUint8();
  1212. size--;
  1213. if ( value === 0 ) {
  1214. break;
  1215. }
  1216. a.push( value );
  1217. }
  1218. while ( size > 0 ) {
  1219. this.getUint8();
  1220. size--;
  1221. }
  1222. return this.encoder.s2u( new Uint8Array( a ) );
  1223. },
  1224. /*
  1225. * Note: Sometimes to use Japanese Unicode characters runs into problems in Three.js.
  1226. * In such a case, use this method to convert it to Unicode hex charcode strings,
  1227. * like 'あいう' -> '0x30420x30440x3046'
  1228. */
  1229. toCharcodeStrings: function ( s ) {
  1230. var str = '';
  1231. for ( var i = 0; i < s.length; i++ ) {
  1232. str += '0x' + ( '0000' + s[ i ].charCodeAt().toString( 16 ) ).substr( -4 );
  1233. }
  1234. return str;
  1235. },
  1236. getUnicodeStrings: function ( size ) {
  1237. var str = '';
  1238. while ( size > 0 ) {
  1239. var value = this.getUint16();
  1240. size -= 2;
  1241. if ( value === 0 ) {
  1242. break;
  1243. }
  1244. str += String.fromCharCode( value );
  1245. }
  1246. while ( size > 0 ) {
  1247. this.getUint8();
  1248. size--;
  1249. }
  1250. return str;
  1251. },
  1252. getTextBuffer: function () {
  1253. var size = this.getUint32();
  1254. return this.getUnicodeStrings( size );
  1255. }
  1256. };