2
0

GLS.FileASE.pas 60 KB

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