/src/away3d/loaders/parsers/AWD2Parser.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 2525 lines · 2175 code · 222 blank · 128 comment · 451 complexity · 91d69d19eb815a7708649ac5d008dfc6 MD5 · raw file

Large files are truncated click here to view the full file

  1. package away3d.loaders.parsers
  2. {
  3. import away3d.*;
  4. import away3d.animators.*;
  5. import away3d.animators.data.*;
  6. import away3d.animators.nodes.*;
  7. import away3d.cameras.*;
  8. import away3d.cameras.lenses.*;
  9. import away3d.containers.*;
  10. import away3d.core.base.*;
  11. import away3d.entities.*;
  12. import away3d.library.assets.*;
  13. import away3d.lights.*;
  14. import away3d.lights.shadowmaps.*;
  15. import away3d.loaders.misc.*;
  16. import away3d.loaders.parsers.utils.*;
  17. import away3d.materials.*;
  18. import away3d.materials.lightpickers.*;
  19. import away3d.materials.methods.*;
  20. import away3d.materials.utils.*;
  21. import away3d.primitives.*;
  22. import away3d.textures.*;
  23. import away3d.tools.utils.*;
  24. import flash.display.*;
  25. import flash.geom.*;
  26. import flash.net.*;
  27. import flash.utils.*;
  28. use namespace arcane;
  29. /**
  30. * AWDParser provides a parser for the AWD data type.
  31. */
  32. public class AWD2Parser extends ParserBase
  33. {
  34. //set to "true" to have some traces in the Console
  35. private var _debug:Boolean = false;
  36. private var _byteData:ByteArray;
  37. private var _cur_block_id:uint;
  38. private var _blocks:Vector.<AWDBlock>;
  39. private var _newBlockBytes:ByteArray;
  40. private var _version:Array;
  41. private var _compression:uint;
  42. private var _accuracyOnBlocks:Boolean;
  43. private var _accuracyMatrix:Boolean;
  44. private var _accuracyGeo:Boolean;
  45. private var _accuracyProps:Boolean;
  46. private var _matrixNrType:uint;
  47. private var _geoNrType:uint;
  48. private var _propsNrType:uint;
  49. private var _streaming:Boolean;
  50. private var _texture_users:Object;
  51. private var _body:ByteArray;
  52. private var _defaultTexture:BitmapTexture;
  53. private var _defaultCubeTexture:BitmapCubeTexture;
  54. private var _defaultBitmapMaterial:TextureMaterial;
  55. private var _cubeTextures:Array;
  56. public static const COMPRESSIONMODE_LZMA:String = "lzma";
  57. public static const UNCOMPRESSED:uint = 0;
  58. public static const DEFLATE:uint = 1;
  59. public static const LZMA:uint = 2;
  60. public static const INT8:uint = 1;
  61. public static const INT16:uint = 2;
  62. public static const INT32:uint = 3;
  63. public static const UINT8:uint = 4;
  64. public static const UINT16:uint = 5;
  65. public static const UINT32:uint = 6;
  66. public static const FLOAT32:uint = 7;
  67. public static const FLOAT64:uint = 8;
  68. public static const BOOL:uint = 21;
  69. public static const COLOR:uint = 22;
  70. public static const BADDR:uint = 23;
  71. public static const AWDSTRING:uint = 31;
  72. public static const AWDBYTEARRAY:uint = 32;
  73. public static const VECTOR2x1:uint = 41;
  74. public static const VECTOR3x1:uint = 42;
  75. public static const VECTOR4x1:uint = 43;
  76. public static const MTX3x2:uint = 44;
  77. public static const MTX3x3:uint = 45;
  78. public static const MTX4x3:uint = 46;
  79. public static const MTX4x4:uint = 47;
  80. private var blendModeDic:Vector.<String>;
  81. private var _depthSizeDic:Vector.<uint>;
  82. /**
  83. * Creates a new AWDParser object.
  84. * @param uri The url or id of the data or file to be parsed.
  85. * @param extra The holder for extra contextual data that the parser might need.
  86. */
  87. public function AWD2Parser()
  88. {
  89. super(ParserDataFormat.BINARY);
  90. blendModeDic = new Vector.<String>(); // used to translate ints to blendMode-strings
  91. blendModeDic.push(BlendMode.NORMAL);
  92. blendModeDic.push(BlendMode.ADD);
  93. blendModeDic.push(BlendMode.ALPHA);
  94. blendModeDic.push(BlendMode.DARKEN);
  95. blendModeDic.push(BlendMode.DIFFERENCE);
  96. blendModeDic.push(BlendMode.ERASE);
  97. blendModeDic.push(BlendMode.HARDLIGHT);
  98. blendModeDic.push(BlendMode.INVERT);
  99. blendModeDic.push(BlendMode.LAYER);
  100. blendModeDic.push(BlendMode.LIGHTEN);
  101. blendModeDic.push(BlendMode.MULTIPLY);
  102. blendModeDic.push(BlendMode.NORMAL);
  103. blendModeDic.push(BlendMode.OVERLAY);
  104. blendModeDic.push(BlendMode.SCREEN);
  105. blendModeDic.push(BlendMode.SHADER);
  106. blendModeDic.push(BlendMode.OVERLAY);
  107. _depthSizeDic = new Vector.<uint>(); // used to translate ints to depthSize-values
  108. _depthSizeDic.push(256);
  109. _depthSizeDic.push(512);
  110. _depthSizeDic.push(2048);
  111. _depthSizeDic.push(1024);
  112. }
  113. /**
  114. * Indicates whether or not a given file extension is supported by the parser.
  115. * @param extension The file extension of a potential file to be parsed.
  116. * @return Whether or not the given file type is supported.
  117. */
  118. public static function supportsType(extension:String):Boolean
  119. {
  120. extension = extension.toLowerCase();
  121. return extension == "awd";
  122. }
  123. /**
  124. * Tests whether a data block can be parsed by the parser.
  125. * @param data The data block to potentially be parsed.
  126. * @return Whether or not the given data is supported.
  127. */
  128. public static function supportsData(data:*):Boolean
  129. {
  130. return (ParserUtil.toString(data, 3) == 'AWD');
  131. }
  132. /**
  133. * @inheritDoc
  134. */
  135. override arcane function resolveDependency(resourceDependency:ResourceDependency):void
  136. {
  137. // this function will be called when Dependency has finished loading.
  138. // the Assets waiting for this Bitmap, can be Texture or CubeTexture.
  139. // if the Bitmap is awaited by a CubeTexture, we need to check if its the last Bitmap of the CubeTexture,
  140. // so we know if we have to finalize the Asset (CubeTexture) or not.
  141. if (resourceDependency.assets.length == 1) {
  142. var isCubeTextureArray:Array = resourceDependency.id.split("#");
  143. var ressourceID:String = isCubeTextureArray[0];
  144. var asset:TextureProxyBase;
  145. var thisBitmapTexture:Texture2DBase;
  146. var block:AWDBlock;
  147. if (isCubeTextureArray.length == 1) {
  148. asset = resourceDependency.assets[0] as Texture2DBase;
  149. if (asset) {
  150. var mat:TextureMaterial;
  151. var users:Array;
  152. block = _blocks[parseInt(resourceDependency.id)];
  153. block.data = asset; // Store finished asset
  154. // Reset name of texture to the one defined in the AWD file,
  155. // as opposed to whatever the image parser came up with.
  156. asset.resetAssetPath(block.name, null, true);
  157. block.name = asset.name;
  158. // Finalize texture asset to dispatch texture event, which was
  159. // previously suppressed while the dependency was loaded.
  160. finalizeAsset(asset);
  161. if (_debug) {
  162. trace("Successfully loadet Bitmap for texture");
  163. trace("Parsed CubeTexture: Name = " + block.name);
  164. }
  165. }
  166. }
  167. if (isCubeTextureArray.length > 1) {
  168. thisBitmapTexture = resourceDependency.assets[0] as BitmapTexture;
  169. _cubeTextures[uint(isCubeTextureArray[1])] = BitmapTexture(thisBitmapTexture).bitmapData;
  170. _texture_users[ressourceID].push(1);
  171. if (_debug)
  172. trace("Successfully loadet Bitmap " + _texture_users[ressourceID].length + " / 6 for Cubetexture");
  173. if (_texture_users[ressourceID].length == _cubeTextures.length) {
  174. asset = new BitmapCubeTexture(_cubeTextures[0], _cubeTextures[1], _cubeTextures[2], _cubeTextures[3], _cubeTextures[4], _cubeTextures[5]);
  175. block = _blocks[ressourceID];
  176. block.data = asset; // Store finished asset
  177. // Reset name of texture to the one defined in the AWD file,
  178. // as opposed to whatever the image parser came up with.
  179. asset.resetAssetPath(block.name, null, true);
  180. block.name = asset.name;
  181. // Finalize texture asset to dispatch texture event, which was
  182. // previously suppressed while the dependency was loaded.
  183. finalizeAsset(asset);
  184. if (_debug)
  185. trace("Parsed CubeTexture: Name = " + block.name);
  186. }
  187. }
  188. }
  189. }
  190. /**
  191. * @inheritDoc
  192. */
  193. override arcane function resolveDependencyFailure(resourceDependency:ResourceDependency):void
  194. {
  195. //not used - if a dependcy fails, the awaiting Texture or CubeTexture will never be finalized, and the default-bitmaps will be used.
  196. // this means, that if one Bitmap of a CubeTexture fails, the CubeTexture will have the DefaultTexture applied for all six Bitmaps.
  197. }
  198. /**
  199. * Resolve a dependency name
  200. *
  201. * @param resourceDependency The dependency to be resolved.
  202. */
  203. arcane override function resolveDependencyName(resourceDependency:ResourceDependency, asset:IAsset):String
  204. {
  205. var oldName:String = asset.name;
  206. if (asset) {
  207. var block:AWDBlock = _blocks[parseInt(resourceDependency.id)];
  208. // Reset name of texture to the one defined in the AWD file,
  209. // as opposed to whatever the image parser came up with.
  210. asset.resetAssetPath(block.name, null, true);
  211. }
  212. var newName:String = asset.name;
  213. asset.name = oldName;
  214. return newName;
  215. }
  216. /**
  217. * @inheritDoc
  218. */
  219. protected override function startParsing(frameLimit:Number):void
  220. {
  221. super.startParsing(frameLimit);
  222. _texture_users = {};
  223. _byteData = getByteData();
  224. _blocks = new Vector.<AWDBlock>();
  225. _blocks[0] = new AWDBlock();
  226. _blocks[0].data = null; // Zero address means null in AWD
  227. _version = []; // will contain 2 int (major-version, minor-version) for awd-version-check
  228. //parse header
  229. _byteData.endian = Endian.LITTLE_ENDIAN;
  230. // Parse header and decompress body if needed
  231. parseHeader();
  232. switch (_compression) {
  233. case DEFLATE:
  234. _body = new ByteArray();
  235. _byteData.readBytes(_body, 0, _byteData.bytesAvailable);
  236. _body.uncompress();
  237. break;
  238. case LZMA:
  239. _body = new ByteArray();
  240. _byteData.readBytes(_body, 0, _byteData.bytesAvailable);
  241. _body.uncompress(COMPRESSIONMODE_LZMA);
  242. break;
  243. case UNCOMPRESSED:
  244. _body = _byteData;
  245. break;
  246. }
  247. _body.endian = Endian.LITTLE_ENDIAN;
  248. }
  249. /**
  250. * @inheritDoc
  251. */
  252. protected override function proceedParsing():Boolean
  253. {
  254. while (_body.bytesAvailable > 0 && !parsingPaused && hasTime())
  255. parseNextBlock();
  256. // Return complete status
  257. if (_body.bytesAvailable == 0)
  258. return PARSING_DONE;
  259. else
  260. return MORE_TO_PARSE;
  261. }
  262. private function parseHeader():void
  263. {
  264. var flags:uint;
  265. var body_len:Number;
  266. _byteData.position = 3; // Skip magic string and parse version
  267. _version[0] = _byteData.readUnsignedByte();
  268. _version[1] = _byteData.readUnsignedByte();
  269. flags = _byteData.readUnsignedShort(); // Parse bit flags
  270. _streaming = bitFlags.test(flags, bitFlags.FLAG1);
  271. if ((_version[0] == 2) && (_version[1] == 1)) {
  272. _accuracyMatrix = bitFlags.test(flags, bitFlags.FLAG2);
  273. _accuracyGeo = bitFlags.test(flags, bitFlags.FLAG3);
  274. _accuracyProps = bitFlags.test(flags, bitFlags.FLAG4);
  275. }
  276. // if we set _accuracyOnBlocks, the precision-values are read from each block-header.
  277. // set storagePrecision types
  278. _geoNrType = FLOAT32;
  279. if (_accuracyGeo)
  280. _geoNrType = FLOAT64;
  281. _matrixNrType = FLOAT32;
  282. if (_accuracyMatrix)
  283. _matrixNrType = FLOAT64;
  284. _propsNrType = FLOAT32;
  285. if (_accuracyProps)
  286. _propsNrType = FLOAT64;
  287. _compression = _byteData.readUnsignedByte(); // compression
  288. if (_debug) {
  289. trace("Import AWDFile of version = " + _version[0] + " - " + _version[1]);
  290. trace("Global Settings = Compression = " + _compression + " | Streaming = " + _streaming + " | Matrix-Precision = " + _accuracyMatrix + " | Geometry-Precision = " + _accuracyGeo + " | Properties-Precision = " + _accuracyProps);
  291. }
  292. // Check file integrity
  293. body_len = _byteData.readUnsignedInt();
  294. if (!_streaming && body_len != _byteData.bytesAvailable)
  295. dieWithError('AWD2 body length does not match header integrity field');
  296. }
  297. private function parseNextBlock():void
  298. {
  299. var block:AWDBlock;
  300. var assetData:IAsset;
  301. var isParsed:Boolean;
  302. var ns:uint, type:uint, flags:uint, len:uint;
  303. _cur_block_id = _body.readUnsignedInt();
  304. ns = _body.readUnsignedByte();
  305. type = _body.readUnsignedByte();
  306. flags = _body.readUnsignedByte();
  307. len = _body.readUnsignedInt();
  308. var blockCompression:Boolean = bitFlags.test(flags, bitFlags.FLAG4);
  309. var blockCompressionLZMA:Boolean = bitFlags.test(flags, bitFlags.FLAG5);
  310. if (_accuracyOnBlocks) {
  311. _accuracyMatrix = bitFlags.test(flags, bitFlags.FLAG1);
  312. _accuracyGeo = bitFlags.test(flags, bitFlags.FLAG2);
  313. _accuracyProps = bitFlags.test(flags, bitFlags.FLAG3);
  314. _geoNrType = FLOAT32;
  315. if (_accuracyGeo)
  316. _geoNrType = FLOAT64;
  317. _matrixNrType = FLOAT32;
  318. if (_accuracyMatrix)
  319. _matrixNrType = FLOAT64;
  320. _propsNrType = FLOAT32;
  321. if (_accuracyProps)
  322. _propsNrType = FLOAT64;
  323. }
  324. var blockEndAll:uint = _body.position + len;
  325. if (len > _body.bytesAvailable) {
  326. dieWithError('AWD2 block length is bigger than the bytes that are available!');
  327. _body.position += _body.bytesAvailable;
  328. return;
  329. }
  330. _newBlockBytes = new ByteArray();
  331. _body.readBytes(_newBlockBytes, 0, len);
  332. if (blockCompression) {
  333. if (blockCompressionLZMA)
  334. _newBlockBytes.uncompress(COMPRESSIONMODE_LZMA);
  335. else
  336. _newBlockBytes.uncompress();
  337. }
  338. _newBlockBytes.endian = Endian.LITTLE_ENDIAN;
  339. _newBlockBytes.position = 0;
  340. block = new AWDBlock();
  341. block.len = _newBlockBytes.position + len;
  342. block.id = _cur_block_id;
  343. var blockEndBlock:uint = _newBlockBytes.position + len;
  344. if (blockCompression) {
  345. blockEndBlock = _newBlockBytes.position + _newBlockBytes.length;
  346. block.len = blockEndBlock;
  347. }
  348. if (_debug)
  349. trace("AWDBlock: ID = " + _cur_block_id + " | TypeID = " + type + " | Compression = " + blockCompression + " | Matrix-Precision = " + _accuracyMatrix + " | Geometry-Precision = " + _accuracyGeo + " | Properties-Precision = " + _accuracyProps);
  350. _blocks[_cur_block_id] = block;
  351. if ((_version[0] == 2) && (_version[1] == 1)) {
  352. switch (type) {
  353. case 11:
  354. parsePrimitves(_cur_block_id);
  355. isParsed = true;
  356. break;
  357. case 31:
  358. parseSkyBoxInstance(_cur_block_id);
  359. isParsed = true;
  360. break;
  361. case 41:
  362. parseLight(_cur_block_id);
  363. isParsed = true;
  364. break;
  365. case 42:
  366. parseCamera(_cur_block_id);
  367. isParsed = true;
  368. break;
  369. case 43:
  370. parseTextureProjector(_cur_block_id);
  371. isParsed = true;
  372. break;
  373. case 51:
  374. parseLightPicker(_cur_block_id);
  375. isParsed = true;
  376. break;
  377. case 81:
  378. parseMaterial_v1(_cur_block_id);
  379. isParsed = true;
  380. break;
  381. case 83:
  382. parseCubeTexture(_cur_block_id);
  383. isParsed = true;
  384. break;
  385. case 91:
  386. parseSharedMethodBlock(_cur_block_id);
  387. isParsed = true;
  388. break;
  389. case 92:
  390. parseShadowMethodBlock(_cur_block_id);
  391. isParsed = true;
  392. break;
  393. case 111:
  394. parseMeshPoseAnimation(_cur_block_id, true);
  395. isParsed = true;
  396. break;
  397. case 112:
  398. parseMeshPoseAnimation(_cur_block_id);
  399. isParsed = true;
  400. break;
  401. case 113:
  402. parseVertexAnimationSet(_cur_block_id);
  403. isParsed = true;
  404. break;
  405. case 122:
  406. parseAnimatorSet(_cur_block_id);
  407. isParsed = true;
  408. break;
  409. case 253:
  410. parseCommand(_cur_block_id);
  411. isParsed = true;
  412. break;
  413. }
  414. }
  415. if (isParsed == false) {
  416. switch (type) {
  417. case 1:
  418. parseTriangleGeometrieBlock(_cur_block_id);
  419. break;
  420. case 22:
  421. parseContainer(_cur_block_id);
  422. break;
  423. case 23:
  424. parseMeshInstance(_cur_block_id);
  425. break;
  426. case 81:
  427. parseMaterial(_cur_block_id);
  428. break;
  429. case 82:
  430. parseTexture(_cur_block_id);
  431. break;
  432. case 101:
  433. parseSkeleton(_cur_block_id);
  434. break;
  435. case 102:
  436. parseSkeletonPose(_cur_block_id);
  437. break;
  438. case 103:
  439. parseSkeletonAnimation(_cur_block_id);
  440. break;
  441. case 121:
  442. parseUVAnimation(_cur_block_id);
  443. break;
  444. case 254:
  445. parseNameSpace(_cur_block_id);
  446. break;
  447. case 255:
  448. parseMetaData(_cur_block_id);
  449. break;
  450. default:
  451. if (_debug)
  452. trace("AWDBlock: Unknown BlockType (BlockID = " + _cur_block_id + ") - Skip " + len + " bytes");
  453. _newBlockBytes.position += len;
  454. break;
  455. }
  456. }
  457. var msgCnt:uint = 0;
  458. if (_newBlockBytes.position == blockEndBlock) {
  459. if (_debug) {
  460. if (block.errorMessages) {
  461. while (msgCnt < block.errorMessages.length) {
  462. trace(" (!) Error: " + block.errorMessages[msgCnt] + " (!)");
  463. msgCnt++;
  464. }
  465. }
  466. }
  467. if (_debug)
  468. trace("\n");
  469. } else {
  470. if (_debug) {
  471. trace(" (!)(!)(!) Error while reading AWDBlock ID " + _cur_block_id + " = skip to next block");
  472. if (block.errorMessages) {
  473. while (msgCnt < block.errorMessages.length) {
  474. trace(" (!) Error: " + block.errorMessages[msgCnt] + " (!)");
  475. msgCnt++;
  476. }
  477. }
  478. }
  479. }
  480. _body.position = blockEndAll;
  481. _newBlockBytes = null;
  482. }
  483. //Block ID = 1
  484. private function parseTriangleGeometrieBlock(blockID:uint):void
  485. {
  486. var geom:Geometry = new Geometry();
  487. // Read name and sub count
  488. var name:String = parseVarStr();
  489. var num_subs:uint = _newBlockBytes.readUnsignedShort();
  490. // Read optional properties
  491. var props:AWDProperties = parseProperties({1:_geoNrType, 2:_geoNrType});
  492. var geoScaleU:Number = props.get(1, 1);
  493. var geoScaleV:Number = props.get(2, 1);
  494. var sub_geoms:Vector.<ISubGeometry> = new Vector.<ISubGeometry>;
  495. // Loop through sub meshes
  496. var subs_parsed:uint = 0;
  497. while (subs_parsed < num_subs) {
  498. var i:uint;
  499. var sm_len:uint, sm_end:uint;
  500. var w_indices:Vector.<Number>;
  501. var weights:Vector.<Number>;
  502. sm_len = _newBlockBytes.readUnsignedInt();
  503. sm_end = _newBlockBytes.position + sm_len;
  504. // Ignore for now
  505. var subProps:AWDProperties = parseProperties({1:_geoNrType, 2:_geoNrType});
  506. // Loop through data streams
  507. while (_newBlockBytes.position < sm_end) {
  508. var idx:uint = 0;
  509. var str_ftype:uint, str_type:uint, str_len:uint, str_end:uint;
  510. // Type, field type, length
  511. str_type = _newBlockBytes.readUnsignedByte();
  512. str_ftype = _newBlockBytes.readUnsignedByte();
  513. str_len = _newBlockBytes.readUnsignedInt();
  514. str_end = _newBlockBytes.position + str_len;
  515. var x:Number, y:Number, z:Number;
  516. if (str_type == 1) {
  517. var verts:Vector.<Number> = new Vector.<Number>();
  518. while (_newBlockBytes.position < str_end) {
  519. // TODO: Respect stream field type
  520. x = readNumber(_accuracyGeo);
  521. y = readNumber(_accuracyGeo);
  522. z = readNumber(_accuracyGeo);
  523. verts[idx++] = x;
  524. verts[idx++] = y;
  525. verts[idx++] = z;
  526. }
  527. } else if (str_type == 2) {
  528. var indices:Vector.<uint> = new Vector.<uint>();
  529. while (_newBlockBytes.position < str_end) {
  530. // TODO: Respect stream field type
  531. indices[idx++] = _newBlockBytes.readUnsignedShort();
  532. }
  533. } else if (str_type == 3) {
  534. var uvs:Vector.<Number> = new Vector.<Number>();
  535. while (_newBlockBytes.position < str_end)
  536. uvs[idx++] = readNumber(_accuracyGeo);
  537. } else if (str_type == 4) {
  538. var normals:Vector.<Number> = new Vector.<Number>();
  539. while (_newBlockBytes.position < str_end)
  540. normals[idx++] = readNumber(_accuracyGeo);
  541. } else if (str_type == 6) {
  542. w_indices = new Vector.<Number>();
  543. while (_newBlockBytes.position < str_end)
  544. w_indices[idx++] = _newBlockBytes.readUnsignedShort()*3; // TODO: Respect stream field type
  545. } else if (str_type == 7) {
  546. weights = new Vector.<Number>();
  547. while (_newBlockBytes.position < str_end)
  548. weights[idx++] = readNumber(_accuracyGeo);
  549. } else
  550. _newBlockBytes.position = str_end;
  551. }
  552. parseUserAttributes(); // Ignore sub-mesh attributes for now
  553. sub_geoms = GeomUtil.fromVectors(verts, indices, uvs, normals, null, weights, w_indices);
  554. var scaleU:Number = subProps.get(1, 1);
  555. var scaleV:Number = subProps.get(2, 1);
  556. var setSubUVs:Boolean = false; //this should remain false atm, because in AwayBuilder the uv is only scaled by the geometry
  557. if ((geoScaleU != scaleU) || (geoScaleV != scaleV)) {
  558. trace("set sub uvs");
  559. setSubUVs = true;
  560. scaleU = geoScaleU/scaleU;
  561. scaleV = geoScaleV/scaleV;
  562. }
  563. for (i = 0; i < sub_geoms.length; i++) {
  564. if (setSubUVs)
  565. sub_geoms[i].scaleUV(scaleU, scaleV);
  566. geom.addSubGeometry(sub_geoms[i]);
  567. // TODO: Somehow map in-sub to out-sub indices to enable look-up
  568. // when creating meshes (and their material assignments.)
  569. }
  570. subs_parsed++;
  571. }
  572. if ((geoScaleU != 1) || (geoScaleV != 1))
  573. geom.scaleUV(geoScaleU, geoScaleV);
  574. parseUserAttributes();
  575. finalizeAsset(geom, name);
  576. _blocks[blockID].data = geom;
  577. if (_debug)
  578. trace("Parsed a TriangleGeometry: Name = " + name + "| SubGeometries = " + sub_geoms.length);
  579. }
  580. //Block ID = 11
  581. private function parsePrimitves(blockID:uint):void
  582. {
  583. var name:String;
  584. var geom:Geometry;
  585. var primType:uint;
  586. var subs_parsed:uint;
  587. var props:AWDProperties;
  588. var bsm:Matrix3D;
  589. // Read name and sub count
  590. name = parseVarStr();
  591. primType = _newBlockBytes.readUnsignedByte();
  592. props = parseProperties({101:_geoNrType, 102:_geoNrType, 103:_geoNrType, 110:_geoNrType, 111:_geoNrType, 301:UINT16, 302:UINT16, 303:UINT16, 701:BOOL, 702:BOOL, 703:BOOL, 704:BOOL});
  593. var primitveTypes:Array = ["Unsupported Type-ID", "PlaneGeometry", "CubeGeometry", "SphereGeometry", "CylinderGeometry", "ConeGeometry", "CapsuleGeometry", "TorusGeometry"]
  594. switch (primType) {
  595. // to do, not all properties are set on all primitives
  596. case 1:
  597. geom = new PlaneGeometry(props.get(101, 100), props.get(102, 100), props.get(301, 1), props.get(302, 1), props.get(701, true), props.get(702, false));
  598. break;
  599. case 2:
  600. geom = new CubeGeometry(props.get(101, 100), props.get(102, 100), props.get(103, 100), props.get(301, 1), props.get(302, 1), props.get(303, 1), props.get(701, true));
  601. break;
  602. case 3:
  603. geom = new SphereGeometry(props.get(101, 50), props.get(301, 16), props.get(302, 12), props.get(701, true));
  604. break;
  605. case 4:
  606. geom = new CylinderGeometry(props.get(101, 50), props.get(102, 50), props.get(103, 100), props.get(301, 16), props.get(302, 1), true, true, true); // bool701, bool702, bool703, bool704);
  607. if (!props.get(701, true))
  608. CylinderGeometry(geom).topClosed = false;
  609. if (!props.get(702, true))
  610. CylinderGeometry(geom).bottomClosed = false;
  611. if (!props.get(703, true))
  612. CylinderGeometry(geom).yUp = false;
  613. break;
  614. case 5:
  615. geom = new ConeGeometry(props.get(101, 50), props.get(102, 100), props.get(301, 16), props.get(302, 1), props.get(701, true), props.get(702, true));
  616. break;
  617. case 6:
  618. geom = new CapsuleGeometry(props.get(101, 50), props.get(102, 100), props.get(301, 16), props.get(302, 15), props.get(701, true));
  619. break;
  620. case 7:
  621. geom = new TorusGeometry(props.get(101, 50), props.get(102, 50), props.get(301, 16), props.get(302, 8), props.get(701, true));
  622. break;
  623. default:
  624. geom = new Geometry();
  625. trace("ERROR: UNSUPPORTED PRIMITIVE_TYPE");
  626. break;
  627. }
  628. if ((props.get(110, 1) != 1) || (props.get(111, 1) != 1)) {
  629. geom.subGeometries;
  630. geom.scaleUV(props.get(110, 1), props.get(111, 1));
  631. }
  632. parseUserAttributes();
  633. geom.name = name;
  634. finalizeAsset(geom, name);
  635. _blocks[blockID].data = geom;
  636. if (_debug) {
  637. if ((primType < 0) || (primType > 7))
  638. primType = 0;
  639. trace("Parsed a Primivite: Name = " + name + "| type = " + primitveTypes[primType]);
  640. }
  641. }
  642. // Block ID = 22
  643. private function parseContainer(blockID:uint):void
  644. {
  645. var name:String;
  646. var par_id:uint;
  647. var mtx:Matrix3D;
  648. var ctr:ObjectContainer3D;
  649. var parent:ObjectContainer3D;
  650. par_id = _newBlockBytes.readUnsignedInt();
  651. mtx = parseMatrix3D();
  652. name = parseVarStr();
  653. var parentName:String = "Root (TopLevel)";
  654. ctr = new ObjectContainer3D();
  655. ctr.transform = mtx;
  656. var returnedArray:Array = getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH, AssetType.ENTITY, AssetType.SEGMENT_SET])
  657. if (returnedArray[0]) {
  658. ObjectContainer3D(returnedArray[1]).addChild(ctr);
  659. parentName = ObjectContainer3D(returnedArray[1]).name;
  660. } else if (par_id > 0)
  661. _blocks[blockID].addError("Could not find a parent for this ObjectContainer3D");
  662. // in AWD version 2.1 we read the Container properties
  663. if ((_version[0] == 2) && (_version[1] == 1)) {
  664. var props:Object = parseProperties({1:_matrixNrType, 2:_matrixNrType, 3:_matrixNrType, 4:UINT8});
  665. ctr.pivotPoint = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0));
  666. }
  667. // in other versions we do not read the Container properties
  668. else
  669. parseProperties(null);
  670. // the extraProperties should only be set for AWD2.1-Files, but is read for both versions
  671. ctr.extra = parseUserAttributes();
  672. finalizeAsset(ctr, name);
  673. _blocks[blockID].data = ctr;
  674. if (_debug)
  675. trace("Parsed a Container: Name = '" + name + "' | Parent-Name = " + parentName);
  676. }
  677. // Block ID = 23
  678. private function parseMeshInstance(blockID:uint):void
  679. {
  680. var num_materials:uint;
  681. var materials_parsed:uint;
  682. var parent:ObjectContainer3D;
  683. var par_id:uint = _newBlockBytes.readUnsignedInt();
  684. var mtx:Matrix3D = parseMatrix3D();
  685. var name:String = parseVarStr();
  686. var parentName:String = "Root (TopLevel)";
  687. var data_id:uint = _newBlockBytes.readUnsignedInt();
  688. var geom:Geometry;
  689. var returnedArrayGeometry:Array = getAssetByID(data_id, [AssetType.GEOMETRY])
  690. if (returnedArrayGeometry[0])
  691. geom = returnedArrayGeometry[1] as Geometry;
  692. else {
  693. _blocks[blockID].addError("Could not find a Geometry for this Mesh. A empty Geometry is created!");
  694. geom = new Geometry();
  695. }
  696. _blocks[blockID].geoID = data_id;
  697. var materials:Vector.<MaterialBase> = new Vector.<MaterialBase>();
  698. num_materials = _newBlockBytes.readUnsignedShort();
  699. var materialNames:Array = new Array();
  700. materials_parsed = 0;
  701. var returnedArrayMaterial:Array;
  702. while (materials_parsed < num_materials) {
  703. var mat_id:uint;
  704. mat_id = _newBlockBytes.readUnsignedInt();
  705. returnedArrayMaterial = getAssetByID(mat_id, [AssetType.MATERIAL])
  706. if ((!returnedArrayMaterial[0]) && (mat_id > 0))
  707. _blocks[blockID].addError("Could not find Material Nr " + materials_parsed + " (ID = " + mat_id + " ) for this Mesh");
  708. materials.push(returnedArrayMaterial[1] as MaterialBase);
  709. materialNames.push(MaterialBase(returnedArrayMaterial[1]).name);
  710. materials_parsed++;
  711. }
  712. var mesh:Mesh = new Mesh(geom, null);
  713. mesh.transform = mtx;
  714. var returnedArrayParent:Array = getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH, AssetType.ENTITY, AssetType.SEGMENT_SET])
  715. if (returnedArrayParent[0]) {
  716. ObjectContainer3D(returnedArrayParent[1]).addChild(mesh);
  717. parentName = ObjectContainer3D(returnedArrayParent[1]).name;
  718. } else if (par_id > 0)
  719. _blocks[blockID].addError("Could not find a parent for this Mesh");
  720. if (materials.length >= 1 && mesh.subMeshes.length == 1)
  721. mesh.material = materials[0];
  722. else if (materials.length > 1) {
  723. var i:uint;
  724. // Assign each sub-mesh in the mesh a material from the list. If more sub-meshes
  725. // than materials, repeat the last material for all remaining sub-meshes.
  726. for (i = 0; i < mesh.subMeshes.length; i++)
  727. mesh.subMeshes[i].material = materials[Math.min(materials.length - 1, i)];
  728. }
  729. if ((_version[0] == 2) && (_version[1] == 1)) {
  730. var props:Object = parseProperties({1:_matrixNrType, 2:_matrixNrType, 3:_matrixNrType, 4:UINT8, 5:BOOL});
  731. mesh.pivotPoint = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0));
  732. mesh.castsShadows = props.get(5, true);
  733. } else
  734. parseProperties(null);
  735. mesh.extra = parseUserAttributes();
  736. finalizeAsset(mesh, name);
  737. _blocks[blockID].data = mesh;
  738. if (_debug)
  739. trace("Parsed a Mesh: Name = '" + name + "' | Parent-Name = " + parentName + "| Geometry-Name = " + geom.name + " | SubMeshes = " + mesh.subMeshes.length + " | Mat-Names = " + materialNames.toString());
  740. }
  741. //Block ID 31
  742. private function parseSkyBoxInstance(blockID:uint):void
  743. {
  744. var name:String = parseVarStr();
  745. var cubeTexAddr:uint = _newBlockBytes.readUnsignedInt();
  746. var returnedArrayCubeTex:Array = getAssetByID(cubeTexAddr, [AssetType.TEXTURE], "CubeTexture");
  747. if ((!returnedArrayCubeTex[0]) && (cubeTexAddr != 0))
  748. _blocks[blockID].addError("Could not find the Cubetexture (ID = " + cubeTexAddr + " ) for this SkyBox");
  749. var asset:SkyBox = new SkyBox(returnedArrayCubeTex[1] as BitmapCubeTexture);
  750. parseProperties(null)
  751. asset.extra = parseUserAttributes();
  752. finalizeAsset(asset, name);
  753. _blocks[blockID].data = asset;
  754. if (_debug)
  755. trace("Parsed a SkyBox: Name = '" + name + "' | CubeTexture-Name = " + BitmapCubeTexture(returnedArrayCubeTex[1]).name);
  756. }
  757. //Block ID = 41
  758. private function parseLight(blockID:uint):void
  759. {
  760. var light:LightBase;
  761. var newShadowMapper:ShadowMapperBase;
  762. var par_id:uint = _newBlockBytes.readUnsignedInt();
  763. var mtx:Matrix3D = parseMatrix3D();
  764. var name:String = parseVarStr();
  765. var lightType:uint = _newBlockBytes.readUnsignedByte();
  766. var props:AWDProperties = parseProperties({1:_propsNrType, 2:_propsNrType, 3:COLOR, 4:_propsNrType, 5:_propsNrType, 6:BOOL, 7:COLOR, 8:_propsNrType, 9:UINT8, 10:UINT8, 11:_propsNrType, 12:UINT16, 21:_matrixNrType, 22:_matrixNrType, 23:_matrixNrType});
  767. var shadowMapperType:uint = props.get(9, 0);
  768. var parentName:String = "Root (TopLevel)";
  769. var lightTypes:Array = ["Unsupported LightType", "PointLight", "DirectionalLight"];
  770. var shadowMapperTypes:Array = ["No ShadowMapper", "DirectionalShadowMapper", "NearDirectionalShadowMapper", "CascadeShadowMapper", "CubeMapShadowMapper"];
  771. if (lightType == 1) {
  772. light = new PointLight();
  773. PointLight(light).radius = props.get(1, 90000);
  774. PointLight(light).fallOff = props.get(2, 100000);
  775. if (shadowMapperType > 0) {
  776. if (shadowMapperType == 4)
  777. newShadowMapper = new CubeMapShadowMapper();
  778. }
  779. light.transform = mtx;
  780. }
  781. if (lightType == 2) {
  782. light = new DirectionalLight(props.get(21, 0), props.get(22, -1), props.get(23, 1));
  783. if (shadowMapperType > 0) {
  784. if (shadowMapperType == 1)
  785. newShadowMapper = new DirectionalShadowMapper();
  786. if (shadowMapperType == 2)
  787. newShadowMapper = new NearDirectionalShadowMapper(props.get(11, 0.5));
  788. if (shadowMapperType == 3)
  789. newShadowMapper = new CascadeShadowMapper(props.get(12, 3));
  790. }
  791. }
  792. if ((lightType != 2) && (lightType != 1)){
  793. _blocks[blockID].addError("Unsuported lighttype = "+lightType);
  794. return
  795. }
  796. light.color = props.get(3, 0xffffff);
  797. light.specular = props.get(4, 1.0);
  798. light.diffuse = props.get(5, 1.0);
  799. light.ambientColor = props.get(7, 0xffffff);
  800. light.ambient = props.get(8, 0.0);
  801. // if a shadowMapper has been created, adjust the depthMapSize if needed, assign to light and set castShadows to true
  802. if (newShadowMapper) {
  803. if (newShadowMapper is CubeMapShadowMapper) {
  804. if (props.get(10, 1) != 1)
  805. newShadowMapper.depthMapSize = _depthSizeDic[props.get(10, 1)];
  806. } else {
  807. if (props.get(10, 2) != 2)
  808. newShadowMapper.depthMapSize = _depthSizeDic[props.get(10, 2)];
  809. }
  810. light.shadowMapper = newShadowMapper;
  811. light.castsShadows = true;
  812. }
  813. if (par_id != 0) {
  814. var returnedArrayParent:Array = getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH, AssetType.ENTITY, AssetType.SEGMENT_SET])
  815. if (returnedArrayParent[0]) {
  816. ObjectContainer3D(returnedArrayParent[1]).addChild(light);
  817. parentName = ObjectContainer3D(returnedArrayParent[1]).name;
  818. } else
  819. _blocks[blockID].addError("Could not find a parent for this Light");
  820. }
  821. parseUserAttributes();
  822. finalizeAsset(light, name);
  823. _blocks[blockID].data = light;
  824. if (_debug)
  825. trace("Parsed a Light: Name = '" + name + "' | Type = " + lightTypes[lightType] + " | Parent-Name = " + parentName + " | ShadowMapper-Type = " + shadowMapperTypes[shadowMapperType]);
  826. }
  827. //Block ID = 43
  828. private function parseCamera(blockID:uint):void
  829. {
  830. var par_id:uint = _newBlockBytes.readUnsignedInt();
  831. var mtx:Matrix3D = parseMatrix3D();
  832. var name:String = parseVarStr();
  833. var parentName:String = "Root (TopLevel)";
  834. var lens:LensBase;
  835. _newBlockBytes.readUnsignedByte(); //set as active camera
  836. _newBlockBytes.readShort(); //lengthof lenses - not used yet
  837. var lenstype:uint = _newBlockBytes.readShort();
  838. var props:AWDProperties = parseProperties({101:_propsNrType, 102:_propsNrType, 103:_propsNrType, 104:_propsNrType});
  839. switch (lenstype) {
  840. case 5001:
  841. lens = new PerspectiveLens(props.get(101, 60));
  842. break;
  843. case 5002:
  844. lens = new OrthographicLens(props.get(101, 500));
  845. break;
  846. case 5003:
  847. lens = new OrthographicOffCenterLens(props.get(101, -400), props.get(102, 400), props.get(103, -300), props.get(104, 300));
  848. break;
  849. default:
  850. trace("unsupportedLenstype");
  851. return;
  852. }
  853. var camera:Camera3D = new Camera3D(lens);
  854. camera.transform = mtx;
  855. var returnedArrayParent:Array = getAssetByID(par_id, [AssetType.CONTAINER, AssetType.LIGHT, AssetType.MESH, AssetType.ENTITY, AssetType.SEGMENT_SET])
  856. if (returnedArrayParent[0]) {
  857. ObjectContainer3D(returnedArrayParent[1]).addChild(camera);
  858. parentName = ObjectContainer3D(returnedArrayParent[1]).name;
  859. } else if (par_id > 0)
  860. _blocks[blockID].addError("Could not find a parent for this Camera");
  861. camera.name = name;
  862. props = parseProperties({1:_matrixNrType, 2:_matrixNrType, 3:_matrixNrType, 4:UINT8, 101:_propsNrType, 102:_propsNrType});
  863. camera.pivotPoint = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0));
  864. camera.lens.near = props.get(101, 20);
  865. camera.lens.far = props.get(102, 3000);
  866. camera.extra = parseUserAttributes();
  867. finalizeAsset(camera, name);
  868. _blocks[blockID].data = camera
  869. if (_debug)
  870. trace("Parsed a Camera: Name = '" + name + "' | Lenstype = " + lens + " | Parent-Name = " + parentName);
  871. }
  872. //Block ID = 43
  873. private function parseTextureProjector(blockID:uint):void
  874. {
  875. var par_id:uint = _newBlockBytes.readUnsignedInt();
  876. var mtx:Matrix3D = parseMatrix3D();
  877. var name:String = parseVarStr();
  878. var parentName:String = "Root (TopLevel)";
  879. var tex_id:uint = _newBlockBytes.readUnsignedInt();
  880. var returnedArrayGeometry:Array = getAssetByID(tex_id, [AssetType.TEXTURE])
  881. if ((!returnedArrayGeometry[0]) && (tex_id != 0))
  882. _blocks[blockID].addError("Could not find the Texture (ID = " + tex_id + " ( for this TextureProjector!");
  883. var textureProjector:TextureProjector = new TextureProjector(returnedArrayGeometry[1]);
  884. textureProjector.name = name;
  885. textureProjector.aspectRatio = _newBlockBytes.readFloat();
  886. textureProjector.fieldOfView = _newBlockBytes.readFloat();
  887. textureProjector.transform = mtx;
  888. var props:AWDProperties = parseProperties({1:_matrixNrType, 2:_matrixNrType, 3:_matrixNrType, 4:UINT8});
  889. textureProjector.pivotPoint = new Vector3D(props.get(1, 0), props.get(2, 0), props.get(3, 0));
  890. textureProjector.extra = parseUserAttributes();
  891. finalizeAsset(textureProjector, name);
  892. _blocks[blockID].data = textureProjector
  893. if (_debug)
  894. trace("Parsed a TextureProjector: Name = '" + name + "' | Texture-Name = " + Texture2DBase(returnedArrayGeometry[1]).name + " | Parent-Name = " + parentName);
  895. }
  896. //Block ID = 51
  897. private function parseLightPicker(blockID:uint):void
  898. {
  899. var name:String = parseVarStr();
  900. var numLights:uint = _newBlockBytes.readUnsignedShort();
  901. var lightsArray:Array = new Array();
  902. var k:int = 0;
  903. var lightID:int = 0;
  904. var returnedArrayLight:Array;
  905. var lightsArrayNames:Array = new Array();
  906. for (k = 0; k < numLights; k++) {
  907. lightID = _newBlockBytes.readUnsignedInt();
  908. returnedArrayLight = getAssetByID(lightID, [AssetType.LIGHT])
  909. if (returnedArrayLight[0]) {
  910. lightsArray.push(returnedArrayLight[1] as LightBase);
  911. lightsArrayNames.push(LightBase(returnedArrayLight[1]).name);
  912. } else
  913. _blocks[blockID].addError("Could not find a Light Nr " + k + " (ID = " + lightID + " ) for this LightPicker");
  914. }
  915. if (lightsArray.length == 0) {
  916. _blocks[blockID].addError("Could not create this LightPicker, cause no Light was found.");
  917. parseUserAttributes();
  918. return; //return without any more parsing for this block
  919. }
  920. var lightPick:LightPickerBase = new StaticLightPicker(lightsArray);
  921. lightPick.name = name;
  922. parseUserAttributes();
  923. finalizeAsset(lightPick, name);
  924. _blocks[blockID].data = lightPick
  925. if (_debug)
  926. trace("Parsed a StaticLightPicker: Name = '" + name + "' | Texture-Name = " + lightsArrayNames.toString());
  927. }
  928. //Block ID = 81
  929. private function parseMaterial(blockID:uint):void
  930. {
  931. // TODO: not used
  932. ////blockLength = block.len;
  933. var name:String;
  934. var type:uint;
  935. var props:AWDProperties;
  936. var mat:MaterialBase;
  937. var attributes:Object;
  938. var finalize:Boolean;
  939. var num_methods:uint;
  940. var methods_parsed:uint;
  941. var returnedArray:Array;
  942. name = parseVarStr();
  943. type = _newBlockBytes.readUnsignedByte();
  944. num_methods = _newBlockBytes.readUnsignedByte();
  945. // Read material numerical properties
  946. // (1=color, 2=bitmap url, 10=alpha, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
  947. props = parseProperties({1:INT32, 2:BADDR, 10:_propsNrType, 11:BOOL, 12:_propsNrType, 13:BOOL});
  948. methods_parsed = 0;
  949. while (methods_parsed < num_methods) {
  950. var method_type:uint;
  951. method_type = _newBlockBytes.readUnsignedShort();
  952. parseProperties(null);
  953. parseUserAttributes();
  954. methods_parsed += 1;
  955. }
  956. var debugString:String = "";
  957. attributes = parseUserAttributes();
  958. if (type == 1) { // Color material
  959. debugString += "Parsed a ColorMaterial(SinglePass): Name = '" + name + "' | ";
  960. var color:uint;
  961. color = props.get(1, 0xcccccc);
  962. if (materialMode < 2)
  963. mat = new ColorMaterial(color, props.get(10, 1.0));
  964. else
  965. mat = new ColorMultiPassMaterial(color);
  966. } else if (type == 2) {
  967. var tex_addr:uint = props.get(2, 0);
  968. returnedArray = getAssetByID(tex_addr, [AssetType.TEXTURE])
  969. if ((!returnedArray[0]) && (tex_addr > 0))
  970. _blocks[blockID].addError("Could not find the DiffsueTexture (ID = " + tex_addr + " ) for this Material");
  971. if (materialMode < 2) {
  972. mat = new TextureMaterial(returnedArray[1]);
  973. TextureMaterial(mat).alphaBlending = props.get(11, false);
  974. TextureMaterial(mat).alpha = props.get(10, 1.0);
  975. debugString += "Parsed a TextureMaterial(SinglePass): Name = '" + name + "' | Texture-Name = " + mat.name;
  976. } else {
  977. mat = new TextureMultiPassMaterial(returnedArray[1]);
  978. debugString += "Parsed a TextureMaterial(MultipAss): Name = '" + name + "' | Texture-Name = " + mat.name;
  979. }
  980. }
  981. mat.extra = attributes;
  982. if (materialMode < 2)
  983. SinglePassMaterialBase(mat).alphaThreshold = props.get(12, 0.0);
  984. else
  985. MultiPassMaterialBase(mat).alphaThreshold = props.get(12, 0.0);
  986. mat.repeat = props.get(13, false);
  987. finalizeAsset(mat, name);
  988. _blocks[blockID].data = mat;
  989. if (_debug)
  990. trace(debugString);
  991. }
  992. // Block ID = 81 AWD2.1
  993. private function parseMaterial_v1(blockID:uint):void
  994. {
  995. var mat:MaterialBase;
  996. var normalTexture:Texture2DBase;
  997. var specTexture:Texture2DBase;
  998. var returnedArray:Array;
  999. var name:String = parseVarStr();
  1000. var type:uint = _newBlockBytes.readUnsignedByte();
  1001. var num_methods:uint = _newBlockBytes.readUnsignedByte();
  1002. var props:AWDProperties = parseProperties({1:UINT32, 2:BADDR, 3:BADDR, 4:UINT8, 5:BOOL, 6:BOOL, 7:BOOL, 8:BOOL, 9:UINT8, 10:_propsNrType, 11:BOOL, 12:_propsNrType, 13:BOOL, 15:_propsNrType, 16:UINT32, 17:BADDR, 18:_propsNrType, 19:_propsNrType, 20:UINT32, 21:BADDR, 22:BADDR});
  1003. var spezialType:uint = props.get(4, 0);
  1004. var debugString:String = "";
  1005. if (spezialType >= 2) { //this is no supported material
  1006. _blocks[blockID].addError("Material-spezialType '" + spezialType + "' is not supported, can only be 0:singlePass, 1:MultiPass !");
  1007. return;
  1008. }
  1009. if (materialMode == 1)
  1010. spezialType = 0;
  1011. else if (materialMode == 2)
  1012. spezialType = 1;
  1013. if (spezialType < 2) { //this is SinglePass or MultiPass
  1014. if (type == 1) { // Color material
  1015. var color:uint = color = props.get(1, 0xcccccc);
  1016. if (spezialType == 1) { // MultiPassMaterial
  1017. mat = new ColorMultiPassMaterial(color);
  1018. debugString += "Parsed a ColorMaterial(MultiPass): Name = '" + name + "' | ";
  1019. } else { // SinglePassMaterial
  1020. mat = new ColorMaterial(color, props.get(10, 1.0));
  1021. ColorMaterial(mat).alphaBlending = props.get(11, false);
  1022. debugString += "Parsed a ColorMaterial(SinglePass): Name = '" + name + "' | ";
  1023. }
  1024. } else if (type == 2) { // texture material
  1025. var tex_addr:uint = props.get(2, 0);
  1026. returnedArray = getAssetByID(tex_addr, [AssetType.TEXTURE])
  1027. if ((!returnedArray[0]) && (tex_addr > 0))
  1028. _blocks[blockID].addError("Could not find the DiffsueTexture (ID = " + tex_addr + " ) for this TextureMaterial");
  1029. var texture:Texture2DBase = returnedArray[1];
  1030. var ambientTexture:Texture2DBase;
  1031. var ambientTex_addr:uint = props.get(17, 0);
  1032. returnedArray = getAssetByID(ambientTex_addr, [AssetType.TEXTURE])
  1033. if ((!returnedArray[0]) && (ambientTex_addr != 0))
  1034. _blocks[blockID].addError("Could not find the AmbientTexture (ID = " + ambientTex_addr + " ) for this TextureMaterial");
  1035. if (returnedArray[0])
  1036. ambientTexture = returnedArray[1]
  1037. if (spezialType == 1) { // MultiPassMaterial
  1038. mat = new TextureMultiPassMaterial(texture);
  1039. debugString += "Parsed a TextureMaterial(MultiPass): Name = '" + name + "' | Texture-Name = " + texture.name;
  1040. if (ambientTexture) {
  1041. TextureMultiPassMaterial(mat).ambientTexture = ambientTexture;
  1042. debugString += " | AmbientTexture-Name = " + ambientTexture.name;
  1043. }
  1044. } else { // SinglePassMaterial
  1045. mat = new TextureMaterial(texture);
  1046. debugString += "Parsed a TextureMaterial(SinglePass): Name = '" + name + "' | Texture-Name = " + texture.name;
  1047. if (ambientTexture) {
  1048. TextureMaterial(mat).ambientTexture = ambientTexture;
  1049. debugString += " | AmbientTexture-Name = " + ambientTexture.name;
  1050. }
  1051. TextureMaterial(mat).alpha = props.get(10, 1.0);
  1052. TextureMaterial(mat).alphaBlending = props.get(11, false);
  1053. }
  1054. }
  1055. var normalTex_addr:uint = props.get(3, 0);
  1056. returnedArray = getAssetByID(normalTex_addr, [AssetType.TEXTURE])
  1057. if ((!returnedArray[0]) && (normalTex_addr != 0))
  1058. _blocks[blockID].addError("Could not find the NormalTexture (ID = " + normalTex_addr + " ) for this TextureMaterial");
  1059. if (returnedArray[0]) {
  1060. normalTexture = returnedArray[1];
  1061. debugString += " | NormalTexture-Name = " + normalTexture.name;
  1062. }
  1063. var specTex_addr:uint = props.get(21, 0);
  1064. returnedArray = getAssetByID(specTex_addr, [AssetType.TEXTURE])
  1065. if ((!returnedArray[0]) && (specTex_addr != 0))
  1066. _blocks[blockID].addError("Could not find the SpecularTexture (ID = " + specTex_addr + " ) for this TextureMaterial");
  1067. if (returnedArray[0]) {
  1068. specTexture = returnedArray[1];
  1069. debugString += " | SpecularTexture-Name = " + specTexture.name;
  1070. }
  1071. var lightPickerAddr:uint = props.get(22, 0);
  1072. returnedArray = getAssetByID(lightPickerAddr, [AssetType.LIGHT_PICKER])
  1073. if ((!returnedArray[0]) && (lightPickerAddr))
  1074. _blocks[blockID].addError("Could not find the LightPicker (ID = " + lightPickerAddr + " ) for this TextureMaterial");
  1075. else {
  1076. MaterialBase(mat).lightPicker = returnedArray[1] as LightPickerBase;
  1077. //debugString+=" | Lightpicker-Name = "+LightPickerBase(returnedArray[1]).name;
  1078. }
  1079. MaterialBase(mat).smooth = props.get(5, true);
  1080. MaterialBase(mat).mipmap = props.get(6, true);
  1081. MaterialBase(mat).bothSides = props.get(7, false);
  1082. MaterialBase(mat).alphaPremultiplied = props.get(8, false);
  1083. MaterialBase(mat).blendMode = blendModeDic[props.get(9, 0)];
  1084. MaterialBase(mat).repeat = props.get(13, false);
  1085. if (spezialType == 0) { // this is a SinglePassMaterial
  1086. if (normalTexture)
  1087. SinglePassMaterialBase(mat).normalMap = normalTexture;
  1088. if (specTexture)
  1089. SinglePassMaterialBase(mat).specularMap = specTexture;
  1090. SinglePassMaterialBase(mat).alphaThreshold = props.get(12, 0.0);
  1091. SinglePassMaterialBase(mat).ambient = props.get(15, 1.0);
  1092. SinglePassMaterialBase(mat).ambientColor = props.get(16, 0xffffff);
  1093. SinglePassMaterialBase(mat).specular = props.get(18, 1.0);
  1094. SinglePassMaterialBase(mat).gloss = props.get(19, 50);
  1095. SinglePassMaterialBase(mat).specularColor = props.get(20, 0xffffff);
  1096. }
  1097. else { // this is MultiPassMaterial
  1098. if (normalTexture)
  1099. MultiPassMaterialBase(mat).normalMap = normalTexture;
  1100. if (specTexture)
  1101. MultiPassMaterialBase(mat).specularMap = specTexture;
  1102. MultiPassMaterialBase(mat).alphaThreshold = props.get(12, 0.0);
  1103. MultiPassMaterialBase(mat).ambient = props.get(15, 1.0);
  1104. MultiPassMaterialBase(mat).ambientColor = props.get(16, 0xffffff);
  1105. MultiPassMaterialBase(mat).specular = props.get(18, 1.0);
  1106. MultiPassMaterialBase(mat).gloss = props.get(19, 50);
  1107. MultiPassMaterialBase(mat).specularColor = props.get(20, 0xffffff);
  1108. }
  1109. var methods_parsed:uint = 0;
  1110. var targetID:uint;
  1111. while (methods_parsed < num_methods) {
  1112. var method_type:uint;
  1113. method_type = _newBlockBytes.readUnsignedShort();
  1114. props = parseProperties({1:BADDR, 2:BADDR, 3:BADDR, 101:_propsNrType, 102:_propsNrType, 103:_propsNrType, 201:UINT32, 202:UINT32, 301:UINT16, 302:UINT16, 401:UINT8, 402:UINT8, 601:COLOR, 602:COLOR, 701:BOOL, 702:BOOL, 801:MTX4x4});
  1115. switch (method_type) {
  1116. case 999: //wrapper-Methods that will load a previous parsed EffektMethod returned
  1117. targetID = props.get(1, 0);
  1118. returnedArray = getAssetByID(targetID, [AssetType.EFFECTS_METHOD]);
  1119. if (!returnedArray[0])
  1120. _blocks[blockID].addError("Could not find the EffectMethod (ID = " + targetID + " ) for this Material");
  1121. else {
  1122. if (spezialType == 0)
  1123. SinglePassMaterialBase(mat).addMethod(returnedArray[1]);
  1124. if (spezialType == 1)
  1125. MultiPassMaterialBase(mat).addMethod(returnedArray[1]);
  1126. debugString += " | EffectMethod-Name = " + EffectMethodBase(returnedArray[1]).name;
  1127. }
  1128. break;
  1129. case 998: //wrapper-Methods that will load a previous parsed ShadowMapMethod
  1130. targetID = props.get(1, 0);
  1131. returnedArray = getAssetByID(targetID, [AssetType.SHADOW_MAP_METHOD]);
  1132. if (!returnedArray[0])
  1133. _blocks[blockID].addError("Could not find the ShadowMethod (ID = " + targetID + " ) for this Material");
  1134. else {
  1135. if (spezialType == 0)
  1136. SinglePassMaterialBase(mat).shadowMethod = returnedArray[1];
  1137. if (spezialType == 1)
  1138. MultiPassMaterialBase(mat).shadowMethod = returnedArray[1];
  1139. debugString += " | ShadowMethod-Name = " + ShadowMapMethodBase(returnedArray[1]).name;
  1140. }
  1141. break;
  1142. case 1: //EnvMapAmbientMethod
  1143. targetID = props.get(1, 0);
  1144. returnedArray = getAssetByID(targetID, [AssetType.TEXTURE], "CubeTexture");
  1145. if (!returnedArray[0])
  1146. _blocks[blockID].addError("Could not find the EnvMap (ID = " + targetID + " ) for this EnvMapAmbientMethodMaterial");
  1147. if (spezialType == 0)
  1148. SinglePassMaterialBase(mat).ambientMethod = new EnvMapAmbientMethod(returnedArray[1]);
  1149. if (spezialType == 1)
  1150. MultiPassMaterialBase(mat).ambientMethod = new EnvMapAmbientMethod(returnedArray[1]);
  1151. debugString += " | EnvMapAmbientMethod | EnvMap-Name =" + CubeTextureBase(returnedArray[1]).name;
  1152. break;
  1153. case 51: //DepthDiffuseMethod
  1154. if (spezialType == 0)
  1155. SinglePassMaterialBase(mat).diffuseMethod = new DepthDiffuseMethod();
  1156. if (spezialType == 1)
  1157. MultiPassMaterialBase(mat).diffuseMethod = new DepthDiffuseMethod();
  1158. debugString += " | DepthDiffuseMethod";
  1159. break;
  1160. case 52: //GradientDiffuseMethod
  1161. targetID = props.get(1, 0);
  1162. returnedArray = getAssetByID(targetID, [AssetType.TEXTURE]);
  1163. if (!returnedArray[0])
  1164. _blocks[blockID].addError("Could not find the GradientDiffuseTexture (ID = " + targetID + " ) for this GradientDiffuseMethod");
  1165. if (spezialType == 0)
  1166. SinglePassMaterialBase(mat).diffuseMethod = new GradientDiffuseMethod(returnedArray[1]);
  1167. if (spezialType == 1)
  1168. MultiPassMaterialBase(mat).diffuseMethod = new GradientDiffuseMethod(returnedArray[1]);
  1169. debugString += " | GradientDiffuseMethod | GradientDiffuseTexture-Name =" + Texture2DBase(returnedArray[1]).name;
  1170. break;
  1171. case 53: //WrapDiffuseMethod
  1172. if (spezialType == 0)
  1173. SinglePassMaterialBase(mat).diffuseMethod = new WrapDiffuseMethod(props.get(101, 5));
  1174. if (spezialType == 1)
  1175. MultiPassMaterialBase(mat).diffuseMethod = new WrapDiffuseMethod(props.get(101, 5));
  1176. debugString += " | WrapDiffuseMethod";
  1177. break;
  1178. case 54: //LightMapDiffuseMethod
  1179. targetID = props.get(1, 0);
  1180. returnedArray = getAssetByID(targetID, [AssetType.TEXTURE]);
  1181. if (!returnedArray[0])
  1182. _blocks[blockID].addError("Could not find the LightMap (ID = " + targetID + " ) for this LightMapDiffuseMethod");
  1183. if (spezialType == 0)
  1184. SinglePassMaterialBase(mat).diffuseMethod = new LightMapDiffuseMethod(returnedArray[1], blendModeDic[props.get(401, 10)], false,