2
0

GXS.FileASE.pas 60 KB

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