GLFileASE.pas 61 KB

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