GLS.FileASE.pas 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784
  1. //
  2. // The graphics rendering engine GLScene http://glscene.org
  3. //
  4. unit GLS.FileASE;
  5. (* ASE (ASCI Scene Export) file format support *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. GLS.VectorFileObjects,
  12. GLS.ApplicationFileIO,
  13. GLS.VectorTypes,
  14. GLS.VectorGeometry,
  15. GLS.VectorLists,
  16. GLS.Texture,
  17. GLS.Material;
  18. const
  19. GL_ASE_MAX_TEXURE_CHANNELS = 12; // maximum texture channels
  20. GL_ASE_MAX_SUBMATERIALS = 5; // maximum material submaterials
  21. GL_ASE_MAX_SMOOTH_GROUPS = 5; // maximum smoothing groups
  22. GL_ASE_MAX_TEXTURE_MAPS = 12; // maximum texture maps
  23. type
  24. // face texture channel indices
  25. TGLASEFaceTexure = record
  26. Idx0, Idx1, Idx2: Integer;
  27. end;
  28. // face texture channels
  29. TGLASEFaceTexureChannels = record
  30. Count: Integer;
  31. ChanelTexture: array [0..GL_ASE_MAX_TEXURE_CHANNELS - 1] of TGLASEFaceTexure;
  32. end;
  33. TGLASESmoothingGroups = record
  34. Count: Integer;
  35. Groups: array [0..GL_ASE_MAX_SMOOTH_GROUPS] of Integer;
  36. end;
  37. // ASE mesh face
  38. TGLASEFace = class(TObject)
  39. private
  40. FV: array [0..2] of Integer;
  41. FNormal: TAffineVector;
  42. FN: array [0..2] of TAffineVector;
  43. FSmoothing: TGLASESmoothingGroups;
  44. FSubMaterialID: Integer; // submaterial ID
  45. FTextChannels: TGLASEFaceTexureChannels;
  46. public
  47. constructor Create;
  48. property VertIdx1: Integer read FV[0]; // vertex 0 index
  49. property VertIdx2: Integer read FV[1]; // vertex 1 index
  50. property VertIdx3: Integer read FV[2]; // vertex 2 index
  51. property Normal: TAffineVector read FNormal; // face normal
  52. property Normal1: TAffineVector read FN[0]; // vertex 0 normal
  53. property Normal2: TAffineVector read FN[1]; // vertex 1 normal
  54. property Normal3: TAffineVector read FN[2]; // vertex 2 normal
  55. property TextChannels: TGLASEFaceTexureChannels read FTextChannels; // channels texture coordinates
  56. property Smoothing: TGLASESmoothingGroups read FSmoothing; // smoothing group list
  57. property SubMaterialID: Integer read FSubMaterialID; // submaterial ID
  58. end;
  59. // ASE mesh faces list
  60. TGLASEFaceList = class(TObject)
  61. private
  62. FItems: TList;
  63. function GetFace(Index: Integer): TGLASEFace;
  64. function GetCount: Integer;
  65. public
  66. constructor Create;
  67. destructor Destroy; override;
  68. function Add: TGLASEFace;
  69. procedure Delete(aIndex: Integer);
  70. procedure Clear;
  71. property Face[Index: Integer]: TGLASEFace read GetFace; default;
  72. property Count: Integer read GetCount;
  73. end;
  74. (* ASE geom object, represents single mesh object;
  75. contains: vertices, faces, verice indices, faces and vertices normals,
  76. channels of texture coordinates and indices, scaling and location info;
  77. this object used only to store ASE data temporary to copy supported piece of it into GLScene TMeshObject *)
  78. TGLASEMeshObject = class(TObject)
  79. private
  80. FFaces: TGLASEFaceList;
  81. FVertices: TAffineVectorList;
  82. FMatrix: TGLMatrix;
  83. FInheritedPosition: TAffineVector;
  84. FInheritedScale: TAffineVector;
  85. FInheritedRotation: TAffineVector;
  86. FRotationAngle: Single;
  87. FRotationAxis: TAffineVector;
  88. FPosition: TGLVector;
  89. FScale: TAffineVector;
  90. FScaleAxisAngle: Single;
  91. FScaleAxis: TAffineVector;
  92. FTexChannels: array [0..GL_ASE_MAX_TEXURE_CHANNELS - 1] of TAffineVectorList;
  93. FTexChannelsCount: Integer;
  94. FHasNormals: Boolean;
  95. FMaterialID: Integer;
  96. function AddTexChannel: TAffineVectorList;
  97. function GetTextChannel(Channel: Integer): TAffineVectorList;
  98. public
  99. constructor Create;
  100. destructor Destroy; override;
  101. property Faces: TGLASEFaceList read FFaces;
  102. property Vertices: TAffineVectorList read FVertices;
  103. property TextChannel[Channel: Integer]: TAffineVectorList read GetTextChannel;
  104. property TextChannelsCount: Integer read FTexChannelsCount;
  105. property Matrix: TGLMatrix read FMatrix;
  106. property InheritedPosition: TAffineVector read FInheritedPosition;
  107. property InheritedRotation: TAffineVector read FInheritedRotation;
  108. property InheritedScale: TAffineVector read FInheritedScale;
  109. property Position: TGLVector read FPosition;
  110. property RotationAxis: TAffineVector read FRotationAxis;
  111. property RotationAngle: Single read FRotationAngle;
  112. property Scale: TAffineVector read FScale;
  113. property ScaleAxis: TAffineVector read FScaleAxis;
  114. property ScaleAxisAngle: Single read FScaleAxisAngle;
  115. property HasNormals: Boolean read FHasNormals;
  116. property MaterialID: Integer read FMaterialID;
  117. end;
  118. TGLASEMaterialTextureMap = record
  119. Kind: string;
  120. Name: string;
  121. _Class: string;
  122. No: Integer;
  123. Amount: Single;
  124. Bitmap: string;
  125. UOffset: Single;
  126. VOffset: Single;
  127. UTiling: Single;
  128. VTiling: Single;
  129. Angle: Single;
  130. Blur: Single;
  131. BlurOffset: Single;
  132. NouseAmount: Single;
  133. NoiseSize: Single;
  134. NoiseLevel: Integer;
  135. NoisePhase: Single;
  136. end;
  137. TGLASEMaterialTextureMaps = record
  138. Map: array [0..GL_ASE_MAX_TEXTURE_MAPS - 1] of TGLASEMaterialTextureMap;
  139. Count: Integer;
  140. end;
  141. TGLASESubMaterial = record
  142. Name: string;
  143. Ambient: TAffineVector;
  144. Diffuse: TAffineVector;
  145. Specular: TAffineVector;
  146. Shiness: Single;
  147. ShineStrength: Single;
  148. Transparency: Single;
  149. WireSize: Single;
  150. SelfIllumination: Single;
  151. TextureMaps: TGLASEMaterialTextureMaps;
  152. end;
  153. TGLASESubMaterialList = record
  154. SubMaterial: array [0..GL_ASE_MAX_SUBMATERIALS - 1] of TGLASESubMaterial;
  155. Count: Integer;
  156. end;
  157. TGLASEMaterial = class(TObject)
  158. private
  159. FWireSize: Single;
  160. FShineStrength: Single;
  161. FShiness: Single;
  162. FTransparency: Single;
  163. FName: string;
  164. FDiffuse: TAffineVector;
  165. FAmbient: TAffineVector;
  166. FSpecular: TAffineVector;
  167. FSubMaterials: TGLASESubMaterialList;
  168. FTextureMaps: TGLASEMaterialTextureMaps;
  169. public
  170. constructor Create;
  171. property Name: string read FName;
  172. property Ambient: TAffineVector read FAmbient;
  173. property Diffuse: TAffineVector read FDiffuse;
  174. property Specular: TAffineVector read FSpecular;
  175. property Shiness: Single read FShiness;
  176. property ShineStrength: Single read FShineStrength;
  177. property Transparency: Single read FTransparency;
  178. property WireSize: Single read FWireSize;
  179. property TextureMaps: TGLASEMaterialTextureMaps read FTextureMaps;
  180. property SubMaterials: TGLASESubMaterialList read FSubMaterials;
  181. end;
  182. TGLASEMaterialList = class(TObject)
  183. private
  184. FItems: TList;
  185. function GetCount: Integer;
  186. function GetMaterial(Index: Integer): TGLASEMaterial;
  187. public
  188. constructor Create;
  189. destructor Destroy; override;
  190. function Add: TGLASEMaterial;
  191. procedure Delete(aIndex: Integer);
  192. procedure Clear;
  193. property Material[Index: Integer]: TGLASEMaterial read GetMaterial; default;
  194. property Count: Integer read GetCount;
  195. end;
  196. // ASE vector file parser
  197. TGLASEVectorFile = class(TGLVectorFile)
  198. private
  199. FStringData: TStringList;
  200. FHeader: string;
  201. FComment: string;
  202. FRECVShadow: Boolean;
  203. FCastShadow: Boolean;
  204. FMotionBlur: Boolean;
  205. FMaterialList: TGLASEMaterialList;
  206. function ContainString(const aData, aString: string): Boolean;
  207. function GetTagOnData(const aData: string): Integer;
  208. function IsEndOfSection(const aData: string): Boolean;
  209. function GetValue3D(const aData: string): TAffineVector;
  210. function GetValue4D(const aData: string; var Value0: Integer): TAffineVector;
  211. function GetStringValue(const aData: string): string;
  212. function GetDoubleValue(const aData: string): Double;
  213. function GetFirstValue(aData: string): string;
  214. function GetEndOfFirstValue(const aData: string): Integer;
  215. procedure SkipSection(var aLineIndex: Integer);
  216. function IsSectionBegingin(const aData: string): Boolean;
  217. function CheckUnknownData(var aLineIndex: Integer): Boolean;
  218. procedure ParseFaceString(const aData: string; var Index, A, B, C, AB, BC, CA, MatID: Integer; var Smooth: TGLASESmoothingGroups);
  219. private
  220. procedure ParseScene(var aLineIndex: Integer);
  221. procedure ParseGeomObject(var aLineIndex: Integer);
  222. procedure ParseMeshOptions(var aLineIndex: Integer; aMesh: TGLASEMeshObject);
  223. procedure ParseMeshGeom(var aLineIndex: Integer; aMesh: TGLASEMeshObject);
  224. procedure ParseMappingChannel(var aLineIndex: Integer; aMesh: TGLASEMeshObject);
  225. procedure ParseMeshVertices(var aLineIndex: Integer; aMesh: TGLASEMeshObject; VerticesCount: Integer);
  226. procedure ParseMeshFaces(var aLineIndex: Integer; aMesh: TGLASEMeshObject; FacesCount: Integer);
  227. procedure ParseMeshNormals(var aLineIndex: Integer; aMesh: TGLASEMeshObject; FacesCount: Integer);
  228. procedure ParseMeshTextureVertices(var aLineIndex: Integer; aMesh: TGLASEMeshObject; TextureVerticesCount: Integer);
  229. procedure ParseMeshTextureFaces(var aLineIndex: Integer; aMesh: TGLASEMeshObject; TextureFacesCount: Integer);
  230. procedure ParseMaterialList(var aLineIndex: Integer);
  231. procedure ParseMaterial(var aLineIndex: Integer; aMaterial: TGLASEMaterial);
  232. procedure ParseSubMaterial(var aLineIndex: Integer; aMaterial: TGLASEMaterial);
  233. function CheckTextureMap(var aLineIndex: Integer; var aMaps: TGLASEMaterialTextureMaps): Boolean;
  234. procedure ParseTextureMap(var aLineIndex: Integer; var aMaps: TGLASEMaterialTextureMaps; const aMapKind: string);
  235. function GetPropMBlur(const aData: string): Boolean;
  236. function GetPropCastShadow(const aData: string): Boolean;
  237. function GetPropRECVShadow(const aData: string): Boolean;
  238. procedure Parse;
  239. public
  240. constructor Create(AOwner: TPersistent); override;
  241. destructor Destroy; override;
  242. procedure LoadFromStream(aStream: TStream); override;
  243. class function Capabilities: TGLDataFileCapabilities; override;
  244. property Header: string read FHeader;
  245. property Comment: string read FComment;
  246. property MotionBlur: Boolean read FMotionBlur;
  247. property CastShadow: Boolean read FCastShadow;
  248. property RECVShadow: Boolean read FRECVShadow;
  249. end;
  250. TASETextureMap = (tmGeneric, tmAmbient, tmDiffuse, tmSpecular, tmShine, tmShinestrength,
  251. tmSelfillum, tmOpacity, tmFiltercolor, tmBump, tmReflect, tmRefract);
  252. (* use this functions to select texture and lightmap from ASE file
  253. aSubMaterialIndex = -1 - means main material maps
  254. Default are:
  255. Texture - main material Diffuse map
  256. Lightmap - main material Ambient map *)
  257. procedure ASESetPreferredTexture(aMap: TASETextureMap; aSubMaterialIndex: Integer = -1);
  258. procedure ASESetPreferredLightmap(aMap: TASETextureMap; aSubMaterialIndex: Integer = -1);
  259. implementation
  260. // ASE file tags
  261. const
  262. ASCII_COMMENT_S = 'COMMENT';
  263. ASCII_SCENE_S = 'SCENE';
  264. ASCII_GEOMOBJECT_S = 'GEOMOBJECT';
  265. ASCII_NODE_NAME_S = 'NODE_NAME';
  266. ASCII_NODE_TM_S = 'NODE_TM';
  267. ASCII_INHERIT_POS_S = 'INHERIT_POS';
  268. ASCII_INHERIT_ROT_S = 'INHERIT_ROT';
  269. ASCII_INHERIT_SCL_S = 'INHERIT_SCL';
  270. ASCII_ROW_S = 'TM_ROW0';
  271. ASCII_POS_S = 'TM_POS';
  272. ASCII_ROTAXIS_S = 'TM_ROTAXIS';
  273. ASCII_ROTANGLE_S = 'TM_ROTANGLE';
  274. ASCII_SCALE_S = 'TM_SCALE';
  275. ASCII_SCALEAXIS_S = 'TM_SCALEAXIS';
  276. ASCII_SCALEAXISANG_S = 'TM_SCALEAXISANG';
  277. ASCII_MESH_S = 'MESH';
  278. ASCII_TIMEVALUE_S = 'TIMEVALUE';
  279. ASCII_MESH_NUM_VERTEX_S = 'MESH_NUMVERTEX';
  280. ASCII_NUM_FACES_S = 'MESH_NUMFACES';
  281. ASCII_MESH_VERTEX_S = 'MESH_VERTEX';
  282. ASCII_VERTEX_LIST_S = 'MESH_VERTEX_LIST';
  283. ASCII_MESH_FACE_S = 'MESH_FACE';
  284. ASCII_MESH_FACE_LIST_S = 'MESH_FACE_LIST';
  285. ASCII_MESH_NORMALS_S = 'MESH_NORMALS';
  286. ASCII_MESH_FACE_NORMAL_S = 'MESH_FACENORMAL';
  287. ASCII_MESH_VERTEX_NORMAL_S = 'MESH_VERTEXNORMAL';
  288. ASCII_PROP_MOTION_BLUR_S = 'PROP_MOTIONBLUR';
  289. ASCII_PROP_CAST_SHADOW_S = 'PROP_CASTSHADOW';
  290. ASCII_PROP_RECV_SHADOW_S = 'PROP_RECVSHADOW';
  291. ASCII_ROW1_S = 'TM_ROW1';
  292. ASCII_ROW2_S = 'TM_ROW2';
  293. ASCII_ROW3_S = 'TM_ROW3';
  294. ASCII_MESH_NUMTVERTEX_S = 'MESH_NUMTVERTEX';
  295. ASCII_MESH_TVERTLIST_S = 'MESH_TVERTLIST';
  296. ASCII_MESH_NUMTVFACES_S = 'MESH_NUMTVFACES';
  297. ASCII_MESH_TFACELIST_S = 'MESH_TFACELIST';
  298. ASCII_MESH_MAPPINGCHANNEL_S = 'MESH_MAPPINGCHANNEL';
  299. ASCII_MATERIAL_S = 'MATERIAL';
  300. ASCII_MATERIAL_LIST_S = 'MATERIAL_LIST';
  301. ASCII_MATERIAL_COUNT_S = 'MATERIAL_COUNT';
  302. ASCII_MATERIAL_NAME_S = 'MATERIAL_NAME';
  303. ASCII_MATERIAL_CLASS_S = 'MATERIAL_CLASS';
  304. ASCII_MATERIAL_AMBIENT_S = 'MATERIAL_AMBIENT';
  305. ASCII_MATERIAL_DIFFUSE_S = 'MATERIAL_DIFFUSE';
  306. ASCII_MATERIAL_SPECULAR_S = 'MATERIAL_SPECULAR';
  307. ASCII_MATERIAL_SHINE_S = 'MATERIAL_SHINE';
  308. ASCII_MATERIAL_SHINESTRENGTH_S = 'MATERIAL_SHINESTRENGTH';
  309. ASCII_MATERIAL_TRANSPARENCY_S = 'MATERIAL_TRANSPARENCY';
  310. ASCII_MATERIAL_WIRESIZE_S = 'MATERIAL_WIRESIZE';
  311. ASCII_NUMSUBMTLS_S = 'NUMSUBMTLS';
  312. ASCII_SUBMATERIAL_S = 'SUBMATERIAL';
  313. ASCII_MATERIAL_SHADING_S = 'MATERIAL_SHADING';
  314. ASCII_MATERIAL_XP_FALLOFF_S = 'MATERIAL_XP_FALLOFF';
  315. ASCII_MATERIAL_SELFILLUM_S = 'MATERIAL_SELFILLUM';
  316. ASCII_MATERIAL_FALLOFF_S = 'MATERIAL_FALLOFF';
  317. ASCII_MATERIAL_XP_TYPE_S = 'MATERIAL_XP_TYPE';
  318. ASCII_MAP_DIFFUSE_S = 'MAP_DIFFUSE';
  319. ASCII_MAP_NAME_S = 'MAP_NAME';
  320. ASCII_MAP_CLASS_S = 'MAP_CLASS';
  321. ASCII_MAP_SUBNO_S = 'MAP_SUBNO';
  322. ASCII_MAP_AMOUNT_S = 'MAP_AMOUNT';
  323. ASCII_BITMAP_S = 'BITMAP';
  324. ASCII_MAP_TYPE_S = 'MAP_TYPE';
  325. ASCII_UVW_U_OFFSET_S = 'UVW_U_OFFSET';
  326. ASCII_UVW_V_OFFSET_S = 'UVW_V_OFFSET';
  327. ASCII_UVW_U_TILING_S = 'UVW_U_TILING';
  328. ASCII_UVW_V_TILING_S = 'UVW_V_TILING';
  329. ASCII_UVW_ANGLE_S = 'UVW_ANGLE';
  330. ASCII_UVW_BLUR_S = 'UVW_BLUR';
  331. ASCII_UVW_BLUR_OFFSET_S = 'UVW_BLUR_OFFSET';
  332. ASCII_UVW_NOUSE_AMT_S = 'UVW_NOUSE_AMT';
  333. ASCII_UVW_NOISE_SIZE_S = 'UVW_NOISE_SIZE';
  334. ASCII_UVW_NOISE_LEVEL_S = 'UVW_NOISE_LEVEL';
  335. ASCII_UVW_NOISE_PHASE_S = 'UVW_NOISE_PHASE';
  336. ASCII_BITMAP_FILTER_S = 'BITMAP_FILTER';
  337. ASCII_MESH_SMOOTHING_S = 'MESH_SMOOTHING';
  338. ASCII_MESH_MTLID_S = 'MESH_MTLID';
  339. ASCII_MATERIAL_REF_S = 'MATERIAL_REF';
  340. ASCII_MAP_AMBIENT_S = 'MAP_AMBIENT';
  341. ASCII_MAP_GENERIC_S = 'MAP_GENERIC';
  342. ASCII_MAP_SPECULAR_S = 'MAP_SPECULAR';
  343. ASCII_MAP_SHINE_S = 'MAP_SHINE';
  344. ASCII_MAP_SHINESTRENGTH_S = 'MAP_SHINESTRENGTH';
  345. ASCII_MAP_SELFILLUM_S = 'MAP_SELFILLUM';
  346. ASCII_MAP_OPACITY_S = 'MAP_OPACITY';
  347. ASCII_MAP_FILTERCOLOR_S = 'MAP_FILTERCOLOR';
  348. ASCII_MAP_BUMP_S = 'MAP_BUMP';
  349. ASCII_MAP_REFLECT_S = 'MAP_REFLECT';
  350. ASCII_MAP_REFRACT_S = 'MAP_REFRACT';
  351. const
  352. ASCII_COMMENT_I = 0;
  353. ASCII_SCENE_I = 1;
  354. ASCII_GEOMOBJECT_I = 2;
  355. ASCII_NODE_NAME_I = 3;
  356. ASCII_NODE_TM_I = 4;
  357. ASCII_INHERIT_POS_I = 5;
  358. ASCII_INHERIT_ROT_I = 6;
  359. ASCII_INHERIT_SCL_I = 7;
  360. ASCII_ROW_I = 8;
  361. ASCII_POS_I = 9;
  362. ASCII_ROTAXIS_I = 10;
  363. ASCII_ROTANGLE_I = 11;
  364. ASCII_SCALE_I = 12;
  365. ASCII_SCALEAXIS_I = 13;
  366. ASCII_SCALEAXISANG_I = 14;
  367. ASCII_MESH_I = 15;
  368. ASCII_TIMEVALUE_I = 16;
  369. ASCII_MESH_NUM_VERTEX_I = 17;
  370. ASCII_NUM_FACES_I = 18;
  371. ASCII_MESH_VERTEX_I = 19;
  372. ASCII_VERTEX_LIST_I = 20;
  373. ASCII_MESH_FACE_I = 21;
  374. ASCII_MESH_FACE_LIST_I = 22;
  375. ASCII_MESH_NORMALS_I = 23;
  376. ASCII_MESH_FACE_NORMAL_I = 24;
  377. ASCII_MESH_VERTEX_NORMAL_I = 25;
  378. ASCII_PROP_MOTION_BLUR_I = 26;
  379. ASCII_PROP_CAST_SHADOW_I = 27;
  380. ASCII_PROP_RECV_SHADOW_I = 28;
  381. ASCII_ROW1_I = 29;
  382. ASCII_ROW2_I = 30;
  383. ASCII_ROW3_I = 31;
  384. ASCII_MESH_NUMTVERTEX_I = 32;
  385. ASCII_MESH_TVERTLIST_I = 33;
  386. ASCII_MESH_NUMTVFACES_I = 34;
  387. ASCII_MESH_TFACELIST_I = 35;
  388. ASCII_MESH_MAPPINGCHANNEL_I = 36;
  389. ASCII_MATERIAL_I = 37;
  390. ASCII_MATERIAL_LIST_I = 38;
  391. ASCII_MATERIAL_COUNT_I = 39;
  392. ASCII_MATERIAL_NAME_I = 40;
  393. ASCII_MATERIAL_CLASS_I = 41;
  394. ASCII_MATERIAL_AMBIENT_I = 42;
  395. ASCII_MATERIAL_DIFFUSE_I = 43;
  396. ASCII_MATERIAL_SPECULAR_I = 44;
  397. ASCII_MATERIAL_SHINE_I = 45;
  398. ASCII_MATERIAL_SHINESTRENGTH_I = 46;
  399. ASCII_MATERIAL_TRANSPARENCY_I = 47;
  400. ASCII_MATERIAL_WIRESIZE_I = 48;
  401. ASCII_NUMSUBMTLS_I = 49;
  402. ASCII_SUBMATERIAL_I = 50;
  403. ASCII_MATERIAL_SHADING_I = 51;
  404. ASCII_MATERIAL_XP_FALLOFF_I = 52;
  405. ASCII_MATERIAL_SELFILLUM_I = 53;
  406. ASCII_MATERIAL_FALLOFF_I = 54;
  407. ASCII_MATERIAL_XP_TYPE_I = 55;
  408. ASCII_MAP_DIFFUSE_I = 56;
  409. ASCII_MAP_NAME_I = 57;
  410. ASCII_MAP_CLASS_I = 58;
  411. ASCII_MAP_SUBNO_I = 59;
  412. ASCII_MAP_AMOUNT_I = 60;
  413. ASCII_BITMAP_I = 61;
  414. ASCII_MAP_TYPE_I = 62;
  415. ASCII_UVW_U_OFFSET_I = 63;
  416. ASCII_UVW_V_OFFSET_I = 64;
  417. ASCII_UVW_U_TILING_I = 65;
  418. ASCII_UVW_V_TILING_I = 66;
  419. ASCII_UVW_ANGLE_I = 67;
  420. ASCII_UVW_BLUR_I = 68;
  421. ASCII_UVW_BLUR_OFFSET_I = 69;
  422. ASCII_UVW_NOUSE_AMT_I = 70;
  423. ASCII_UVW_NOISE_SIZE_I = 71;
  424. ASCII_UVW_NOISE_LEVEL_I = 72;
  425. ASCII_UVW_NOISE_PHASE_I = 73;
  426. ASCII_BITMAP_FILTER_I = 74;
  427. ASCII_MESH_SMOOTHING_I = 75;
  428. ASCII_MESH_MTLID_I = 76;
  429. ASCII_MATERIAL_REF_I = 77;
  430. ASCII_MAP_AMBIENT_I = 78;
  431. ASCII_MAP_GENERIC_I = 79;
  432. ASCII_MAP_SPECULAR_I = 80;
  433. ASCII_MAP_SHINE_I = 81;
  434. ASCII_MAP_SHINESTRENGTH_I = 82;
  435. ASCII_MAP_SELFILLUM_I = 83;
  436. ASCII_MAP_OPACITY_I = 84;
  437. ASCII_MAP_FILTERCOLOR_I = 85;
  438. ASCII_MAP_BUMP_I = 86;
  439. ASCII_MAP_REFLECT_I = 87;
  440. ASCII_MAP_REFRACT_I = 88;
  441. const
  442. ASCII_MESH_OT = 0;
  443. ASCII_LIGHT_OT = 1;
  444. type
  445. TTagIdx = record
  446. Idx: Integer;
  447. Name: string;
  448. end;
  449. (* WARNING: if vTagIdx elements Names are substring one to each other, it must be arragned by Name length,
  450. for correct fast lookup. i.e.:
  451. MESH_FACE must be placed before MESH_FACE_LIST *)
  452. const
  453. vTagIdx: array [0..88] of TTagIdx = (
  454. (Idx: ASCII_COMMENT_I; Name: ASCII_COMMENT_S),
  455. (Idx: ASCII_SCENE_I; Name: ASCII_SCENE_S),
  456. (Idx: ASCII_GEOMOBJECT_I; Name: ASCII_GEOMOBJECT_S),
  457. (Idx: ASCII_NODE_NAME_I; Name: ASCII_NODE_NAME_S),
  458. (Idx: ASCII_NODE_TM_I; Name: ASCII_NODE_TM_S),
  459. (Idx: ASCII_INHERIT_POS_I; Name: ASCII_INHERIT_POS_S),
  460. (Idx: ASCII_INHERIT_ROT_I; Name: ASCII_INHERIT_ROT_S),
  461. (Idx: ASCII_INHERIT_SCL_I; Name: ASCII_INHERIT_SCL_S),
  462. (Idx: ASCII_ROW_I; Name: ASCII_ROW_S),
  463. (Idx: ASCII_POS_I; Name: ASCII_POS_S),
  464. (Idx: ASCII_ROTAXIS_I; Name: ASCII_ROTAXIS_S),
  465. (Idx: ASCII_ROTANGLE_I; Name: ASCII_ROTANGLE_S),
  466. (Idx: ASCII_SCALE_I; Name: ASCII_SCALE_S),
  467. (Idx: ASCII_SCALEAXIS_I; Name: ASCII_SCALEAXIS_S),
  468. (Idx: ASCII_SCALEAXISANG_I; Name: ASCII_SCALEAXISANG_S),
  469. (Idx: ASCII_MESH_I; Name: ASCII_MESH_S),
  470. (Idx: ASCII_TIMEVALUE_I; Name: ASCII_TIMEVALUE_S),
  471. (Idx: ASCII_MESH_NUM_VERTEX_I; Name: ASCII_MESH_NUM_VERTEX_S),
  472. (Idx: ASCII_NUM_FACES_I; Name: ASCII_NUM_FACES_S),
  473. (Idx: ASCII_MESH_VERTEX_I; Name: ASCII_MESH_VERTEX_S),
  474. (Idx: ASCII_VERTEX_LIST_I; Name: ASCII_VERTEX_LIST_S),
  475. (Idx: ASCII_MESH_FACE_I; Name: ASCII_MESH_FACE_S),
  476. (Idx: ASCII_MESH_FACE_LIST_I; Name: ASCII_MESH_FACE_LIST_S),
  477. (Idx: ASCII_MESH_NORMALS_I; Name: ASCII_MESH_NORMALS_S),
  478. (Idx: ASCII_MESH_FACE_NORMAL_I; Name: ASCII_MESH_FACE_NORMAL_S),
  479. (Idx: ASCII_MESH_VERTEX_NORMAL_I; Name: ASCII_MESH_VERTEX_NORMAL_S),
  480. (Idx: ASCII_PROP_MOTION_BLUR_I; Name: ASCII_PROP_MOTION_BLUR_S),
  481. (Idx: ASCII_PROP_CAST_SHADOW_I; Name: ASCII_PROP_CAST_SHADOW_S),
  482. (Idx: ASCII_PROP_RECV_SHADOW_I; Name: ASCII_PROP_RECV_SHADOW_S),
  483. (Idx: ASCII_ROW1_I; Name: ASCII_ROW1_S),
  484. (Idx: ASCII_ROW2_I; Name: ASCII_ROW2_S),
  485. (Idx: ASCII_ROW3_I; Name: ASCII_ROW3_S),
  486. (Idx: ASCII_MESH_NUMTVERTEX_I; Name: ASCII_MESH_NUMTVERTEX_S),
  487. (Idx: ASCII_MESH_TVERTLIST_I; Name: ASCII_MESH_TVERTLIST_S),
  488. (Idx: ASCII_MESH_NUMTVFACES_I; Name: ASCII_MESH_NUMTVFACES_S),
  489. (Idx: ASCII_MESH_TFACELIST_I; Name: ASCII_MESH_TFACELIST_S),
  490. (Idx: ASCII_MESH_MAPPINGCHANNEL_I; Name: ASCII_MESH_MAPPINGCHANNEL_S),
  491. (Idx: ASCII_MATERIAL_I; Name: ASCII_MATERIAL_S),
  492. (Idx: ASCII_MATERIAL_LIST_I; Name: ASCII_MATERIAL_LIST_S),
  493. (Idx: ASCII_MATERIAL_COUNT_I; Name: ASCII_MATERIAL_COUNT_S),
  494. (Idx: ASCII_MATERIAL_NAME_I; Name: ASCII_MATERIAL_NAME_S),
  495. (Idx: ASCII_MATERIAL_CLASS_I; Name: ASCII_MATERIAL_CLASS_S),
  496. (Idx: ASCII_MATERIAL_AMBIENT_I; Name: ASCII_MATERIAL_AMBIENT_S),
  497. (Idx: ASCII_MATERIAL_DIFFUSE_I; Name: ASCII_MATERIAL_DIFFUSE_S),
  498. (Idx: ASCII_MATERIAL_SPECULAR_I; Name: ASCII_MATERIAL_SPECULAR_S),
  499. (Idx: ASCII_MATERIAL_SHINE_I; Name: ASCII_MATERIAL_SHINE_S),
  500. (Idx: ASCII_MATERIAL_SHINESTRENGTH_I; Name: ASCII_MATERIAL_SHINESTRENGTH_S),
  501. (Idx: ASCII_MATERIAL_TRANSPARENCY_I; Name: ASCII_MATERIAL_TRANSPARENCY_S),
  502. (Idx: ASCII_MATERIAL_WIRESIZE_I; Name: ASCII_MATERIAL_WIRESIZE_S),
  503. (Idx: ASCII_NUMSUBMTLS_I; Name: ASCII_NUMSUBMTLS_S),
  504. (Idx: ASCII_SUBMATERIAL_I; Name: ASCII_SUBMATERIAL_S),
  505. (Idx: ASCII_MATERIAL_SHADING_I; Name: ASCII_MATERIAL_SHADING_S),
  506. (Idx: ASCII_MATERIAL_XP_FALLOFF_I; Name: ASCII_MATERIAL_XP_FALLOFF_S),
  507. (Idx: ASCII_MATERIAL_SELFILLUM_I; Name: ASCII_MATERIAL_SELFILLUM_S),
  508. (Idx: ASCII_MATERIAL_FALLOFF_I; Name: ASCII_MATERIAL_FALLOFF_S),
  509. (Idx: ASCII_MATERIAL_XP_TYPE_I; Name: ASCII_MATERIAL_XP_TYPE_S),
  510. (Idx: ASCII_MAP_DIFFUSE_I; Name: ASCII_MAP_DIFFUSE_S),
  511. (Idx: ASCII_MAP_AMBIENT_I; Name: ASCII_MAP_AMBIENT_S),
  512. (Idx: ASCII_MAP_GENERIC_I; Name: ASCII_MAP_GENERIC_S),
  513. (Idx: ASCII_MAP_SPECULAR_I; Name: ASCII_MAP_SPECULAR_S),
  514. (Idx: ASCII_MAP_SHINE_I; Name: ASCII_MAP_SHINE_S),
  515. (Idx: ASCII_MAP_SHINESTRENGTH_I; Name: ASCII_MAP_SHINESTRENGTH_S),
  516. (Idx: ASCII_MAP_SELFILLUM_I; Name: ASCII_MAP_SELFILLUM_S),
  517. (Idx: ASCII_MAP_OPACITY_I; Name: ASCII_MAP_OPACITY_S),
  518. (Idx: ASCII_MAP_FILTERCOLOR_I; Name: ASCII_MAP_FILTERCOLOR_S),
  519. (Idx: ASCII_MAP_BUMP_I; Name: ASCII_MAP_BUMP_S),
  520. (Idx: ASCII_MAP_REFLECT_I; Name: ASCII_MAP_REFLECT_S),
  521. (Idx: ASCII_MAP_REFRACT_I; Name: ASCII_MAP_REFRACT_S),
  522. (Idx: ASCII_MAP_NAME_I; Name: ASCII_MAP_NAME_S),
  523. (Idx: ASCII_MAP_CLASS_I; Name: ASCII_MAP_CLASS_S),
  524. (Idx: ASCII_MAP_SUBNO_I; Name: ASCII_MAP_SUBNO_S),
  525. (Idx: ASCII_MAP_AMOUNT_I; Name: ASCII_MAP_AMOUNT_S),
  526. (Idx: ASCII_BITMAP_I; Name: ASCII_BITMAP_S),
  527. (Idx: ASCII_MAP_TYPE_I; Name: ASCII_MAP_TYPE_S),
  528. (Idx: ASCII_UVW_U_OFFSET_I; Name: ASCII_UVW_U_OFFSET_S),
  529. (Idx: ASCII_UVW_V_OFFSET_I; Name: ASCII_UVW_V_OFFSET_S),
  530. (Idx: ASCII_UVW_U_TILING_I; Name: ASCII_UVW_U_TILING_S),
  531. (Idx: ASCII_UVW_V_TILING_I; Name: ASCII_UVW_V_TILING_S),
  532. (Idx: ASCII_UVW_ANGLE_I; Name: ASCII_UVW_ANGLE_S),
  533. (Idx: ASCII_UVW_BLUR_I; Name: ASCII_UVW_BLUR_S),
  534. (Idx: ASCII_UVW_BLUR_OFFSET_I; Name: ASCII_UVW_BLUR_OFFSET_S),
  535. (Idx: ASCII_UVW_NOUSE_AMT_I; Name: ASCII_UVW_NOUSE_AMT_S),
  536. (Idx: ASCII_UVW_NOISE_SIZE_I; Name: ASCII_UVW_NOISE_SIZE_S),
  537. (Idx: ASCII_UVW_NOISE_LEVEL_I; Name: ASCII_UVW_NOISE_LEVEL_S),
  538. (Idx: ASCII_UVW_NOISE_PHASE_I; Name: ASCII_UVW_NOISE_PHASE_S),
  539. (Idx: ASCII_BITMAP_FILTER_I; Name: ASCII_BITMAP_FILTER_S),
  540. (Idx: ASCII_MESH_SMOOTHING_I; Name: ASCII_MESH_SMOOTHING_S),
  541. (Idx: ASCII_MESH_MTLID_I; Name: ASCII_MESH_MTLID_S),
  542. (Idx: ASCII_MATERIAL_REF_I; Name: ASCII_MATERIAL_REF_S)
  543. );
  544. procedure ChangeDotToComma(var aValue: string);
  545. var
  546. Index: Integer;
  547. begin
  548. for Index := 1 to Length(aValue) do
  549. if aValue[Index] = '.' then
  550. aValue[Index] := ',';
  551. end;
  552. procedure ChangeCommaToDot(var aValue: string);
  553. var
  554. Index: Integer;
  555. begin
  556. for Index := 1 to Length(aValue) do
  557. if aValue[Index] = ',' then
  558. aValue[Index] := '.';
  559. end;
  560. procedure ChangeTabToSpace(var aValue: string);
  561. var
  562. Index: Integer;
  563. begin
  564. for Index := 1 to Length(aValue) do
  565. if aValue[Index] = #9 then
  566. aValue[Index] := #32;
  567. end;
  568. function StringToFloatRegular(aValue: string): Double;
  569. begin
  570. Result := StrToFloatDef(aValue, 0);
  571. if Result = 0 then begin
  572. ChangeDotToComma(aValue);
  573. Result := StrToFloatDef(aValue, 0);
  574. if Result = 0 then begin
  575. ChangeCommaToDot(aValue);
  576. Result := StrToFloatDef(aValue, 0);
  577. end;
  578. end;
  579. end;
  580. var
  581. vPrepTexMap: TASETextureMap;
  582. vPrepTexSubM: Integer;
  583. vPrepLightMap: TASETextureMap;
  584. vPrepLightSubM: Integer;
  585. procedure ASESetPreferredTexture(aMap: TASETextureMap; aSubMaterialIndex: Integer = -1);
  586. begin
  587. vPrepTexMap := aMap;
  588. vPrepTexSubM := aSubmaterialIndex
  589. end;
  590. procedure ASESetPreferredLightmap(aMap: TASETextureMap; aSubMaterialIndex: Integer = -1);
  591. begin
  592. vPrepLightMap := aMap;
  593. vPrepLightSubM := aSubMaterialIndex;
  594. end;
  595. // here ASE geom object is converted to GLScene mesh
  596. procedure CopyASEToMesh(aASEMesh: TGLASEMeshObject; aMesh: TMeshObject; aASEMaterials: TGLASEMaterialList);
  597. const
  598. ASETextureMapKinds: array [TASETextureMap] of string = (
  599. ASCII_MAP_GENERIC_S,
  600. ASCII_MAP_AMBIENT_S,
  601. ASCII_MAP_DIFFUSE_S,
  602. ASCII_MAP_SPECULAR_S,
  603. ASCII_MAP_SHINE_S,
  604. ASCII_MAP_SHINESTRENGTH_S,
  605. ASCII_MAP_SELFILLUM_S,
  606. ASCII_MAP_OPACITY_S,
  607. ASCII_MAP_FILTERCOLOR_S,
  608. ASCII_MAP_BUMP_S,
  609. ASCII_MAP_REFLECT_S,
  610. ASCII_MAP_REFRACT_S);
  611. function FindTextureMap(aMaterial: TGLASEMaterial; aMapKind: string; aSubmaterialIndex: Integer;
  612. out TM: TGLASEMaterialTextureMap): Boolean;
  613. function FindInMaps(const aMaps: TGLASEMaterialTextureMaps): Boolean;
  614. var
  615. i: Integer;
  616. begin
  617. Result := False;
  618. for i := 0 to aMaps.Count - 1 do
  619. if aMaps.Map[i].Kind = aMapKind then begin
  620. TM := aMaps.Map[i];
  621. Result := True;
  622. Break;
  623. end;
  624. end;
  625. begin
  626. if aSubmaterialIndex = -1 then
  627. Result := FindInMaps(aMaterial.TextureMaps)
  628. else
  629. if aSubmaterialIndex < aMaterial.SubMaterials.Count then
  630. Result := FindInMaps(aMaterial.SubMaterials.SubMaterial[aSubmaterialIndex].TextureMaps)
  631. else
  632. Result := False;
  633. end;
  634. function GetOrAllocateMaterial(const aIndex, aSubID: Integer): string;
  635. var
  636. material : TGLASEMaterial;
  637. specColor : TGLVector;
  638. matLib : TGLMaterialLibrary;
  639. libMat : TGLLibMaterial;
  640. TM: TGLASEMaterialTextureMap;
  641. begin
  642. material := aASEMaterials[aIndex];
  643. Assert(Assigned(material));
  644. if Assigned(aMesh.Owner) and Assigned(aMesh.Owner.Owner) then begin
  645. matLib := aMesh.Owner.Owner.MaterialLibrary;
  646. if Assigned(matLib) then begin
  647. Result := material.Name + IntToStr(aIndex) + IntToStr(aSubID);
  648. libMat := matLib.Materials.GetLibMaterialByName(Result);
  649. if not Assigned(libMat) then begin
  650. libMat:=matLib.Materials.Add;
  651. libMat.Name := Result;
  652. with libMat.Material.FrontProperties do begin
  653. Ambient.Color:= VectorMake(material.Ambient, 1);
  654. Diffuse.Color:= VectorMake(material.Diffuse, 1);
  655. specColor := VectorMake(material.Specular, 1);
  656. ScaleVector(specColor, 1 - material.Shiness);
  657. Specular.Color:=specColor;
  658. Shininess:=MaxInteger(0, Integer(Round((1 - material.ShineStrength) * 128)));
  659. end;
  660. if FindTextureMap(material, ASETextureMapKinds[vPrepTexMap], vPrepTexSubM, TM) and (Trim(TM.Bitmap) <> '') then begin
  661. try
  662. with libMat.Material.Texture do begin
  663. Image.LoadFromFile(TM.Bitmap);
  664. Disabled:=False;
  665. TextureMode:=tmModulate;
  666. end;
  667. except
  668. on E: ETexture do begin
  669. if not aMesh.Owner.Owner.IgnoreMissingTextures then
  670. raise;
  671. end;
  672. end;
  673. end;
  674. end;
  675. end else Result:='';
  676. end else Result:='';
  677. end;
  678. function GetOrAllocateLightMap(const aIndex, aSubID: Integer) : Integer;
  679. var
  680. material : TGLASEMaterial;
  681. matLib : TGLMaterialLibrary;
  682. libMat : TGLLibMaterial;
  683. name: string;
  684. TM: TGLASEMaterialTextureMap;
  685. begin
  686. Result:=-1;
  687. material := aASEMaterials.Material[aIndex];
  688. name := material.Name + IntToStr(aIndex) + IntToStr(aSubID);
  689. Assert(Assigned(material));
  690. if Assigned(aMesh.Owner) and Assigned(aMesh.Owner.Owner) then begin
  691. matLib := aMesh.Owner.Owner.LightmapLibrary;
  692. if Assigned(matLib) then begin
  693. if FindTextureMap(material, ASETextureMapKinds[vPrepLightMap], vPrepLightSubM, TM) and (Trim(TM.Bitmap)<>'') then begin
  694. libMat:=matLib.Materials.GetLibMaterialByName(name);
  695. if not Assigned(libMat) then begin
  696. libMat:=matLib.Materials.Add;
  697. libMat.Name:=name;
  698. try
  699. with libMat.Material.Texture do begin
  700. Image.LoadFromFile(TM.Bitmap);
  701. Disabled:=False;
  702. TextureMode:=tmModulate;
  703. end;
  704. except
  705. on E: ETexture do begin
  706. if not aMesh.Owner.Owner.IgnoreMissingTextures then
  707. raise;
  708. end;
  709. end;
  710. end;
  711. Result:=libmat.Index;
  712. end;
  713. end;
  714. end;
  715. end;
  716. var
  717. vLastFG: TFGVertexIndexList;
  718. function GetFaceGroup(aMaterialID, aSubMaterialID: Integer): TFGVertexIndexList;
  719. var
  720. i: Integer;
  721. name: string;
  722. begin
  723. Result := nil;
  724. if aMaterialID >= 0 then
  725. name := aASEMaterials[aMaterialID].Name +
  726. IntToStr(aMaterialID) + IntToStr(aSubMaterialID)
  727. else
  728. name := '';
  729. if Assigned(vLastFG) and (vLastFG.MaterialName = name) then
  730. Result := vLastFG
  731. else begin
  732. vLastFG := nil;
  733. for i := 0 to aMesh.FaceGroups.Count - 1 do
  734. if aMesh.FaceGroups.Items[i].MaterialName = name then begin
  735. Result := TFGVertexIndexList(aMesh.FaceGroups.Items[i]);
  736. vLastFG := Result;
  737. Break;
  738. end;
  739. if not Assigned(Result) then begin
  740. Result := TFGVertexIndexList.CreateOwned(aMesh.FaceGroups);
  741. if aMaterialID > -1 then begin
  742. Result.MaterialName := GetOrAllocateMaterial(aMaterialID, aSubMaterialID);
  743. Result.LightMapIndex := GetOrAllocateLightMap(aMaterialID, aSubMaterialID);
  744. end;
  745. vLastFG := Result;
  746. end;
  747. end;
  748. end;
  749. var
  750. fg: TFGVertexIndexList;
  751. aseFace: TGLASEFace;
  752. i: Integer;
  753. norm, tex, light: Boolean;
  754. lmt: array [0..2] of TAffineVector;
  755. subID: Integer;
  756. vi: TIntegerList;
  757. begin
  758. norm := aASEMesh.HasNormals;
  759. tex := aASEMesh.TextChannelsCount > 0;
  760. light := tex and (aASEMesh.TextChannelsCount > 1);
  761. subID := -1;
  762. vi := TIntegerList.Create;
  763. if tex or norm then begin
  764. // here used NOT optimized storage
  765. aMesh.Mode := momFaceGroups;
  766. aMesh.Vertices.Capacity := aASEMesh.Faces.Count*3;
  767. if norm then
  768. aMesh.Normals.Capacity := aASEMesh.Faces.Count*3;
  769. if tex then
  770. aMesh.Normals.Capacity := aASEMesh.Faces.Count*3;
  771. vLastFG := nil;
  772. for i := 0 to aASEMesh.Faces.Count - 1 do begin
  773. aseFace := aASEMesh.Faces[i];
  774. fg := GetFaceGroup(aASEMesh.MaterialID, 0{aseFace.SubMaterialID});
  775. if (aseFace.SubMaterialID > -1) and (subID = -1) then
  776. subID := aseFace.SubMaterialID;
  777. aMesh.Vertices.Add(aASEMesh.Vertices[aseFace.VertIdx1],
  778. aASEMesh.Vertices[aseFace.VertIdx2],
  779. aASEMesh.Vertices[aseFace.VertIdx3]);
  780. if norm then
  781. aMesh.Normals.Add(aseFace.Normal1, aseFace.Normal2, aseFace.Normal3);
  782. if tex then begin
  783. Assert(aseFace.TextChannels.Count = aASEMesh.TextChannelsCount);
  784. aMesh.TexCoords.Add(aASEMesh.TextChannel[0][aseFace.TextChannels.ChanelTexture[0].Idx0],
  785. aASEMesh.TextChannel[0][aseFace.TextChannels.ChanelTexture[0].Idx1],
  786. aASEMesh.TextChannel[0][aseFace.TextChannels.ChanelTexture[0].Idx2]);
  787. if light then begin
  788. lmt[0] := aASEMesh.TextChannel[1][aseFace.TextChannels.ChanelTexture[1].Idx0];
  789. lmt[1] := aASEMesh.TextChannel[1][aseFace.TextChannels.ChanelTexture[1].Idx1];
  790. lmt[2] := aASEMesh.TextChannel[1][aseFace.TextChannels.ChanelTexture[1].Idx2];
  791. aMesh.LightMapTexCoords.Add(lmt[0].X, lmt[0].Y);
  792. aMesh.LightMapTexCoords.Add(lmt[1].X, lmt[1].Y);
  793. aMesh.LightMapTexCoords.Add(lmt[2].X, lmt[2].Y);
  794. end;
  795. end;
  796. fg.VertexIndices.Add(i*3 + 0, i*3 + 1, i*3 + 2);
  797. vi.Add(i*3 + 0, i*3 + 1, i*3 + 2);
  798. end;
  799. end else begin
  800. fg := TFGVertexIndexList.CreateOwned(aMesh.FaceGroups);
  801. aMesh.Vertices.Assign(aASEMesh.Vertices);
  802. aMesh.Mode := momTriangles;
  803. fg.VertexIndices.Capacity := aASEMesh.Faces.Count*3;
  804. for i := 0 to aASEMesh.Faces.Count - 1 do begin
  805. aseFace := aASEMesh.Faces[i];
  806. fg.VertexIndices.Add(aseFace.VertIdx1, aseFace.VertIdx2, aseFace.VertIdx3);
  807. end;
  808. end;
  809. // if ASE does not contain normals data we should build it automatically
  810. if aMesh.Normals.Count = 0 then
  811. aMesh.BuildNormals(vi, momTriangles);
  812. vi.Free;
  813. end;
  814. { TGLASEFace }
  815. constructor TGLASEFace.Create;
  816. begin
  817. FTextChannels.Count := 0;
  818. FSmoothing.Count := 0;
  819. end;
  820. { TGLASEFaceList }
  821. constructor TGLASEFaceList.Create;
  822. begin
  823. FItems := TList.Create;
  824. end;
  825. destructor TGLASEFaceList.Destroy;
  826. begin
  827. Clear;
  828. FreeAndNil(FItems);
  829. inherited;
  830. end;
  831. function TGLASEFaceList.Add: TGLASEFace;
  832. begin
  833. Result := TGLASEFace.Create;
  834. FItems.Add(Result);
  835. end;
  836. procedure TGLASEFaceList.Delete(aIndex: Integer);
  837. begin
  838. Face[aIndex].Free;
  839. FItems.Delete(aIndex);
  840. end;
  841. procedure TGLASEFaceList.Clear;
  842. var
  843. i: Integer;
  844. begin
  845. for i := 0 to Count - 1 do
  846. Face[i].Free;
  847. FItems.Clear;
  848. end;
  849. function TGLASEFaceList.GetFace(Index: Integer): TGLASEFace;
  850. begin
  851. Result := FItems[Index];
  852. end;
  853. function TGLASEFaceList.GetCount: Integer;
  854. begin
  855. Result := FItems.Count;
  856. end;
  857. { TGLASEMaterial }
  858. constructor TGLASEMaterial.Create;
  859. begin
  860. FSubMaterials.Count := 0;
  861. end;
  862. { TGLASEMeshObject }
  863. constructor TGLASEMeshObject.Create;
  864. begin
  865. FFaces := TGLASEFaceList.Create;
  866. FVertices := TAffineVectorList.Create;
  867. FTexChannelsCount := 0;
  868. FHasNormals := False;
  869. FMaterialID := -1;
  870. end;
  871. destructor TGLASEMeshObject.Destroy;
  872. var
  873. i: Integer;
  874. begin
  875. FreeAndNil(FFaces);
  876. FreeAndNil(FVertices);
  877. for i := 0 to FTexChannelsCount - 1 do
  878. FTexChannels[i].Free;
  879. inherited;
  880. end;
  881. function TGLASEMeshObject.AddTexChannel: TAffineVectorList;
  882. begin
  883. Assert(FTexChannelsCount < GL_ASE_MAX_TEXURE_CHANNELS, 'texture channels count maximum reached');
  884. Result := TAffineVectorList.Create;
  885. FTexChannels[FTexChannelsCount] := Result;
  886. Inc(FTexChannelsCount);
  887. end;
  888. function TGLASEMeshObject.GetTextChannel(Channel: Integer): TAffineVectorList;
  889. begin
  890. Result := FTexChannels[Channel];
  891. end;
  892. { TGLASEMaterialList }
  893. constructor TGLASEMaterialList.Create;
  894. begin
  895. FItems := TList.Create;
  896. end;
  897. destructor TGLASEMaterialList.Destroy;
  898. begin
  899. Clear;
  900. FreeAndNil(FItems);
  901. inherited;
  902. end;
  903. function TGLASEMaterialList.Add: TGLASEMaterial;
  904. begin
  905. Result := TGLASEMaterial.Create;
  906. FItems.Add(Result);
  907. end;
  908. procedure TGLASEMaterialList.Delete(aIndex: Integer);
  909. begin
  910. Material[aIndex].Free;
  911. FItems.Delete(aIndex);
  912. end;
  913. procedure TGLASEMaterialList.Clear;
  914. var
  915. i: Integer;
  916. begin
  917. for i := 0 to Count - 1 do
  918. Material[i].Free;
  919. FItems.Clear;
  920. end;
  921. function TGLASEMaterialList.GetMaterial(Index: Integer): TGLASEMaterial;
  922. begin
  923. Result := FItems[Index];
  924. end;
  925. function TGLASEMaterialList.GetCount: Integer;
  926. begin
  927. Result := FItems.Count;
  928. end;
  929. { TGLASEVectorFile }
  930. constructor TGLASEVectorFile.Create;
  931. begin
  932. inherited;
  933. FStringData := TStringList.Create;
  934. FMaterialList := TGLASEMaterialList.Create;
  935. end;
  936. destructor TGLASEVectorFile.Destroy;
  937. begin
  938. FMaterialList.Free;
  939. FStringData.Free;
  940. inherited;
  941. end;
  942. class function TGLASEVectorFile.Capabilities: TGLDataFileCapabilities;
  943. begin
  944. Result := [dfcRead];
  945. end;
  946. procedure TGLASEVectorFile.LoadFromStream(aStream: TStream);
  947. begin
  948. FStringData.LoadFromStream(aStream);
  949. Parse;
  950. end;
  951. function TGLASEVectorFile.ContainString(const aData, aString: string): Boolean;
  952. begin
  953. Result := (Length(aData) >= Length(aString)) and (Pos(AString, aData) > 0);
  954. end;
  955. function TGLASEVectorFile.GetDoubleValue(const aData: string): Double;
  956. var
  957. Start: Integer;
  958. Data: string;
  959. Value: string;
  960. begin
  961. Start := GetEndOfFirstValue(aData);
  962. Data := Copy(aData, Start, Length(aData) - Start + 1);
  963. Value := GetFirstValue(Data);
  964. Result := StringToFloatRegular(Value);
  965. end;
  966. function TGLASEVectorFile.GetEndOfFirstValue(const aData: string): Integer;
  967. var
  968. Value: string;
  969. begin
  970. Value := GetFirstValue(aData);
  971. Result := Pos(Value, aData) + Length(Value);
  972. end;
  973. function TGLASEVectorFile.GetFirstValue(aData: string): string;
  974. const
  975. sep1 = #32;
  976. var
  977. Index: Integer;
  978. start, ending: Integer;
  979. begin
  980. ChangeTabToSpace(aData);
  981. start := 1;
  982. ending := Length(aData);
  983. // getting start
  984. for Index := 1 to Length(aData) do
  985. if aData[Index] <> sep1 then begin
  986. start := Index;
  987. Break;
  988. end;
  989. // getting ending
  990. Result :='';
  991. for Index := start to Length(aData) do
  992. if aData[Index] = sep1 then begin
  993. ending := Index;
  994. Break;
  995. end;
  996. if ending = Length(aData) then
  997. Inc(ending);
  998. Result := Copy(aData, start, ending - start);
  999. end;
  1000. function TGLASEVectorFile.GetPropCastShadow(const aData: string): Boolean;
  1001. begin
  1002. Result := Pos('1', aData) > 0;
  1003. end;
  1004. function TGLASEVectorFile.GetPropMBlur(const aData: string): Boolean;
  1005. begin
  1006. Result := Pos('1', aData) > 0;
  1007. end;
  1008. function TGLASEVectorFile.GetPropRECVShadow(const aData: string): Boolean;
  1009. begin
  1010. Result := Pos('1', aData) > 0;
  1011. end;
  1012. function TGLASEVectorFile.GetStringValue(const aData: string): string;
  1013. const
  1014. Breaker = '"';
  1015. var
  1016. Start: Integer;
  1017. begin
  1018. Start := Pos(Breaker, aData) + 1;
  1019. Result := Copy(aData, Start, Length(aData) - Start);
  1020. end;
  1021. function TGLASEVectorFile.GetTagOnData(const aData: string): Integer;
  1022. var
  1023. Index: Integer;
  1024. begin
  1025. Result := -1;
  1026. for Index := High(vTagIdx) downto Low(vTagIdx) do
  1027. if ContainString(aData, vTagIdx[Index].Name) then begin
  1028. Result := vTagIdx[Index].Idx;
  1029. Break;
  1030. end;
  1031. end;
  1032. function TGLASEVectorFile.GetValue3D(const aData: string): TAffineVector;
  1033. var
  1034. Start: Integer;
  1035. Data: string;
  1036. Value: String;
  1037. begin
  1038. Data := aData;
  1039. Start := GetEndOfFirstValue(Data);
  1040. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1041. Value := GetFirstValue(Data);
  1042. Result.X := StringToFloatRegular(Value);
  1043. Start := GetEndOfFirstValue(Data) + 1;
  1044. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1045. Value := GetFirstValue(Data);
  1046. Result.Y := StringToFloatRegular(Value);
  1047. Start := GetEndOfFirstValue(Data) + 1;
  1048. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1049. Value := GetFirstValue(Data);
  1050. Result.Z := StringToFloatRegular(Value);
  1051. end;
  1052. function TGLASEVectorFile.GetValue4D(const aData: string; var Value0: Integer): TAffineVector;
  1053. var
  1054. Start: Integer;
  1055. Data: string;
  1056. Value: String;
  1057. begin
  1058. Data := aData;
  1059. Value0 := Round(GetDoubleValue(aData));
  1060. Start := GetEndOfFirstValue(Data) + 1;
  1061. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1062. Start := GetEndOfFirstValue(Data) + 1;
  1063. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1064. Value := GetFirstValue(Data);
  1065. Result.X := StringToFloatRegular(Value);
  1066. Start := GetEndOfFirstValue(Data) + 1;
  1067. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1068. Value := GetFirstValue(Data);
  1069. Result.Y := StringToFloatRegular(Value);
  1070. Start := GetEndOfFirstValue(Data) + 1;
  1071. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1072. Value := GetFirstValue(Data);
  1073. Result.Z := StringToFloatRegular(Value);
  1074. end;
  1075. function TGLASEVectorFile.IsEndOfSection(const aData: string): Boolean;
  1076. begin
  1077. if AData[1] = '}' then begin
  1078. Result := True;
  1079. end else begin
  1080. Result := Pos('}', aData) > 0;
  1081. end;
  1082. end;
  1083. function TGLASEVectorFile.IsSectionBegingin(const aData: string): Boolean;
  1084. begin
  1085. Result := Pos('{', aData) > 0;
  1086. end;
  1087. function TGLASEVectorFile.CheckUnknownData(var aLineIndex: Integer): Boolean;
  1088. begin
  1089. Result := IsSectionBegingin(FStringData[aLineIndex]);
  1090. if Result then begin
  1091. SkipSection(aLineIndex);
  1092. end else
  1093. Inc(aLineIndex);
  1094. end;
  1095. procedure TGLASEVectorFile.SkipSection(var aLineIndex: Integer);
  1096. var
  1097. Data: string;
  1098. begin
  1099. Inc(aLineIndex);
  1100. Data := FStringData[aLineIndex];
  1101. while not IsEndOfSection(Data) do begin
  1102. CheckUnknownData(aLineIndex);
  1103. Data := FStringData[aLineIndex];
  1104. end;
  1105. Inc(aLineIndex);
  1106. end;
  1107. procedure TGLASEVectorFile.Parse;
  1108. var
  1109. LineIndex: Integer;
  1110. Data: string;
  1111. b: Boolean;
  1112. begin
  1113. LineIndex := 0;
  1114. while LineIndex < FStringData.Count do begin
  1115. Data := FStringData[LineIndex];
  1116. b := IsSectionBegingin(Data);
  1117. case GetTagOnData(Data) of
  1118. ASCII_COMMENT_I: FComment := GetStringValue(Data);
  1119. ASCII_SCENE_I: ParseScene(LineIndex);
  1120. ASCII_GEOMOBJECT_I: ParseGeomObject(LineIndex);
  1121. ASCII_PROP_MOTION_BLUR_I: FMotionBlur := GetPropMBlur(Data);
  1122. ASCII_PROP_CAST_SHADOW_I: FCastShadow := GetPropCastShadow(Data);
  1123. ASCII_PROP_RECV_SHADOW_I: FRECVShadow := GetPropRECVShadow(Data);
  1124. ASCII_MATERIAL_LIST_I: ParseMaterialList(LineIndex);
  1125. else begin
  1126. if LineIndex = 0 then
  1127. FHeader := Data;
  1128. b := True;
  1129. CheckUnknownData(LineIndex);
  1130. end;
  1131. end;
  1132. if not b then
  1133. Inc(LineIndex);
  1134. end;
  1135. end;
  1136. procedure TGLASEVectorFile.ParseFaceString(const aData: string; var Index, A, B, C, AB, BC, CA, MatID: Integer;
  1137. var Smooth: TGLASESmoothingGroups);
  1138. var
  1139. Data: string;
  1140. Start: Integer;
  1141. Value: string;
  1142. function GetNextValueStr: string;
  1143. begin
  1144. Start := GetEndOfFirstValue(Data);
  1145. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1146. Start := GetEndOfFirstValue(Data);
  1147. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1148. Result := GetFirstValue(Data);
  1149. end;
  1150. function GetNextValue: Integer;
  1151. begin
  1152. Result := StrToInt(GetNextValueStr);
  1153. end;
  1154. function GetLastValue: Integer;
  1155. begin
  1156. Start := GetEndOfFirstValue(Data);
  1157. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1158. Result := StrToInt(GetFirstValue(Data));
  1159. end;
  1160. procedure GetNextValues(var aValues: TGLASESmoothingGroups);
  1161. procedure iAdd(aIdx: Integer);
  1162. begin
  1163. aValues.Groups[aValues.Count] := aIdx;
  1164. Inc(aValues.Count);
  1165. end;
  1166. const
  1167. sep = ',';
  1168. var
  1169. v, sub: string;
  1170. p: Integer;
  1171. begin
  1172. v := GetNextValueStr;
  1173. if Trim(v) = '' then
  1174. Exit;
  1175. p := Pos(sep, v);
  1176. if (p = 0) and (StrToIntDef(v, -1) = -1) then
  1177. Exit;
  1178. while p > 0 do begin
  1179. aValues.Count := 0;
  1180. sub := Copy(v, 1, p - 1);
  1181. iAdd(StrToInt(sub));
  1182. v := Copy(v, p + 1, Length(v));
  1183. p := Pos(sep, v);
  1184. end;
  1185. iAdd(StrToInt(v));
  1186. end;
  1187. begin
  1188. Data := aData;
  1189. Start := GetEndOfFirstValue(Data);
  1190. Data := Copy(Data, Start, Length(Data) - Start + 1);
  1191. // Index
  1192. Value := GetFirstValue(Data);
  1193. Value := Copy(Value, 1, Length(Value) - 1);
  1194. Index := StrToInt(Value);
  1195. A := GetNextValue;
  1196. B := GetNextValue;
  1197. C := GetNextValue;
  1198. AB := GetNextValue;
  1199. BC := GetNextValue;
  1200. CA := GetNextValue;
  1201. if Pos(ASCII_MESH_SMOOTHING_S, Data) > 0 then
  1202. GetNextValues(Smooth);
  1203. if Pos(ASCII_MESH_MTLID_S, Data) > 0 then begin
  1204. if Smooth.Count > 0 then
  1205. MatID := GetNextValue
  1206. else
  1207. MatID := GetLastValue;
  1208. end;
  1209. end;
  1210. procedure TGLASEVectorFile.ParseGeomObject(var aLineIndex: Integer);
  1211. var
  1212. aseMesh: TGLASEMeshObject;
  1213. obj: TMeshObject;
  1214. Data: string;
  1215. b: Boolean;
  1216. begin
  1217. aseMesh := TGLASEMeshObject.Create;
  1218. try
  1219. obj := TMeshObject.CreateOwned(Owner.MeshObjects);
  1220. Inc(aLineIndex);
  1221. Data := FStringData[aLineIndex];
  1222. while not IsEndOfSection(Data) do begin
  1223. b := IsSectionBegingin(Data);
  1224. case GetTagOnData(Data) of
  1225. ASCII_NODE_NAME_I: obj.Name := GetStringValue(Data);
  1226. ASCII_NODE_TM_I: ParseMeshOptions(aLineIndex, aseMesh);
  1227. ASCII_MESH_I: ParseMeshGeom(aLineIndex, aseMesh);
  1228. ASCII_MATERIAL_REF_I: aseMesh.FMaterialID := Round(GetDoubleValue(Data));
  1229. else begin
  1230. b := True;
  1231. CheckUnknownData(aLineIndex);
  1232. end;
  1233. end;
  1234. if not b then
  1235. Inc(aLineIndex);
  1236. Data := FStringData[aLineIndex];
  1237. end;
  1238. CopyASEToMesh(aseMesh, obj, FMaterialList);
  1239. finally
  1240. aseMesh.Free;
  1241. end;
  1242. Inc(aLineIndex);
  1243. end;
  1244. procedure TGLASEVectorFile.ParseMeshFaces(var aLineIndex: Integer; aMesh: TGLASEMeshObject; FacesCount: Integer);
  1245. var
  1246. Data: string;
  1247. Index, A, B, C, AB, BC, CA, ID: Integer;
  1248. face: TGLASEFace;
  1249. smooth: TGLASESmoothingGroups;
  1250. begin
  1251. Inc(aLineIndex);
  1252. Data := FStringData[aLineIndex];
  1253. while not IsEndOfSection(Data) do begin
  1254. smooth.Count := 0;
  1255. ID := -1;
  1256. ParseFaceString(Data, Index, A, B, C, AB, BC, CA, ID, smooth);
  1257. Assert(Index = aMesh.Faces.Count, 'unexpexted unsorted faces');
  1258. face := aMesh.Faces.Add;
  1259. face.FV[0] := A;
  1260. face.FV[1] := B;
  1261. face.FV[2] := C;
  1262. face.FSmoothing := smooth;
  1263. // face.AB := AB;
  1264. // face.BC := BC;
  1265. // face.CA := CA;
  1266. // face.FSmoothing := Smooth;
  1267. face.FSubMaterialID := ID;
  1268. CheckUnknownData(aLineIndex);
  1269. Data := FStringData[aLineIndex];
  1270. end;
  1271. Inc(aLineIndex);
  1272. end;
  1273. procedure TGLASEVectorFile.ParseMeshNormals(var aLineIndex: Integer; aMesh: TGLASEMeshObject; FacesCount: Integer);
  1274. var
  1275. Data: string;
  1276. Index: Integer;
  1277. Counter: Integer;
  1278. face: TGLASEFace;
  1279. Normal: TAffineVector;
  1280. begin
  1281. aMesh.FHasNormals := True;
  1282. Inc(aLineIndex);
  1283. Data := FStringData[aLineIndex];
  1284. Counter := 0;
  1285. face := nil;
  1286. while not IsEndOfSection(Data) do begin
  1287. if Counter = 0 then begin
  1288. Normal := GetValue4D(Data, Index);
  1289. face := aMesh.Faces[Index];
  1290. face.FNormal := Normal;
  1291. Inc(Counter);
  1292. end else begin
  1293. Assert(Assigned(face));
  1294. Normal := GetValue4D(Data, Index);
  1295. Assert(face.FV[Counter - 1] = Index);
  1296. face.FN[Counter - 1] := Normal;
  1297. if Counter = 3 then begin
  1298. Counter := 0;
  1299. face := nil;
  1300. end else
  1301. Inc(Counter);
  1302. end;
  1303. CheckUnknownData(aLineIndex);
  1304. Data := FStringData[ALineIndex];
  1305. end;
  1306. Inc(aLineIndex);
  1307. end;
  1308. procedure TGLASEVectorFile.ParseMeshTextureFaces(var aLineIndex: Integer; aMesh: TGLASEMeshObject;
  1309. TextureFacesCount: Integer);
  1310. var
  1311. Data: string;
  1312. faceIndex: Integer;
  1313. face: TGLASEFace;
  1314. v3D: TAffineVector;
  1315. chanelIdx: Integer;
  1316. begin
  1317. Inc(aLineIndex);
  1318. Data := FStringData[aLineIndex];
  1319. while not IsEndOfSection(Data) do begin
  1320. v3D := GetValue4D(Data, faceIndex);
  1321. face := aMesh.Faces[faceIndex];
  1322. chanelIdx := face.FTextChannels.Count;
  1323. face.FTextChannels.ChanelTexture[chanelIdx].Idx0 := Round(v3D.X);
  1324. face.FTextChannels.ChanelTexture[chanelIdx].Idx1 := Round(v3D.Y);
  1325. face.FTextChannels.ChanelTexture[chanelIdx].Idx2 := Round(v3D.Z);
  1326. Inc(face.FTextChannels.Count);
  1327. CheckUnknownData(aLineIndex);
  1328. Data := FStringData[aLineIndex];
  1329. end;
  1330. Inc(aLineIndex);
  1331. end;
  1332. procedure TGLASEVectorFile.ParseMeshTextureVertices(var aLineIndex: Integer; aMesh: TGLASEMeshObject;
  1333. TextureVerticesCount: Integer);
  1334. var
  1335. Data: string;
  1336. Index: Integer;
  1337. channel: TAffineVectorList;
  1338. begin
  1339. Inc(aLineIndex);
  1340. Data := FStringData[aLineIndex];
  1341. channel := aMesh.AddTexChannel;
  1342. while not IsEndOfSection(Data) do begin
  1343. channel.Add(GetValue4D(Data, Index));
  1344. Assert(Index = (channel.Count - 1), 'unexpected unsorted texture coordinates');
  1345. CheckUnknownData(aLineIndex);
  1346. Data := FStringData[aLineIndex];
  1347. end;
  1348. Inc(aLineIndex);
  1349. end;
  1350. procedure TGLASEVectorFile.ParseMeshGeom(var aLineIndex: Integer; aMesh: TGLASEMeshObject);
  1351. var
  1352. Data: string;
  1353. VerticesCount: Integer;
  1354. FacesCount: Integer;
  1355. TextureVerticesCount: Integer;
  1356. TextureFacesCount: Integer;
  1357. b: Boolean;
  1358. begin
  1359. VerticesCount := 0;
  1360. FacesCount := 0;
  1361. TextureVerticesCount := 0;
  1362. TextureFacesCount := 0;
  1363. Inc(aLineIndex);
  1364. Data := FStringData[aLineIndex];
  1365. while not IsEndOfSection(Data) do begin
  1366. b := IsSectionBegingin(Data);
  1367. case GetTagOnData(Data) of
  1368. ASCII_TIMEVALUE_I: ; //aMesh.TimeValue := Round(GetDoubleValue(Data));
  1369. ASCII_MESH_NUM_VERTEX_I: VerticesCount := Round(GetDoubleValue(Data));
  1370. ASCII_NUM_FACES_I: FacesCount := Round(GetDoubleValue(Data));
  1371. ASCII_VERTEX_LIST_I: ParseMeshVertices(aLineIndex, aMesh, VerticesCount);
  1372. ASCII_MESH_FACE_LIST_I: ParseMeshFaces(aLineIndex, aMesh, FacesCount);
  1373. ASCII_MESH_NORMALS_I: ParseMeshNormals(aLineIndex, aMesh, FacesCount);
  1374. ASCII_MESH_NUMTVERTEX_I: TextureVerticesCount := Round(GetDoubleValue(Data));
  1375. ASCII_MESH_TVERTLIST_I: ParseMeshTextureVertices(aLineIndex, aMesh, TextureVerticesCount);
  1376. ASCII_MESH_NUMTVFACES_I: TextureFacesCount := Round(GetDoubleValue(Data));
  1377. ASCII_MESH_TFACELIST_I: ParseMeshTextureFaces(aLineIndex, aMesh, TextureFacesCount);
  1378. ASCII_MESH_MAPPINGCHANNEL_I: ParseMappingChannel(aLineIndex, aMesh);
  1379. else begin
  1380. b := True;
  1381. CheckUnknownData(aLineIndex);
  1382. end;
  1383. end;
  1384. if not b then
  1385. Inc(aLineIndex);
  1386. Data := FStringData[aLineIndex];
  1387. end;
  1388. Inc(aLineIndex);
  1389. end;
  1390. procedure TGLASEVectorFile.ParseMeshVertices(var aLineIndex: Integer; aMesh: TGLASEMeshObject;
  1391. VerticesCount: Integer);
  1392. var
  1393. Data: string;
  1394. VertIndex: Integer;
  1395. begin
  1396. Inc(aLineIndex);
  1397. Data := FStringData[aLineIndex];
  1398. while not IsEndOfSection(Data) do begin
  1399. aMesh.Vertices.Add(GetValue4D(Data, VertIndex));
  1400. Assert(VertIndex = (aMesh.Vertices.Count - 1), 'unexpeted unsorted vertices');
  1401. CheckUnknownData(aLineIndex);
  1402. Data := FStringData[aLineIndex];
  1403. end;
  1404. Inc(aLineIndex);
  1405. end;
  1406. procedure TGLASEVectorFile.ParseMappingChannel(var aLineIndex: Integer; aMesh: TGLASEMeshObject);
  1407. var
  1408. Data: string;
  1409. TextureVerticesCount: Integer;
  1410. TextureFacesCount: Integer;
  1411. b: Boolean;
  1412. begin
  1413. TextureVerticesCount := 0;
  1414. TextureFacesCount := 0;
  1415. Inc(aLineIndex);
  1416. Data := FStringData[aLineIndex];
  1417. while not IsEndOfSection(Data) do begin
  1418. b := IsSectionBegingin(Data);
  1419. case GetTagOnData(Data) of
  1420. ASCII_MESH_NUMTVERTEX_I: TextureVerticesCount := Round(GetDoubleValue(Data));
  1421. ASCII_MESH_TVERTLIST_I: ParseMeshTextureVertices(aLineIndex, aMesh, TextureVerticesCount);
  1422. ASCII_MESH_NUMTVFACES_I: TextureFacesCount := Round(GetDoubleValue(Data));
  1423. ASCII_MESH_TFACELIST_I: ParseMeshTextureFaces(aLineIndex, aMesh, TextureFacesCount);
  1424. else begin
  1425. b := True;
  1426. CheckUnknownData(aLineIndex);
  1427. end;
  1428. end;
  1429. if not b then
  1430. Inc(aLineIndex);
  1431. Data := FStringData[aLineIndex];
  1432. end;
  1433. Inc(aLineIndex);
  1434. end;
  1435. procedure TGLASEVectorFile.ParseMeshOptions(var aLineIndex: Integer; aMesh: TGLASEMeshObject);
  1436. var
  1437. Data: string;
  1438. b: Boolean;
  1439. begin
  1440. Inc(aLineIndex);
  1441. Data := FStringData[aLineIndex];
  1442. while not IsEndOfSection(Data) do begin
  1443. b := IsSectionBegingin(Data);
  1444. case GetTagOnData(Data) of
  1445. ASCII_INHERIT_POS_I: aMesh.FInheritedPosition := GetValue3D(Data);
  1446. ASCII_INHERIT_ROT_I: aMesh.FInheritedRotation := GetValue3D(Data);
  1447. ASCII_INHERIT_SCL_I: aMesh.FInheritedScale := GetValue3D(Data);
  1448. ASCII_ROW_I: aMesh.FMatrix.V[0] := VectorMake(GetValue3D(Data));
  1449. ASCII_ROW1_I: aMesh.FMatrix.V[1] := VectorMake(GetValue3D(Data));
  1450. ASCII_ROW2_I: aMesh.FMatrix.V[2] := VectorMake(GetValue3D(Data));
  1451. ASCII_ROW3_I: aMesh.FMatrix.V[3] := PointMake(GetValue3D(Data));
  1452. ASCII_POS_I: aMesh.FPosition := PointMake(GetValue3D(Data));
  1453. ASCII_ROTAXIS_I: aMesh.FRotationAxis := GetValue3D(Data);
  1454. ASCII_ROTANGLE_I: aMesh.FRotationAngle := GetDoubleValue(Data);
  1455. ASCII_SCALE_I: aMesh.FScale := GetValue3D(Data);
  1456. ASCII_SCALEAXIS_I: aMesh.FScaleAxis := GetValue3D(Data);
  1457. ASCII_SCALEAXISANG_I: aMesh.FScaleAxisAngle := GetDoubleValue(Data);
  1458. else begin
  1459. b := True;
  1460. CheckUnknownData(aLineIndex);
  1461. end;
  1462. end;
  1463. if not b then
  1464. Inc(aLineIndex);
  1465. Data := FStringData[aLineIndex];
  1466. end;
  1467. Inc(aLineIndex);
  1468. end;
  1469. procedure TGLASEVectorFile.ParseScene(var aLineIndex: Integer);
  1470. begin
  1471. CheckUnknownData(aLineIndex);
  1472. end;
  1473. procedure TGLASEVectorFile.ParseMaterialList(var aLineIndex: Integer);
  1474. var
  1475. Data: string;
  1476. material: TGLASEMaterial;
  1477. begin
  1478. Inc(aLineIndex);
  1479. Data := FStringData[aLineIndex];
  1480. while not IsEndOfSection(Data) do begin
  1481. case GetTagOnData(Data) of
  1482. ASCII_MATERIAL_I: begin
  1483. material := FMaterialList.Add;
  1484. ParseMaterial(aLineIndex, material);
  1485. end; else begin
  1486. CheckUnknownData(aLineIndex);
  1487. end;
  1488. end;
  1489. Data := FStringData[aLineIndex];
  1490. end;
  1491. Inc(aLineIndex);
  1492. end;
  1493. function TGLASEVectorFile.CheckTextureMap(var aLineIndex: Integer; var aMaps: TGLASEMaterialTextureMaps): Boolean;
  1494. var
  1495. Data: string;
  1496. begin
  1497. Result := True;
  1498. Data := FStringData[aLineIndex];
  1499. case GetTagOnData(Data) of
  1500. ASCII_MAP_AMBIENT_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_AMBIENT_S);
  1501. ASCII_MAP_DIFFUSE_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_DIFFUSE_S);
  1502. ASCII_MAP_GENERIC_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_GENERIC_S);
  1503. ASCII_MAP_SPECULAR_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_SPECULAR_S);
  1504. ASCII_MAP_SHINE_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_SHINE_S);
  1505. ASCII_MAP_SHINESTRENGTH_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_SHINESTRENGTH_S);
  1506. ASCII_MAP_SELFILLUM_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_SELFILLUM_S);
  1507. ASCII_MAP_OPACITY_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_OPACITY_S);
  1508. ASCII_MAP_FILTERCOLOR_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_FILTERCOLOR_S);
  1509. ASCII_MAP_BUMP_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_BUMP_S);
  1510. ASCII_MAP_REFLECT_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_REFLECT_S);
  1511. ASCII_MAP_REFRACT_I: ParseTextureMap(aLineIndex, aMaps, ASCII_MAP_REFRACT_S);
  1512. else
  1513. Result := False;
  1514. end;
  1515. end;
  1516. procedure TGLASEVectorFile.ParseMaterial(var aLineIndex: Integer; aMaterial: TGLASEMaterial);
  1517. var
  1518. Data: string;
  1519. b: Boolean;
  1520. begin
  1521. Inc(aLineIndex);
  1522. Data := FStringData[aLineIndex];
  1523. while not IsEndOfSection(Data) do begin
  1524. b := IsSectionBegingin(Data);
  1525. case GetTagOnData(Data) of
  1526. ASCII_MATERIAL_NAME_I: aMaterial.FName := GetStringValue(Data);
  1527. ASCII_MATERIAL_AMBIENT_I: aMaterial.FAmbient := GetValue3D(Data);
  1528. ASCII_MATERIAL_DIFFUSE_I: aMaterial.FDiffuse := GetValue3D(Data);
  1529. ASCII_MATERIAL_SPECULAR_I: aMaterial.FSpecular := GetValue3D(Data);
  1530. ASCII_MATERIAL_SHINE_I: aMaterial.FShiness := GetDoubleValue(Data);
  1531. ASCII_MATERIAL_SHINESTRENGTH_I: aMaterial.FShineStrength := GetDoubleValue(Data);
  1532. ASCII_MATERIAL_TRANSPARENCY_I: aMaterial.FTransparency := GetDoubleValue(Data);
  1533. ASCII_MATERIAL_WIRESIZE_I: aMaterial.FWireSize := GetDoubleValue(Data);
  1534. ASCII_SUBMATERIAL_I: ParseSubMaterial(aLineIndex, aMaterial);
  1535. else
  1536. if not CheckTextureMap(aLineIndex, aMaterial.FTextureMaps) then begin
  1537. b := True;
  1538. CheckUnknownData(aLineIndex);
  1539. end;
  1540. end;
  1541. if not b then
  1542. Inc(aLineIndex);
  1543. Data := FStringData[aLineIndex];
  1544. end;
  1545. Inc(aLineIndex);
  1546. end;
  1547. procedure TGLASEVectorFile.ParseSubMaterial(var aLineIndex: Integer; aMaterial: TGLASEMaterial);
  1548. var
  1549. Data: string;
  1550. Index: Integer;
  1551. b: Boolean;
  1552. begin
  1553. Index := aMaterial.FSubMaterials.Count;
  1554. Inc(aMaterial.FSubMaterials.Count);
  1555. Inc(aLineIndex);
  1556. Data := FStringData[aLineIndex];
  1557. while not IsEndOfSection(Data) do begin
  1558. b := IsSectionBegingin(Data);
  1559. case GetTagOnData(Data) of
  1560. ASCII_MATERIAL_NAME_I: aMaterial.FSubMaterials.SubMaterial[Index].Name := GetStringValue(Data);
  1561. ASCII_MATERIAL_AMBIENT_I: aMaterial.FSubMaterials.SubMaterial[Index].Ambient := GetValue3D(Data);
  1562. ASCII_MATERIAL_DIFFUSE_I: aMaterial.FSubMaterials.SubMaterial[Index].Diffuse := GetValue3D(Data);
  1563. ASCII_MATERIAL_SPECULAR_I: aMaterial.FSubMaterials.SubMaterial[Index].Specular := GetValue3D(Data);
  1564. ASCII_MATERIAL_SHINE_I: aMaterial.FSubMaterials.SubMaterial[Index].Shiness := GetDoubleValue(Data);
  1565. ASCII_MATERIAL_SHINESTRENGTH_I: aMaterial.FSubMaterials.SubMaterial[Index].ShineStrength := GetDoubleValue(Data);
  1566. ASCII_MATERIAL_TRANSPARENCY_I: aMaterial.FSubMaterials.SubMaterial[Index].Transparency := GetDoubleValue(Data);
  1567. ASCII_MATERIAL_WIRESIZE_I: aMaterial.FSubMaterials.SubMaterial[Index].WireSize := GetDoubleValue(Data);
  1568. ASCII_MATERIAL_SELFILLUM_I: aMaterial.FSubMaterials.SubMaterial[Index].SelfIllumination := GetDoubleValue(Data);
  1569. else
  1570. if not CheckTextureMap(aLineIndex, aMaterial.FSubMaterials.SubMaterial[Index].TextureMaps) then begin
  1571. b := True;
  1572. CheckUnknownData(aLineIndex);
  1573. end;
  1574. end;
  1575. if not b then
  1576. Inc(aLineIndex);
  1577. Data := FStringData[aLineIndex];
  1578. end;
  1579. Inc(aLineIndex);
  1580. end;
  1581. procedure TGLASEVectorFile.ParseTextureMap(var aLineIndex: Integer; var aMaps: TGLASEMaterialTextureMaps; const aMapKind: string);
  1582. var
  1583. Data: string;
  1584. Index: Integer;
  1585. b: Boolean;
  1586. begin
  1587. Index := aMaps.Count;
  1588. Inc(aMaps.Count);
  1589. aMaps.Map[Index].Kind := aMapKind;
  1590. Inc(aLineIndex);
  1591. Data := FStringData[aLineIndex];
  1592. while not IsEndOfSection(Data) do begin
  1593. b := IsSectionBegingin(Data);
  1594. case GetTagOnData(Data) of
  1595. ASCII_MAP_NAME_I: aMaps.Map[Index].Name := GetStringValue(Data);
  1596. ASCII_MAP_CLASS_I: aMaps.Map[Index]._Class := GetStringValue(Data);
  1597. ASCII_MAP_SUBNO_I: aMaps.Map[Index].No := Round(GetDoubleValue(Data));
  1598. ASCII_MAP_AMOUNT_I: aMaps.Map[Index].Amount := GetDoubleValue(Data);
  1599. ASCII_BITMAP_I: aMaps.Map[Index].Bitmap := GetStringValue(Data);
  1600. ASCII_UVW_U_OFFSET_I: aMaps.Map[Index].UOffset := GetDoubleValue(Data);
  1601. ASCII_UVW_V_OFFSET_I: aMaps.Map[Index].VOffset := GetDoubleValue(Data);
  1602. ASCII_UVW_U_TILING_I: aMaps.Map[Index].UTiling := GetDoubleValue(Data);
  1603. ASCII_UVW_V_TILING_I: aMaps.Map[Index].VTiling := GetDoubleValue(Data);
  1604. ASCII_UVW_ANGLE_I: aMaps.Map[Index].Angle := GetDoubleValue(Data);
  1605. ASCII_UVW_BLUR_I: aMaps.Map[Index].Blur := GetDoubleValue(Data);
  1606. ASCII_UVW_BLUR_OFFSET_I: aMaps.Map[Index].BlurOffset := GetDoubleValue(Data);
  1607. ASCII_UVW_NOUSE_AMT_I: aMaps.Map[Index].NouseAmount := GetDoubleValue(Data);
  1608. ASCII_UVW_NOISE_SIZE_I: aMaps.Map[Index].NoiseSize := GetDoubleValue(Data);
  1609. ASCII_UVW_NOISE_LEVEL_I: aMaps.Map[Index].NoiseLevel := Round(GetDoubleValue(Data));
  1610. ASCII_UVW_NOISE_PHASE_I: aMaps.Map[Index].NoisePhase := GetDoubleValue(Data);
  1611. else begin
  1612. b := True;
  1613. CheckUnknownData(aLineIndex);
  1614. end;
  1615. end;
  1616. if not b then
  1617. Inc(aLineIndex);
  1618. Data := FStringData[aLineIndex];
  1619. end;
  1620. Inc(aLineIndex);
  1621. end;
  1622. initialization
  1623. RegisterVectorFileFormat('ase', 'ASCII files', TGLASEVectorFile);
  1624. ASESetPreferredTexture(tmDiffuse);
  1625. ASESetPreferredLightmap(tmAmbient);
  1626. end.