mirror of
				https://github.com/MapMakersAndProgrammers/alternativa3d-archive.git
				synced 2025-10-31 01:06:16 -07:00 
			
		
		
		
	more versions added
This commit is contained in:
		| @@ -0,0 +1,35 @@ | ||||
| K 25 | ||||
| svn:wc:ra_dav:version-url | ||||
| V 99 | ||||
| /!svn/ver/497/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders | ||||
| END | ||||
| Loader3DS.as | ||||
| K 25 | ||||
| svn:wc:ra_dav:version-url | ||||
| V 112 | ||||
| /!svn/ver/497/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders/Loader3DS.as | ||||
| END | ||||
| LoaderOBJ.as | ||||
| K 25 | ||||
| svn:wc:ra_dav:version-url | ||||
| V 112 | ||||
| /!svn/ver/497/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders/LoaderOBJ.as | ||||
| END | ||||
| LoaderMTL.as | ||||
| K 25 | ||||
| svn:wc:ra_dav:version-url | ||||
| V 112 | ||||
| /!svn/ver/497/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders/LoaderMTL.as | ||||
| END | ||||
| MTLTextureMapInfo.as | ||||
| K 25 | ||||
| svn:wc:ra_dav:version-url | ||||
| V 120 | ||||
| /!svn/ver/497/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders/MTLTextureMapInfo.as | ||||
| END | ||||
| MaterialInfo.as | ||||
| K 25 | ||||
| svn:wc:ra_dav:version-url | ||||
| V 115 | ||||
| /!svn/ver/497/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders/MaterialInfo.as | ||||
| END | ||||
| @@ -0,0 +1,88 @@ | ||||
| 8 | ||||
|  | ||||
| dir | ||||
| 46043 | ||||
| http://svndev.alternativaplatform.com/platform/clients/fp10/libraries/Alternativa3D/tags/5.4.1/alternativa/engine3d/loaders | ||||
| http://svndev.alternativaplatform.com | ||||
|  | ||||
|  | ||||
|  | ||||
| 2008-09-08T06:50:26.103978Z | ||||
| 468 | ||||
| mike | ||||
|  | ||||
|  | ||||
| svn:special svn:externals svn:needs-lock | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| d9e2387a-1f3e-40e2-b57f-9df5970a2fa5 | ||||
|  | ||||
| Loader3DS.as | ||||
| file | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 2010-10-28T04:31:16.000000Z | ||||
| 00968101ff4527373d553d422e7330fb | ||||
| 2008-09-08T06:50:26.103978Z | ||||
| 468 | ||||
| mike | ||||
|  | ||||
| LoaderOBJ.as | ||||
| file | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 2010-10-28T04:31:16.000000Z | ||||
| fbea6bb68b725694c17d00505a0095e6 | ||||
| 2008-09-08T06:50:26.103978Z | ||||
| 468 | ||||
| mike | ||||
|  | ||||
| LoaderMTL.as | ||||
| file | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 2010-10-28T04:31:16.000000Z | ||||
| 8323b7d5fbc1556a49d9fd6d8af752c1 | ||||
| 2008-09-08T06:50:26.103978Z | ||||
| 468 | ||||
| mike | ||||
|  | ||||
| MTLTextureMapInfo.as | ||||
| file | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 2010-10-28T04:31:16.000000Z | ||||
| 42806a924c6d67153cb53141ba5e2737 | ||||
| 2008-08-25T13:44:47.077292Z | ||||
| 176 | ||||
| int | ||||
|  | ||||
| MaterialInfo.as | ||||
| file | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 2010-10-28T04:31:16.000000Z | ||||
| 8010397834f3e9cd80b825cbbf4983ec | ||||
| 2008-08-25T13:44:47.077292Z | ||||
| 176 | ||||
| int | ||||
|  | ||||
| @@ -0,0 +1 @@ | ||||
| 8 | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,285 @@ | ||||
| package alternativa.engine3d.loaders { | ||||
| 	import alternativa.engine3d.*; | ||||
| 	import alternativa.types.Map; | ||||
| 	import alternativa.utils.ColorUtils; | ||||
| 	 | ||||
| 	import flash.display.Bitmap; | ||||
| 	import flash.display.BitmapData; | ||||
| 	import flash.display.Loader; | ||||
| 	import flash.events.ErrorEvent; | ||||
| 	import flash.events.Event; | ||||
| 	import flash.events.EventDispatcher; | ||||
| 	import flash.events.IOErrorEvent; | ||||
| 	import flash.events.SecurityErrorEvent; | ||||
| 	import flash.geom.Point; | ||||
| 	import flash.net.URLLoader; | ||||
| 	import flash.net.URLRequest; | ||||
| 	import flash.system.LoaderContext; | ||||
| 	 | ||||
| 	use namespace alternativa3d; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @private | ||||
| 	 * Загрузчик библиотеки материалов из файлов в формате MTL material format (Lightwave, OBJ). | ||||
| 	 * <p> | ||||
| 	 * На данный момент обеспечивается загрузка цвета, прозрачности и диффузной текстуры материала. | ||||
| 	 */ | ||||
| 	internal class LoaderMTL extends EventDispatcher { | ||||
| 		 | ||||
| 		private static const COMMENT_CHAR:String = "#"; | ||||
| 		private static const CMD_NEW_MATERIAL:String = "newmtl"; | ||||
| 		private static const CMD_DIFFUSE_REFLECTIVITY:String = "Kd"; | ||||
| 		private static const CMD_DISSOLVE:String = "d"; | ||||
| 		private static const CMD_MAP_DIFFUSE:String = "map_Kd"; | ||||
| 		 | ||||
| 		private static const REGEXP_TRIM:RegExp = /^\s*(.*?)\s*$/; | ||||
| 		private static const REGEXP_SPLIT_FILE:RegExp = /\r*\n/; | ||||
| 		private static const REGEXP_SPLIT_LINE:RegExp = /\s+/; | ||||
| 		 | ||||
| 		// Загрузчик файла MTL | ||||
| 		private var fileLoader:URLLoader; | ||||
| 		// Загрузчик файлов текстур | ||||
| 		private var bitmapLoader:Loader; | ||||
| 		// Контекст загрузки для bitmapLoader | ||||
| 		private var loaderContext:LoaderContext; | ||||
| 		// Базовый URL файла MTL | ||||
| 		private var baseUrl:String; | ||||
|  | ||||
| 		// Библиотека загруженных материалов | ||||
| 		private var _library:Map; | ||||
| 		// Список материалов, имеющих диффузные текстуры | ||||
| 		private var diffuseMaps:Map; | ||||
| 		// Имя текущего материала | ||||
| 		private var materialName:String; | ||||
| 		// параметры текущего материала | ||||
| 		private var currentMaterialInfo:MaterialInfo = new MaterialInfo(); | ||||
| 		 | ||||
| 		alternativa3d static var stubBitmapData:BitmapData; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Создаёт новый экземпляр класса. | ||||
| 		 */ | ||||
| 		public function LoaderMTL() { | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Прекращение текущей загрузки. | ||||
| 		 */ | ||||
| 		public function close():void { | ||||
| 			try { | ||||
| 				fileLoader.close(); | ||||
| 			} catch (e:Error) { | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Библиотека материалов. Ключами являются наименования материалов, значениями -- объекты, наследники класса | ||||
| 		 * <code>alternativa.engine3d.loaders.MaterialInfo</code>. | ||||
| 		 * @see alternativa.engine3d.loaders.MaterialInfo | ||||
| 		 */ | ||||
| 		public function get library():Map { | ||||
| 			return _library; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Метод выполняет загрузку файла материалов, разбор его содержимого, загрузку текстур при необходимости и | ||||
| 		 * формирование библиотеки материалов. После окончания работы метода посылается сообщение | ||||
| 		 * <code>Event.COMPLETE</code> и становится доступна библиотека материалов через свойство <code>library</code>. | ||||
| 		 * <p> | ||||
| 		 * При возникновении ошибок, связанных с вводом-выводом или с безопасностью, посылаются сообщения <code>IOErrorEvent.IO_ERROR</code> и  | ||||
| 		 * <code>SecurityErrorEvent.SECURITY_ERROR</code> соответственно. | ||||
| 		 * <p> | ||||
| 		 * Если происходит ошибка при загрузке файла текстуры, то соответствующая текстура заменяется на текстуру-заглушку. | ||||
| 		 * <p> | ||||
| 		 * @param url URL MTL-файла | ||||
| 		 * @param loaderContext LoaderContext для загрузки файлов текстур | ||||
| 		 *   | ||||
| 		 * @see #library | ||||
| 		 */ | ||||
| 		public function load(url:String, loaderContext:LoaderContext = null):void { | ||||
| 			this.loaderContext = loaderContext; | ||||
| 			baseUrl = url.substring(0, url.lastIndexOf("/") + 1); | ||||
|  | ||||
| 			if (fileLoader == null) { | ||||
| 				fileLoader = new URLLoader(); | ||||
| 				fileLoader.addEventListener(Event.COMPLETE, parseMTLFile); | ||||
| 				fileLoader.addEventListener(IOErrorEvent.IO_ERROR, onError); | ||||
| 				fileLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError); | ||||
|  | ||||
| 				bitmapLoader = new Loader(); | ||||
| 				bitmapLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBitmapLoadComplete); | ||||
| 				bitmapLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onBitmapLoadComplete); | ||||
| 				bitmapLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onBitmapLoadComplete); | ||||
| 			} | ||||
| 			 | ||||
| 			try { | ||||
| 				fileLoader.close(); | ||||
| 				bitmapLoader.close(); | ||||
| 			} catch (e:Error) { | ||||
| 				// Пропуск ошибки при попытке закрытия неактивных загрузчиков | ||||
| 			} | ||||
| 			 | ||||
| 			fileLoader.load(new URLRequest(url)); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Разбор содержимого загруженного файла материалов. | ||||
| 		 */ | ||||
| 		private function parseMTLFile(e:Event = null):void { | ||||
| 			var lines:Array = fileLoader.data.split(REGEXP_SPLIT_FILE); | ||||
| 			_library = new Map(); | ||||
| 			diffuseMaps = new Map(); | ||||
| 			for each (var line:String in lines) { | ||||
| 				parseLine(line); | ||||
| 			} | ||||
| 			defineMaterial(); | ||||
| 			 | ||||
| 			if (diffuseMaps.isEmpty()) { | ||||
| 				// Текстур нет, загрузка окончена | ||||
| 				dispatchEvent(new Event(Event.COMPLETE)); | ||||
| 			} else { | ||||
| 				// Загрузка файлов текстур | ||||
| 				loadNextBitmap(); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Разбор строки файла. | ||||
| 		 *  | ||||
| 		 * @param line строка файла | ||||
| 		 */ | ||||
| 		private	function parseLine(line:String):void { | ||||
| 			line = line.replace(REGEXP_TRIM,"$1") | ||||
| 			if (line.length == 0 || line.charAt(0) == COMMENT_CHAR) { | ||||
| 				return; | ||||
| 			} | ||||
| 			var parts:Array = line.split(REGEXP_SPLIT_LINE); | ||||
| 			switch (parts[0]) { | ||||
| 				case CMD_NEW_MATERIAL: | ||||
| 					defineMaterial(parts); | ||||
| 					break; | ||||
| 				case CMD_DIFFUSE_REFLECTIVITY: | ||||
| 					readDiffuseReflectivity(parts); | ||||
| 					break; | ||||
| 				case CMD_DISSOLVE: | ||||
| 					readAlpha(parts); | ||||
| 					break; | ||||
| 				case CMD_MAP_DIFFUSE: | ||||
| 					parseDiffuseMapLine(parts); | ||||
| 					break; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Определение нового материала. | ||||
| 		 */		 | ||||
| 		private function defineMaterial(parts:Array = null):void { | ||||
| 			if (materialName != null) { | ||||
| 				_library[materialName] = currentMaterialInfo; | ||||
| 			} | ||||
| 			if (parts != null) { | ||||
| 				materialName = parts[1]; | ||||
| 				currentMaterialInfo = new MaterialInfo(); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Чтение коэффициентов диффузного отражения. Считываются только коэффициенты, заданные в формате r g b. Для текущей | ||||
| 		 * версии движка данные коэффициенты преобразуются в цвет материала. | ||||
| 		 */ | ||||
| 		private function readDiffuseReflectivity(parts:Array):void { | ||||
| 			var r:Number = Number(parts[1]); | ||||
| 			// Проверка, заданы ли коэффициенты в виде r g b | ||||
| 			if (!isNaN(r)) { | ||||
| 				var g:Number = Number(parts[2]); | ||||
| 				var b:Number = Number(parts[3]); | ||||
| 				currentMaterialInfo.color = ColorUtils.rgb(255 * r, 255 * g, 255 * b);  | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 * Чтение коэффициента непрозрачности. Считывается только коэффициент, заданный числом | ||||
| 		 * (не поддерживается параметр -halo). | ||||
| 		 */ | ||||
| 		private function readAlpha(parts:Array):void { | ||||
| 			var alpha:Number = Number(parts[1]); | ||||
| 			if (!isNaN(alpha)) { | ||||
| 				currentMaterialInfo.alpha = alpha; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Разбор строки, задающей текстурную карту для диффузного отражения. | ||||
| 		 */ | ||||
| 		private function parseDiffuseMapLine(parts:Array):void { | ||||
| 			var info:MTLTextureMapInfo = MTLTextureMapInfo.parse(parts); | ||||
| 			diffuseMaps[materialName] = info; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Загрузка файла следующей текстуры. | ||||
| 		 */ | ||||
| 		private function loadNextBitmap():void { | ||||
| 			// Установка имени текущего текстурного материала, для которого выполняется загрузка текстуры | ||||
| 			for (materialName in diffuseMaps) { | ||||
| 				break; | ||||
| 			} | ||||
| 			bitmapLoader.load(new URLRequest(baseUrl + diffuseMaps[materialName].fileName), loaderContext); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 */ | ||||
| 		private function createStubBitmap():void { | ||||
| 			if (stubBitmapData == null) { | ||||
| 				var size:uint = 10; | ||||
| 				stubBitmapData = new BitmapData(size, size, false, 0); | ||||
| 				for (var i:uint = 0; i < size; i++) { | ||||
| 					for (var j:uint = 0; j < size; j+=2) { | ||||
| 						stubBitmapData.setPixel((i % 2) ? j : (j+1), i, 0xFF00FF); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Обработка результата загрузки файла текстуры. | ||||
| 		 */ | ||||
| 		private function onBitmapLoadComplete(e:Event):void { | ||||
| 			var bmd:BitmapData; | ||||
| 			 | ||||
| 			if (e is ErrorEvent) { | ||||
| 				if (stubBitmapData == null) { | ||||
| 					createStubBitmap(); | ||||
| 				} | ||||
| 				bmd = stubBitmapData; | ||||
| 			} else { | ||||
| 				bmd = Bitmap(bitmapLoader.content).bitmapData; | ||||
| 			} | ||||
| 			 | ||||
| 			var mtlInfo:MTLTextureMapInfo = diffuseMaps[materialName]; | ||||
| 			delete diffuseMaps[materialName]; | ||||
| 			var info:MaterialInfo = _library[materialName]; | ||||
| 			 | ||||
| 			info.bitmapData = bmd; | ||||
| 			info.repeat = mtlInfo.repeat; | ||||
| 			info.mapOffset = new Point(mtlInfo.offsetU, mtlInfo.offsetV); | ||||
| 			info.mapSize = new Point(mtlInfo.sizeU, mtlInfo.sizeV); | ||||
| 			info.textureFileName = mtlInfo.fileName; | ||||
| 	 | ||||
| 			if (diffuseMaps.isEmpty()) { | ||||
| 				dispatchEvent(new Event(Event.COMPLETE)); | ||||
| 			} else { | ||||
| 				loadNextBitmap(); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @param e | ||||
| 		 */ | ||||
| 		private function onError(e:IOErrorEvent):void { | ||||
| 			dispatchEvent(e); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,509 @@ | ||||
| package alternativa.engine3d.loaders { | ||||
| 	import alternativa.engine3d.*; | ||||
| 	import alternativa.engine3d.core.Face; | ||||
| 	import alternativa.engine3d.core.Mesh; | ||||
| 	import alternativa.engine3d.core.Object3D; | ||||
| 	import alternativa.engine3d.core.Surface; | ||||
| 	import alternativa.engine3d.core.Vertex; | ||||
| 	import alternativa.engine3d.materials.FillMaterial; | ||||
| 	import alternativa.engine3d.materials.TextureMaterial; | ||||
| 	import alternativa.engine3d.materials.TextureMaterialPrecision; | ||||
| 	import alternativa.types.Map; | ||||
| 	import alternativa.types.Point3D; | ||||
| 	import alternativa.types.Texture; | ||||
| 	 | ||||
| 	import flash.display.BlendMode; | ||||
| 	import flash.events.ErrorEvent; | ||||
| 	import flash.events.Event; | ||||
| 	import flash.events.EventDispatcher; | ||||
| 	import flash.events.IOErrorEvent; | ||||
| 	import flash.events.SecurityErrorEvent; | ||||
| 	import flash.geom.Point; | ||||
| 	import flash.net.URLLoader; | ||||
| 	import flash.net.URLRequest; | ||||
| 	import flash.system.LoaderContext; | ||||
| 	 | ||||
| 	use namespace alternativa3d; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Загрузчик моделей из файла в формате OBJ. Так как OBJ не поддерживает иерархию объектов, все загруженные | ||||
| 	 * модели помещаются в один контейнер <code>Object3D</code>. | ||||
| 	 * <p> | ||||
| 	 * Поддерживаюся следующие команды формата OBJ: | ||||
| 	 * <p> | ||||
| 	 * <table border="1" style="border-collapse: collapse"> | ||||
| 	 * <tr> | ||||
| 	 *   <th width="30%">Команда</th> | ||||
| 	 *   <th>Описание</th> | ||||
| 	 *   <th>Действие</th></tr> | ||||
| 	 * <tr> | ||||
| 	 *   <td>o object_name</td> | ||||
| 	 *   <td>Объявление нового объекта с именем object_name</td> | ||||
| 	 *   <td>Если для текущего объекта были определены грани, то команда создаёт новый текущий объект с указанным именем, | ||||
| 	 *       иначе у текущего объекта просто меняется имя на указанное.</td> | ||||
| 	 * </tr> | ||||
| 	 * <tr> | ||||
| 	 *   <td>v x y z</td> | ||||
| 	 *   <td>Объявление вершины с координатами x y z</td> | ||||
| 	 *   <td>Вершина помещается в общий список вершин сцены для дальнейшего использования</td> | ||||
| 	 * </tr> | ||||
| 	 * <tr> | ||||
| 	 *   <td>vt u [v]</td> | ||||
| 	 *   <td>Объявление текстурной вершины с координатами u v</td> | ||||
| 	 *   <td>Вершина помещается в общий список текстурных вершин сцены для дальнейшего использования</td> | ||||
| 	 * </tr> | ||||
| 	 * <tr> | ||||
| 	 *   <td>f v0[/vt0] v1[/vt1] ... vN[/vtN]</td> | ||||
| 	 *   <td>Объявление грани, состоящей из указанных вершин и опционально имеющую заданные текстурные координаты для вершин.</td> | ||||
| 	 *   <td>Грань добавляется к текущему активному объекту. Если есть активный материал, то грань также добавляется в поверхность | ||||
| 	 *       текущего объекта, соответствующую текущему материалу.</td> | ||||
| 	 * </tr> | ||||
| 	 * <tr> | ||||
| 	 *   <td>usemtl material_name</td> | ||||
| 	 *   <td>Установка текущего материала с именем material_name</td> | ||||
| 	 *   <td>С момента установки текущего материала все грани, создаваемые в текущем объекте будут помещаться в поверхность, | ||||
| 	 *       соотвествующую этому материалу и имеющую идентификатор, совпадающий с его именем.</td> | ||||
| 	 * </tr> | ||||
| 	 * <tr> | ||||
| 	 *   <td>mtllib file1 file2 ...</td> | ||||
| 	 *   <td>Объявление файлов, содержащих определения материалов</td> | ||||
| 	 *   <td>Выполняется загрузка файлов и формирование библиотеки материалов</td> | ||||
| 	 * </tr> | ||||
| 	 * </table> | ||||
| 	 *  | ||||
| 	 * <p> | ||||
| 	 * Пример использования: | ||||
| 	 * <pre> | ||||
| 	 * var loader:LoaderOBJ = new LoaderOBJ(); | ||||
| 	 * loader.addEventListener(Event.COMPLETE, onLoadingComplete); | ||||
| 	 * loader.load("foo.obj"); | ||||
| 	 *  | ||||
| 	 * function onLoadingComplete(e:Event):void { | ||||
| 	 *   scene.root.addChild(e.target.content); | ||||
| 	 * } | ||||
| 	 * </pre> | ||||
| 	 */ | ||||
| 	public class LoaderOBJ extends EventDispatcher { | ||||
| 		 | ||||
| 		private static const COMMENT_CHAR:String = "#"; | ||||
| 		 | ||||
| 		private static const CMD_OBJECT_NAME:String = "o"; | ||||
| 		private static const CMD_GROUP_NAME:String = "g"; | ||||
| 		private static const CMD_VERTEX:String = "v"; | ||||
| 		private static const CMD_TEXTURE_VERTEX:String = "vt"; | ||||
| 		private static const CMD_FACE:String = "f"; | ||||
| 		private static const CMD_MATERIAL_LIB:String = "mtllib"; | ||||
| 		private static const CMD_USE_MATERIAL:String = "usemtl"; | ||||
|  | ||||
| 		private static const REGEXP_TRIM:RegExp = /^\s*(.*?)\s*$/; | ||||
| 		private static const REGEXP_SPLIT_FILE:RegExp = /\r*\n/; | ||||
| 		private static const REGEXP_SPLIT_LINE:RegExp = /\s+/; | ||||
| 		 | ||||
| 		private var basePath:String; | ||||
| 		private var objLoader:URLLoader; | ||||
| 		private var mtlLoader:LoaderMTL; | ||||
| 		private var loaderContext:LoaderContext; | ||||
| 		private var loadMaterials:Boolean; | ||||
| 		// Объект, содержащий все определённые в obj файле объекты | ||||
| 		private var _content:Object3D; | ||||
| 		// Текущий конструируемый объект | ||||
| 		private var currentObject:Mesh; | ||||
| 		// Стартовый индекс вершины в глобальном массиве вершин для текущего объекта | ||||
| 		private var vIndexStart:int = 0; | ||||
| 		// Стартовый индекс текстурной вершины в глобальном массиве текстурных вершин для текущего объекта | ||||
| 		private var vtIndexStart:int = 0; | ||||
| 		// Глобальный массив вершин, определённых во входном файле | ||||
| 		private var globalVertices:Array; | ||||
| 		// Глобальный массив текстурных вершин, определённых во входном файле | ||||
| 		private var globalTextureVertices:Array; | ||||
| 		// Имя текущего активного материала. Если значение равно null, то активного материала нет.  | ||||
| 		private var currentMaterialName:String; | ||||
| 		// Массив граней текущего объекта, которым назначен текущий материал | ||||
| 		private var materialFaces:Array; | ||||
| 		// Массив имён файлов, содержащих определения материалов | ||||
| 		private var materialFileNames:Array; | ||||
| 		private var currentMaterialFileIndex:int; | ||||
| 		private var materialLibrary:Map; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Сглаживание текстур при увеличении масштаба. | ||||
| 		 *  | ||||
| 		 * @see alternativa.engine3d.materials.TextureMaterial | ||||
| 		 */		 | ||||
| 		public var smooth:Boolean = false; | ||||
| 		/** | ||||
| 		 * Режим наложения цвета для создаваемых текстурных материалов. | ||||
| 		 *  | ||||
| 		 * @see alternativa.engine3d.materials.TextureMaterial | ||||
| 		 */ | ||||
| 		public var blendMode:String = BlendMode.NORMAL; | ||||
| 		/** | ||||
| 		 * Точность перспективной коррекции для создаваемых текстурных материалов. | ||||
| 		 *  | ||||
| 		 * @see alternativa.engine3d.materials.TextureMaterial | ||||
| 		 */		 | ||||
| 		public var precision:Number = TextureMaterialPrecision.MEDIUM; | ||||
|  | ||||
| 		/** | ||||
| 		 * Устанавливаемый уровень мобильности загруженных объектов. | ||||
| 		 */		 | ||||
| 		public var mobility:int = 0; | ||||
|  | ||||
| 		/** | ||||
| 		 * При установленном значении <code>true</code> выполняется преобразование координат геометрических вершин посредством | ||||
| 		 * поворота на 90 градусов относительно оси X. Смысл флага в преобразовании системы координат, в которой вверх направлена | ||||
| 		 * ось <code>Y</code>, в систему координат, использующуюся в Alternativa3D (вверх направлена ось <code>Z</code>).  | ||||
| 		 */		 | ||||
| 		public var rotateModel:Boolean; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Создаёт новый экземпляр загрузчика. | ||||
| 		 */ | ||||
| 		public function LoaderOBJ() { | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Контейнер, содержащий все загруженные из OBJ-файла модели. | ||||
| 		 */ | ||||
| 		public function get content():Object3D { | ||||
| 			return _content; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Прекращение текущей загрузки. | ||||
| 		 */ | ||||
| 		public function close():void { | ||||
| 			try { | ||||
| 				objLoader.close(); | ||||
| 			} catch (e:Error) { | ||||
| 			} | ||||
| 			mtlLoader.close(); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Загрузка сцены из OBJ-файла по указанному адресу. По окончании загрузки посылается сообщение <code>Event.COMPLETE</code>, | ||||
| 		 * после чего контейнер с загруженными объектами становится доступным через свойство <code>content</code>. | ||||
| 		 * <p> | ||||
| 		 * При возникновении ошибок, связанных с вводом-выводом или с безопасностью, посылаются сообщения <code>IOErrorEvent.IO_ERROR</code> и  | ||||
| 		 * <code>SecurityErrorEvent.SECURITY_ERROR</code> соответственно. | ||||
| 		 * <p> | ||||
| 		 * @param url URL OBJ-файла  | ||||
| 		 * @param loadMaterials флаг загрузки материалов. Если указано значение <code>true</code>, будут обработаны все файлы | ||||
| 		 * 		материалов, указанные в исходном OBJ-файле. | ||||
| 		 * @param context LoaderContext для загрузки файлов текстур | ||||
| 		 *  | ||||
| 		 * @see #content | ||||
| 		 */ | ||||
| 		public function load(url:String, loadMaterials:Boolean = true, context:LoaderContext = null):void { | ||||
| 			_content = null; | ||||
| 			this.loadMaterials = loadMaterials; | ||||
| 			this.loaderContext = context; | ||||
| 			basePath = url.substring(0, url.lastIndexOf("/") + 1); | ||||
| 			if (objLoader == null) { | ||||
| 				objLoader = new URLLoader(); | ||||
| 				objLoader.addEventListener(Event.COMPLETE, onObjLoadComplete); | ||||
| 				objLoader.addEventListener(IOErrorEvent.IO_ERROR, onObjLoadError); | ||||
| 				objLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onObjLoadError); | ||||
| 			} else { | ||||
| 				close(); | ||||
| 			} | ||||
| 			objLoader.load(new URLRequest(url)); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Обработка окончания загрузки obj файла. | ||||
| 		 *  | ||||
| 		 * @param e | ||||
| 		 */ | ||||
| 		private function onObjLoadComplete(e:Event):void { | ||||
| 			parse(objLoader.data); | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 * Обработка ошибки при загрузке. | ||||
| 		 *  | ||||
| 		 * @param e | ||||
| 		 */ | ||||
| 		private function onObjLoadError(e:ErrorEvent):void { | ||||
| 			dispatchEvent(e); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Метод выполняет разбор данных, полученных из obj файла. | ||||
| 		 *  | ||||
| 		 * @param s содержимое obj файла  | ||||
| 		 * @param materialLibrary библиотека материалов | ||||
| 		 * @return объект, содержащий все трёхмерные объекты, определённые в obj файле | ||||
| 		 */ | ||||
| 		private function parse(data:String):void { | ||||
| 			_content = new Object3D(); | ||||
| 			currentObject = new Mesh(); | ||||
| 			currentObject.mobility = mobility; | ||||
| 			_content.addChild(currentObject); | ||||
| 			 | ||||
| 			globalVertices = new Array(); | ||||
| 			globalTextureVertices = new Array(); | ||||
| 			materialFileNames = new Array(); | ||||
| 			 | ||||
| 			var lines:Array = data.split(REGEXP_SPLIT_FILE); | ||||
| 			for each (var line:String in lines) { | ||||
| 				parseLine(line); | ||||
| 			} | ||||
| 			moveFacesToSurface(); | ||||
| 			// Вся геометрия загружена и сформирована. Выполняется загрузка информации о материалах. | ||||
| 			if (loadMaterials && materialFileNames.length > 0) { | ||||
| 				loadMaterialsLibrary(); | ||||
| 			} else { | ||||
| 				dispatchEvent(new Event(Event.COMPLETE)); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 */ | ||||
| 		private function parseLine(line:String):void { | ||||
| 			line = line.replace(REGEXP_TRIM,"$1"); | ||||
| 			if (line.length == 0 || line.charAt(0) == COMMENT_CHAR) { | ||||
| 				return; | ||||
| 			} | ||||
| 			var parts:Array = line.split(REGEXP_SPLIT_LINE); | ||||
| 			switch (parts[0]) { | ||||
| 				// Объявление нового объекта | ||||
| 				case CMD_OBJECT_NAME: | ||||
| 					defineObject(parts[1]); | ||||
| 					break; | ||||
| 				// Объявление вершины | ||||
| 				case CMD_VERTEX: | ||||
| 					globalVertices.push(new Point3D(Number(parts[1]), Number(parts[2]), Number(parts[3]))); | ||||
| 					break; | ||||
| 				// Объявление текстурной вершины | ||||
| 				case CMD_TEXTURE_VERTEX: | ||||
| 					globalTextureVertices.push(new Point3D(Number(parts[1]), Number(parts[2]), Number(parts[3]))); | ||||
| 					break; | ||||
| 				// Объявление грани | ||||
| 				case CMD_FACE: | ||||
| 					createFace(parts); | ||||
| 					break; | ||||
| 				case CMD_MATERIAL_LIB: | ||||
| 					storeMaterialFileNames(parts); | ||||
| 					break; | ||||
| 				case CMD_USE_MATERIAL: | ||||
| 					setNewMaterial(parts); | ||||
| 					break; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Объявление нового объекта. | ||||
| 		 *  | ||||
| 		 * @param objectName имя объекта | ||||
| 		 */ | ||||
| 		private function defineObject(objectName:String):void { | ||||
| 			if (currentObject.faces.length == 0) { | ||||
| 				// Если у текущего объекта нет граней, то он остаётся текущим, но меняется имя | ||||
| 				currentObject.name = objectName; | ||||
| 			} else { | ||||
| 				// Если у текущего объекта есть грани, то обявление нового имени создаёт новый объект | ||||
| 				moveFacesToSurface(); | ||||
| 				currentObject = new Mesh(objectName); | ||||
| 				currentObject.mobility = mobility; | ||||
| 				_content.addChild(currentObject); | ||||
| 			} | ||||
| 			vIndexStart = globalVertices.length; | ||||
| 			vtIndexStart = globalTextureVertices.length; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Создание грани в текущем объекте. | ||||
| 		 *  | ||||
| 		 * @param parts массив, содержащий индексы вершин грани, начиная с элемента с индексом 1  | ||||
| 		 */		 | ||||
| 		private function createFace(parts:Array):void { | ||||
| 			// Стартовый индекс вершины в объекте для добавляемой грани | ||||
| 			var startVertexIndex:int = currentObject.vertices.length; | ||||
| 			// Создание вершин в объекте | ||||
| 			var faceVertexCount:int = parts.length - 1; | ||||
| 			var vtIndices:Array = new Array(3); | ||||
| 			// Массив идентификаторов вершин грани | ||||
| 			var faceVertices:Array = new Array(faceVertexCount); | ||||
| 			for (var i:int = 0; i < faceVertexCount; i++) { | ||||
| 				var indices:Array = parts[i + 1].split("/"); | ||||
| 				// Создание вершины | ||||
| 				var vIdx:int = int(indices[0]); | ||||
| 				// Если индекс положительный, то его значение уменьшается на единицу, т.к. в obj формате индексация начинается с 1. | ||||
| 				// Если индекс отрицательный, то выполняется смещение на его значение назад от стартового глобального индекса вершин для текущего объекта. | ||||
| 				var actualIndex:int = vIdx > 0 ? vIdx - 1 : vIndexStart + vIdx; | ||||
| 				 | ||||
| 				var vertex:Vertex = currentObject.vertices[actualIndex]; | ||||
| 				// Если вершины нет в объекте, она добавляется | ||||
| 				if (vertex == null) { | ||||
| 					var p:Point3D = globalVertices[actualIndex]; | ||||
| 					if (rotateModel) { | ||||
| 						// В формате obj направление "вверх" совпадает с осью Y, поэтому выполняется поворот координат на 90 градусов по оси X  | ||||
| 						vertex = currentObject.createVertex(p.x, -p.z, p.y, actualIndex); | ||||
| 					} else { | ||||
| 						vertex = currentObject.createVertex(p.x, p.y, p.z, actualIndex); | ||||
| 					} | ||||
| 				} | ||||
| 				faceVertices[i] = vertex; | ||||
| 				 | ||||
| 				// Запись индекса текстурной вершины | ||||
| 				if (i < 3) { | ||||
| 					vtIndices[i] = int(indices[1]); | ||||
| 				} | ||||
| 			} | ||||
| 			// Создание грани | ||||
| 			var face:Face = currentObject.createFace(faceVertices, currentObject.faces.length); | ||||
| 			// Установка uv координат | ||||
| 			if (vtIndices[0] != 0) { | ||||
| 				p = globalTextureVertices[vtIndices[0] - 1]; | ||||
| 				face.aUV = new Point(p.x, p.y); | ||||
| 				p = globalTextureVertices[vtIndices[1] - 1]; | ||||
| 				face.bUV = new Point(p.x, p.y); | ||||
| 				p = globalTextureVertices[vtIndices[2] - 1]; | ||||
| 				face.cUV = new Point(p.x, p.y); | ||||
| 			} | ||||
| 			// Если есть активный материал, то грань заносится в массив для последующего формирования поверхности в объекте | ||||
| 			if (currentMaterialName != null) { | ||||
| 				materialFaces.push(face); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Загрузка библиотек материалов. | ||||
| 		 *  | ||||
| 		 * @param parts массив, содержащий имена файлов материалов, начиная с элемента с индексом 1 | ||||
| 		 */ | ||||
| 		private function storeMaterialFileNames(parts:Array):void { | ||||
| 			for (var i:int = 1; i < parts.length; i++) { | ||||
| 				materialFileNames.push(parts[i]); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 * Установка нового текущего материала. | ||||
| 		 *  | ||||
| 		 * @param parts массив, во втором элементе которого содержится имя материала | ||||
| 		 */ | ||||
| 		private function setNewMaterial(parts:Array):void { | ||||
| 			// Все сохранённые грани добавляются в соответствующую поверхность текущего объекта | ||||
| 			moveFacesToSurface(); | ||||
| 			// Установка нового текущего материала | ||||
| 			currentMaterialName = parts[1]; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Добавление всех граней с текущим материалом в поверхность с идентификатором, совпадающим с именем материала.  | ||||
| 		 */ | ||||
| 		private function moveFacesToSurface():void { | ||||
| 			if (currentMaterialName != null && materialFaces.length > 0) { | ||||
| 				if (currentObject.hasSurface(currentMaterialName)) { | ||||
| 					// При наличии поверхности с таким идентификатором, грани добавляются в неё | ||||
| 					var surface:Surface = currentObject.getSurfaceById(currentMaterialName); | ||||
| 					for each (var face:* in materialFaces) { | ||||
| 						surface.addFace(face); | ||||
| 					} | ||||
| 				} else { | ||||
| 					// При отсутствии поверхности с таким идентификатором, создатся новая поверхность | ||||
| 					currentObject.createSurface(materialFaces, currentMaterialName); | ||||
| 				} | ||||
| 			} | ||||
| 			materialFaces = []; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Загрузка материалов. | ||||
| 		 */ | ||||
| 		private function loadMaterialsLibrary():void { | ||||
| 			if (mtlLoader == null) { | ||||
| 				mtlLoader = new LoaderMTL(); | ||||
| 				mtlLoader.addEventListener(Event.COMPLETE, onMaterialFileLoadComplete); | ||||
| 				mtlLoader.addEventListener(IOErrorEvent.IO_ERROR, onObjLoadError); | ||||
| 				mtlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onObjLoadError); | ||||
| 			} | ||||
| 			materialLibrary = new Map(); | ||||
| 			 | ||||
| 			currentMaterialFileIndex = -1; | ||||
| 			loadNextMaterialFile(); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Обработка успешной загрузки библиотеки материалов. | ||||
| 		 */ | ||||
| 		private function onMaterialFileLoadComplete(e:Event):void { | ||||
| 			materialLibrary.concat(mtlLoader.library); | ||||
| 			// Загрузка следующего файла материалов | ||||
| 			loadNextMaterialFile(); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 */ | ||||
| 		private function loadNextMaterialFile():void { | ||||
| 			currentMaterialFileIndex++; | ||||
| 			if (currentMaterialFileIndex == materialFileNames.length) { | ||||
| 				setMaterials(); | ||||
| 				dispatchEvent(new Event(Event.COMPLETE)); | ||||
| 			} else { | ||||
| 				mtlLoader.load(basePath + materialFileNames[currentMaterialFileIndex], loaderContext); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Установка материалов. | ||||
| 		 */ | ||||
| 		private function setMaterials():void { | ||||
| 			if (materialLibrary != null) { | ||||
| 				for (var objectKey:* in _content.children) { | ||||
| 					var object:Mesh = objectKey; | ||||
| 					for (var surfaceKey:* in object.surfaces) { | ||||
| 						var surface:Surface = object.surfaces[surfaceKey]; | ||||
| 						// Поверхности имеют идентификаторы, соответствующие именам материалов | ||||
| 						var materialInfo:MaterialInfo = materialLibrary[surfaceKey]; | ||||
| 						if (materialInfo != null) { | ||||
| 							if (materialInfo.bitmapData == null) { | ||||
| 								surface.material = new FillMaterial(materialInfo.color, materialInfo.alpha, blendMode); | ||||
| 							} else { | ||||
| 								surface.material = new TextureMaterial(new Texture(materialInfo.bitmapData, materialInfo.textureFileName), materialInfo.alpha, materialInfo.repeat, (materialInfo.bitmapData != LoaderMTL.stubBitmapData) ? smooth : false, blendMode, -1, 0, precision); | ||||
| 								transformUVs(surface, materialInfo.mapOffset, materialInfo.mapSize); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Метод выполняет преобразование UV-координат текстурированных граней. В связи с тем, что в формате MRL предусмотрено | ||||
| 		 * масштабирование и смещение текстурной карты в UV-пространстве, а в движке такой фунциональности нет, необходимо | ||||
| 		 * эмулировать преобразования текстуры преобразованием UV-координат граней. Преобразования выполняются исходя из предположения, | ||||
| 		 * что текстурное пространство сначала масштабируется относительно центра, а затем сдвигается на указанную величину | ||||
| 		 * смещения. | ||||
| 		 *  | ||||
| 		 * @param surface поверхность, грани которой обрабатываюся | ||||
| 		 * @param mapOffset смещение текстурной карты. Значение mapOffset.x указывает смещение по U, значение mapOffset.y | ||||
| 		 * 		указывает смещение по V. | ||||
| 		 * @param mapSize коэффициенты масштабирования текстурной карты. Значение mapSize.x указывает коэффициент масштабирования | ||||
| 		 * 		по оси U, значение mapSize.y указывает коэффициент масштабирования по оси V.  | ||||
| 		 */ | ||||
| 		private function transformUVs(surface:Surface, mapOffset:Point, mapSize:Point):void { | ||||
| 			for (var key:* in surface.faces) { | ||||
| 				var face:Face = key; | ||||
| 				var uv:Point = face.aUV; | ||||
| 				if (uv != null) { | ||||
| 					uv.x = 0.5 + (uv.x - 0.5 - mapOffset.x) * mapSize.x; | ||||
| 					uv.y = 0.5 + (uv.y - 0.5 - mapOffset.y) * mapSize.y; | ||||
| 					face.aUV = uv; | ||||
| 					uv = face.bUV; | ||||
| 					uv.x = 0.5 + (uv.x - 0.5 - mapOffset.x) * mapSize.x; | ||||
| 					uv.y = 0.5 + (uv.y - 0.5 - mapOffset.y) * mapSize.y; | ||||
| 					face.bUV = uv; | ||||
| 					uv = face.cUV; | ||||
| 					uv.x = 0.5 + (uv.x - 0.5 - mapOffset.x) * mapSize.x; | ||||
| 					uv.y = 0.5 + (uv.y - 0.5 - mapOffset.y) * mapSize.y; | ||||
| 					face.cUV = uv; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,120 @@ | ||||
| package alternativa.engine3d.loaders { | ||||
| 	/** | ||||
| 	 * @private | ||||
| 	 * Класс содержит информацию о текстуре в формате MTL material format (Lightwave, OBJ) и функционал для разбора  | ||||
| 	 * описания текстуры. | ||||
| 	 * Описание формата можно посмотреть по адресу: http://local.wasp.uwa.edu.au/~pbourke/dataformats/mtl/ | ||||
| 	 */ | ||||
| 	internal class MTLTextureMapInfo { | ||||
| 		 | ||||
| 		// Ассоциация параметров команды объявления текстуры и методов для их чтения | ||||
| 		private static const optionReaders:Object = { | ||||
| 			"-clamp": clampReader, | ||||
| 			"-o": offsetReader, | ||||
| 			"-s": sizeReader, | ||||
|  | ||||
| 			"-blendu": stubReader, | ||||
| 			"-blendv": stubReader, | ||||
| 			"-bm": stubReader, | ||||
| 			"-boost": stubReader, | ||||
| 			"-cc": stubReader, | ||||
| 			"-imfchan": stubReader, | ||||
| 			"-mm": stubReader, | ||||
| 			"-t": stubReader, | ||||
| 			"-texres": stubReader | ||||
| 		}; | ||||
| 		 | ||||
| 		// Смещение в текстурном пространстве | ||||
| 		public var offsetU:Number = 0; | ||||
| 		public var offsetV:Number = 0; | ||||
| 		public var offsetW:Number = 0; | ||||
| 		 | ||||
| 		// Масштабирование текстурного пространства | ||||
| 		public var sizeU:Number = 1; | ||||
| 		public var sizeV:Number = 1; | ||||
| 		public var sizeW:Number = 1; | ||||
| 		 | ||||
| 		// Флаг повторения текстуры | ||||
| 		public var repeat:Boolean = true; | ||||
| 		// Имя файла текстуры  | ||||
| 		public var fileName:String; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Метод выполняет разбор данных о текстуре. | ||||
| 		 *  | ||||
| 		 * @param parts Данные о текстуре. Массив должен содержать части разделённой по пробелам входной строки MTL-файла. | ||||
| 		 * @return объект, содержащий данные о текстуре | ||||
| 		 */ | ||||
| 		public static function parse(parts:Array):MTLTextureMapInfo { | ||||
| 			var info:MTLTextureMapInfo = new MTLTextureMapInfo(); | ||||
| 			// Начальное значение индекса единица, т.к. первый элемент массива содержит тип текстуры | ||||
| 			var index:int = 1; | ||||
| 			var reader:Function; | ||||
| 			// Чтение параметров текстуры | ||||
| 			while ((reader = optionReaders[parts[index]]) != null) { | ||||
| 				index = reader(index, parts, info); | ||||
| 			} | ||||
| 			// Если не было ошибок, последний элемент массива должен содержать имя файла текстуры | ||||
| 			info.fileName = parts[index]; | ||||
| 			return info; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Читатель-заглушка. Пропускает все неподдерживаемые параметры. | ||||
| 		 */ | ||||
| 		private static function stubReader(index:int, parts:Array, info:MTLTextureMapInfo):int	{ | ||||
| 			index++; | ||||
| 			var maxIndex:int = parts.length - 1; | ||||
| 			while ((MTLTextureMapInfo.optionReaders[parts[index]] == null) && (index < maxIndex)) { | ||||
| 				index++; | ||||
| 			} | ||||
| 			return index; | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 * Метод чтения параметров масштабирования текстурного пространства. | ||||
| 		 */ | ||||
| 		private static function sizeReader(index:int, parts:Array, info:MTLTextureMapInfo):int	{ | ||||
| 			info.sizeU = Number(parts[index + 1]); | ||||
| 			index += 2; | ||||
| 			var value:Number = Number(parts[index]); | ||||
| 			if (!isNaN(value)) { | ||||
| 				info.sizeV = value; | ||||
| 				index++; | ||||
| 				value = Number(parts[index]); | ||||
| 				if (!isNaN(value)) { | ||||
| 					info.sizeW = value; | ||||
| 					index++; | ||||
| 				} | ||||
| 			} | ||||
| 			return index; | ||||
| 		} | ||||
| 	 | ||||
| 		/** | ||||
| 		 * Метод чтения параметров смещения текстуры. | ||||
| 		 */ | ||||
| 		private static function offsetReader(index:int, parts:Array, info:MTLTextureMapInfo):int	{ | ||||
| 			info.offsetU = Number(parts[index + 1]); | ||||
| 			index += 2; | ||||
| 			var value:Number = Number(parts[index]); | ||||
| 			if (!isNaN(value)) { | ||||
| 				info.offsetV = value; | ||||
| 				index++; | ||||
| 				value = Number(parts[index]); | ||||
| 				if (!isNaN(value)) { | ||||
| 					info.offsetW = value; | ||||
| 					index++; | ||||
| 				} | ||||
| 			} | ||||
| 			return index; | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Метод чтения параметра повторения текстуры. | ||||
| 		 */ | ||||
| 		private static function clampReader(index:int, parts:Array, info:MTLTextureMapInfo):int		{ | ||||
| 			info.repeat = parts[index + 1] == "off"; | ||||
| 			return index + 2; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,20 @@ | ||||
| package alternativa.engine3d.loaders { | ||||
| 	import flash.display.BitmapData; | ||||
| 	import flash.geom.Point; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @private | ||||
| 	 * Класс содержит обобщённую информацию о материале. | ||||
| 	 */ | ||||
| 	internal class MaterialInfo { | ||||
| 		public var color:uint; | ||||
| 		public var alpha:Number; | ||||
|  | ||||
| 		public var textureFileName:String; | ||||
| 		public var bitmapData:BitmapData; | ||||
| 		public var repeat:Boolean; | ||||
|  | ||||
| 		public var mapOffset:Point; | ||||
| 		public var mapSize:Point; | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Tubix
					Tubix