LZScene

Форк
0
/
GLFileLMTS.pas 
720 строк · 22.6 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
   History :  
6
   31/05/10 - Yar - Fixes for Linux x64
7
   22/01/10 - Yar - Added GLTextureFormat to uses
8
   25/07/07 - DaStr - Replaced some types to get rid of compiler warnings
9
   08/10/08 - DanB - fix for different Char size in Delphi 2009+
10
   22/06/08 - DaStr - Fixups after converting TGLMeshObject.LightMapTexCoords
11
  to TAffineVectorList (thanks Ast) (Bugtracker ID = 2000089)
12
   29/05/08 - DaStr - Replaced GLUtils with GLGraphics (BugTracker ID = 1923844)
13
  Added $I GLScene.inc
14
   13/08/07 - fig -  Added checks for DDS textures in LoadFromStream()
15
   23/03/07 - fig -  Fixed exception when material properties were loaded without a material library being assigned.
16
   15/01/07 - fig -  If available, material data is now imported/exported.
17
   15/01/07 - fig -  Added checks in the loader for invalid material indices.  LMTools can return meshes like this for some reason.
18
   14/01/07 - fig -  Material/facegroup name is now changed to the available filename instead of stripping the extention.
19
   12/01/07 - fig -  Fixed LoadFromStream() to handle duplicate and null textures correctly.
20
   07/01/07 - fig -  Fixed the file extention stripping. extra periods in the filenames were causing conflicts.
21
   06/01/07 - fig -  Strip all texture file extentions on load/save
22
   03/01/07 - fig -  can now use different texture types from the ones stated in the file,
23
  missing texture exception handling, normals are built on load,
24
  support for more facegroup types added.
25
   02/01/07 - fig - Added SavetoStream() and Capabilities function.
26
   02/01/07 - PvD - Dealing with non empty material libraries.
27
   02/01/07 - PvD - Mirrored mesh in X to original orientation.
28
   01/01/07 - Dave Gravel - Modification to make it work.
29
   10/09/03 - Domin - Creation
30
   
31
}
32
unit GLFileLMTS;
33

34
interface
35

36
{$I GLScene.inc}
37

38
uses
39
  Graphics,
40
  Classes, SysUtils,
41
  GLVectorFileObjects, GLApplicationFileIO, GLVectorLists, GLVectorGeometry,
42
  GLTexture, GLPersistentClasses, GLGraphics, GLMaterial;
43

44
const
45
  C_LMTS_ID = $53544D4C;
46
  C_LMTS_VER = 4;
47
  C_LMTS_SUBS = $53425553;
48
  C_LMTS_TEXT = $54584554;
49
  C_LMTS_TRIS = $53495254;
50

51
  C_LMTS_TEXFNLEN = 255; // max texture filename length
52

53
type
54
  PLMTS_Header = ^TLMTS_Header;
55

56
  TLMTS_Header = record // packed
57
    ID: cardinal;
58
    Ver: cardinal;
59
    headerSize: cardinal;
60
    nTexts: word; // # of textures
61
    nSubsets: word;
62
    nTris: cardinal;
63
    subSize: word;
64
    vtxSize: word;
65
  end;
66

67
  PLMTS_TexData = ^TLMTS_TexData;
68

69
  TLMTS_TexData = record // packed
70
    fName: array [0 .. C_LMTS_TEXFNLEN] of ansichar;
71
    Flags: word;
72
  end;
73

74
  PLMTS_Subset = ^TLMTS_Subset;
75

76
  TLMTS_Subset = record // packed
77
    Offset: longint;
78
    Count: longint;
79
    TextID1: word;
80
    TextID2: word;
81
  end;
82

83
  PLMTS_Vertex = ^TLMTS_Vertex;
84

85
  TLMTS_Vertex = record // packed
86
    x, y, z: single;
87
    u1, v1, u2, v2: single;
88
  end;
89

90
  PLMTS = ^TLMTS;
91

92
  TLMTS = record
93
    header: TLMTS_Header;
94
    usrData: pointer;
95
    usrSize: cardinal;
96
    texData: pointer;
97
    subsets: pointer;
98
    tris: pointer;
99
    ok: boolean;
100
  end;
101

102
  TMaterialInfo = record
103
    FShininess, BShininess: TShininess;
104
    FAmbient, FDiffuse, FEmission, FSpecular, BAmbient, BDiffuse, BEmission,
105
      BSpecular: TVector;
106
    ImageAlpha: TGLTextureImageAlpha;
107
    magFilter: TGLMagFilter;
108
    minFilter: TGLMinFilter;
109
    TextureMode: TGLTextureMode;
110
    TextureWrap: TGLTextureWrap;
111
    Blendingmode: TBlendingMode;
112
    FaceCulling: TFaceCulling;
113
    mathash: integer;
114
  end;
115

116
  TGLLMTSVectorFile = class(TGLVectorFile)
117
  public
118
    class function Capabilities: TGLDataFileCapabilities; override;
119

120
    procedure LoadFromStream(aStream: TStream); override;
121
    procedure SaveToStream(aStream: TStream); override;
122

123
  end;
124

125
implementation
126

127
uses
128
  GLTextureFormat;
129

130
// ------------------
131
// ------------------ TGLLMTSVectorFile ------------------
132
// ------------------
133

134
// Capabilities
135
//
136

137
class function TGLLMTSVectorFile.Capabilities: TGLDataFileCapabilities;
138
begin
139
  Result := [dfcRead, dfcWrite];
140
end;
141

142
// LoadFromStream
143
//
144

145
procedure TGLLMTSVectorFile.LoadFromStream(aStream: TStream);
146
var
147
  MO: TGLMeshObject;
148
  FG: TFGVertexIndexList;
149
  LL: TGLMaterialLibrary;
150
  ML: TGLMaterialLibrary;
151
  LMTS: TLMTS;
152
  T: TLMTS_TexData;
153
  V: array [0 .. 2] of TLMTS_Vertex;
154
  S: TLMTS_Subset;
155
  _4cc: cardinal;
156
  C: integer;
157
  fName: string;
158
  vi: Tintegerlist;
159
  libmat: TGLLibmaterial;
160
  lmnames, matnames: TStringlist;
161
  MatInfoHeader: array [0 .. 3] of ansichar;
162
  MatInfoCount: cardinal;
163
  Matinfo: array of TMaterialInfo;
164
  i, j: integer;
165
begin
166
  owner.MeshObjects.Clear;
167

168
  MO := TGLMeshObject.CreateOwned(owner.MeshObjects);
169
  MO.Mode := momFaceGroups;
170

171
  vi := Tintegerlist.create;
172

173
  LL := owner.LightmapLibrary;
174
  ML := owner.MaterialLibrary;
175

176
  lmnames := TStringlist.create;
177
  matnames := TStringlist.create;
178
  MatInfoCount := 0;
179
  try
180
    // read header...
181
    aStream.Read(LMTS.header, SizeOf(TLMTS_Header));
182
    // verify...
183
    if (LMTS.header.ID <> C_LMTS_ID) or (LMTS.header.Ver <> C_LMTS_VER) or
184
      (LMTS.header.headerSize < SizeOf(TLMTS_Header)) or
185
      (LMTS.header.subSize < SizeOf(TLMTS_Subset)) or
186
      (LMTS.header.vtxSize < SizeOf(TLMTS_Vertex)) then
187
      raise Exception.create('Error in header');
188

189
    // read "user" data - actually skip this data...
190
    LMTS.usrSize := LMTS.header.headerSize - SizeOf(TLMTS_Header);
191
    if (LMTS.usrSize > 7) then
192
    begin
193
      aStream.Read(MatInfoHeader, 4);
194
      if MatInfoHeader = 'MATI' then
195
      begin
196
        aStream.Read(MatInfoCount, 4);
197
        if MatInfoCount > 0 then
198
        begin
199
          setlength(Matinfo, MatInfoCount);
200
          for i := 0 to MatInfoCount - 1 do
201
          begin
202
            aStream.Read(Matinfo[i], SizeOf(Matinfo[i]));
203
          end;
204
        end;
205
        if LMTS.usrSize > ((MatInfoCount * SizeOf(TMaterialInfo)) + 8) then
206
        begin
207
          LMTS.usrSize := LMTS.usrSize -
208
            ((MatInfoCount * SizeOf(TMaterialInfo)) + 8);
209
          aStream.Seek(LMTS.usrSize, soFromCurrent);
210
        end;
211
      end
212
      else
213
        aStream.Seek(LMTS.usrSize - 4, soFromCurrent);
214
    end
215
    else if (LMTS.usrSize > 0) then
216
      aStream.Seek(LMTS.usrSize, soFromCurrent);
217

218
    // read texture filenames data...
219
    aStream.Read(_4cc, SizeOf(_4cc));
220
    if (_4cc <> C_LMTS_TEXT) then
221
      raise Exception.create('Texture data not found');
222

223
    for C := 0 to LMTS.header.nTexts - 1 do
224
    begin
225
      aStream.Read(T, SizeOf(TLMTS_TexData));
226
      if T.Flags = 0 then
227
      begin
228
        if Assigned(ML) and (trim(String(T.fName)) <> '') then
229
        begin
230
          fName := String(T.fName);
231
          try
232
            if lastdelimiter('.', fName) <> length(fName) - 3 then
233
              fName := fName + '.tga'
234
            else
235
              fName := changefileext(fName, '.tga');
236
            if not fileexists(fName) then
237
            begin
238
              fName := changefileext(fName, '.jpg');
239
              if not fileexists(fName) then
240
              begin
241
                fName := changefileext(fName, '.png');
242
                if not fileexists(fName) then
243
                begin
244
                  fName := changefileext(fName, '.bmp');
245
                  if not fileexists(fName) then
246
                  begin
247
                    fName := changefileext(fName, '.dds');
248
                    if not fileexists(fName) then
249
                    begin
250
                      fName := String(T.fName);
251
                    end;
252
                    // fName:=fName+' (missing)';
253
                  end;
254

255
                end;
256
              end;
257
            end;
258
            libmat := ML.Materials.GetLibMaterialByName(fName);
259
            if not Assigned(libmat) then
260
            begin
261
              with ML.AddTextureMaterial(fName, fName) do
262
                Material.Texture.TextureMode := tmModulate;
263
            end;
264
            matnames.add(fName);
265
          except
266
            matnames.add(fName);
267
            { on E: ETexture do
268
              begin
269
              if not Owner.IgnoreMissingTextures then
270
              raise;
271
              end; }
272
          end;
273
        end
274
        else
275
          matnames.add(String(T.fName));
276
      end
277
      else
278
      begin
279
        if Assigned(LL) and (trim(String(T.fName)) <> '') then
280
        begin
281
          fName := String(T.fName);
282
          try
283
            if lastdelimiter('.', fName) <> length(fName) - 3 then
284
              fName := fName + '.tga'
285
            else
286
              fName := changefileext(fName, '.tga');
287
            if not fileexists(fName) then
288
            begin
289
              fName := changefileext(fName, '.jpg');
290
              if not fileexists(fName) then
291
              begin
292
                fName := changefileext(fName, '.png');
293
                if not fileexists(fName) then
294
                begin
295
                  fName := changefileext(fName, '.bmp');
296
                  if not fileexists(fName) then
297
                  begin
298
                    fName := changefileext(fName, '.dds');
299
                    if not fileexists(fName) then
300
                    begin
301
                      fName := String(T.fName);
302
                    end;
303
                    // fName:=fName+' (missing)';
304
                  end;
305
                end;
306

307
              end;
308
            end;
309
            libmat := LL.Materials.GetLibMaterialByName(fName);
310
            if not Assigned(libmat) then
311
            begin
312
              with LL.AddTextureMaterial(fName, fName).Material.Texture do
313
              begin
314
                minFilter := miLinear;
315
                TextureWrap := twNone;
316
                TextureFormat := tfRGB;
317
                TextureMode := tmModulate;
318
              end;
319
            end;
320
            lmnames.add(fName);
321
          except
322
            lmnames.add(fName);
323
            { on E: ETexture do
324
              begin
325
              if not Owner.IgnoreMissingTextures then
326
              raise;
327
              end; }
328
          end;
329
        end
330
        else
331
          lmnames.add(String(T.fName));
332
      end;
333
    end;
334

335
    if Assigned(owner.MaterialLibrary) then
336
      for i := 0 to MatInfoCount - 1 do
337
      begin
338
        libmat := nil;
339
        for j := 0 to owner.MaterialLibrary.Materials.Count - 1 do
340
          if owner.MaterialLibrary.Materials[j].NameHashKey = Matinfo[i].mathash
341
          then
342
          begin
343
            libmat := owner.MaterialLibrary.Materials[j];
344
            break;
345
          end;
346

347
        if Assigned(libmat) then
348
        begin
349
          with Matinfo[i] do
350
          begin
351
            libmat.Material.FrontProperties.Shininess := FShininess;
352
            libmat.Material.BackProperties.Shininess := BShininess;
353
            libmat.Material.FrontProperties.Ambient.Color := FAmbient;
354
            libmat.Material.FrontProperties.Diffuse.Color := FDiffuse;
355
            libmat.Material.FrontProperties.Emission.Color := FEmission;
356
            libmat.Material.FrontProperties.Specular.Color := FSpecular;
357

358
            libmat.Material.BackProperties.Ambient.Color := BAmbient;
359
            libmat.Material.BackProperties.Diffuse.Color := BDiffuse;
360
            libmat.Material.BackProperties.Emission.Color := BEmission;
361
            libmat.Material.BackProperties.Specular.Color := BSpecular;
362

363
            libmat.Material.Texture.ImageAlpha := ImageAlpha;
364
            libmat.Material.Texture.magFilter := magFilter;
365
            libmat.Material.Texture.minFilter := minFilter;
366
            libmat.Material.Texture.TextureMode := TextureMode;
367
            libmat.Material.Texture.TextureWrap := TextureWrap;
368
            libmat.Material.Blendingmode := Blendingmode;
369
            libmat.Material.FaceCulling := FaceCulling;
370
          end;
371
        end;
372
      end;
373

374
    // read subset data...
375
    aStream.Read(_4cc, SizeOf(_4cc));
376
    if (_4cc <> C_LMTS_SUBS) then
377
      raise Exception.create('Subset data not found');
378
    for C := LMTS.header.nSubsets - 1 downto 0 do
379
    begin
380
      aStream.Read(S, LMTS.header.subSize);
381
      FG := TFGVertexIndexList.CreateOwned(MO.FaceGroups);
382
      FG.Mode := fgmmTriangles;
383
      FG.vertexindices.AddSerie(S.Offset * 3, 1, S.Count * 3);
384
      vi.AddSerie(S.Offset * 3, 1, S.Count * 3);
385

386
      if Assigned(ML) and (S.TextID1 <> $FFFF) then
387
      begin
388
        if (S.TextID1 < matnames.Count) then
389
        begin
390
          libmat := ML.Materials.GetLibMaterialByName(matnames[S.TextID1]);
391
          if Assigned(libmat) then
392
            FG.MaterialName := libmat.Name;
393
        end;
394
      end;
395

396
      if Assigned(LL) and (S.TextID2 <> $FFFF) then
397
      begin
398
        if (S.TextID2 - matnames.Count < lmnames.Count) and
399
          (S.TextID2 - matnames.Count > -1) then
400
        begin
401
          libmat := LL.Materials.GetLibMaterialByName
402
            (lmnames[S.TextID2 - matnames.Count]);
403
          if Assigned(libmat) then
404
            FG.lightmapindex := libmat.Index;
405
        end;
406
      end;
407
    end;
408
    // read vertex data...
409
    aStream.Read(_4cc, SizeOf(_4cc));
410
    if (_4cc <> C_LMTS_TRIS) then
411
      raise Exception.create('Vertex data not found');
412
    for C := 0 to integer(LMTS.header.nTris) - 1 do
413
    begin
414
      aStream.Read(V[0], LMTS.header.vtxSize);
415
      aStream.Read(V[1], LMTS.header.vtxSize);
416
      aStream.Read(V[2], LMTS.header.vtxSize);
417

418
      MO.Vertices.add(-V[0].x, V[0].y, V[0].z);
419
      MO.TexCoords.add(V[0].u1, -V[0].v1);
420
      MO.LightmapTexCoords.add(V[0].u2, 1 - V[0].v2);
421

422
      MO.Vertices.add(-V[2].x, V[2].y, V[2].z);
423
      MO.TexCoords.add(V[2].u1, -V[2].v1);
424
      MO.LightmapTexCoords.add(V[2].u2, 1 - V[2].v2);
425

426
      MO.Vertices.add(-V[1].x, V[1].y, V[1].z);
427
      MO.TexCoords.add(V[1].u1, -V[1].v1);
428
      MO.LightmapTexCoords.add(V[1].u2, 1 - V[1].v2);
429
    end;
430
    MO.BuildNormals(vi, momtriangles);
431
    vi.free;
432
    matnames.free;
433
    lmnames.free;
434
    setlength(Matinfo, 0);
435
  except
436
    matnames.free;
437
    lmnames.free;
438
    MO.free;
439
  end;
440
end;
441

442
// SaveToStream
443
//
444

445
procedure TGLLMTSVectorFile.SaveToStream(aStream: TStream);
446
var
447
  MO: TGLMeshObject;
448
  FG: TFGVertexIndexList;
449
  i, j, k, l, lmstartindex, C, matindex: integer;
450
  h: TLMTS_Header;
451
  V: array [0 .. 2] of TLMTS_Vertex;
452
  texData: array of TLMTS_TexData;
453
  subsets: array of TLMTS_Subset;
454
  tris: array of TLMTS_Vertex;
455
  _4cc: cardinal;
456
  matname: AnsiString;
457
  ss: integer;
458
  Matinfo: array of TMaterialInfo;
459
  MatInfoCount: integer;
460
  libmat: TGLLibmaterial;
461
begin
462
  setlength(tris, 0);
463
  setlength(subsets, 0);
464
  setlength(texData, 0);
465
  C := 0;
466
  lmstartindex := maxint;
467
  for i := 0 to owner.MeshObjects.Count - 1 do
468
  begin
469
    MO := owner.MeshObjects[i];
470
    for j := 0 to MO.FaceGroups.Count - 1 do
471
    begin
472
      FG := TFGVertexIndexList(MO.FaceGroups[j]);
473

474
      matname := AnsiString(FG.MaterialName);
475

476
      // no duplicate textures please
477
      matindex := -1;
478
      for k := 0 to high(texData) do
479
        if texData[k].fName = matname then
480
        begin
481
          matindex := k;
482
          break;
483
        end;
484

485
      if matindex = -1 then // not a duplicate, so add it
486
      begin
487
        setlength(texData, length(texData) + 1);
488
        with texData[high(texData)] do
489
        begin
490
          matindex := high(texData);
491

492
          strpcopy(pansichar(@fName), matname);
493
          Flags := 0;
494
        end;
495

496
        inc(C); // used to offest the lightmap index
497
      end;
498

499
      // set some of the facegroup (subsets) info here.
500
      setlength(subsets, length(subsets) + 1);
501
      with subsets[high(subsets)] do
502
      begin
503
        if (matname <> '') then
504
          TextID1 := matindex
505
        else
506
          TextID1 := $FFFF;
507
      end;
508

509
      if (FG.lightmapindex > -1) and (lmstartindex > FG.lightmapindex) then
510
        lmstartindex := FG.lightmapindex; // used to offest the lightmap index
511
    end;
512
  end;
513

514
  if lmstartindex = maxint then
515
    lmstartindex := 0; // cool, lightmaps start from the first index
516
  ss := 0;
517
  for i := 0 to owner.MeshObjects.Count - 1 do
518
  begin
519
    MO := owner.MeshObjects[i];
520
    for j := 0 to MO.FaceGroups.Count - 1 do
521
    begin
522
      FG := TFGVertexIndexList(MO.FaceGroups[j]);
523

524
      // subset already created earlier, just finish filling the data.
525
      // we needed the "c" and "lmstartindex" to be able to do this
526
      with subsets[ss] do
527
      begin
528
        Offset := length(tris) div 3;
529
        Count := FG.vertexindices.Count div 3;
530

531
        if (FG.lightmapindex > -1) and Assigned(owner.LightmapLibrary) then
532
          TextID2 := C + FG.lightmapindex - lmstartindex
533
        else
534
          TextID2 := $FFFF;
535
      end;
536

537
      // fill the vertex data
538
      k := 0;
539
      while k < FG.vertexindices.Count do
540
      begin
541
        for l := 0 to 2 do
542
        begin
543
          with V[l] do
544
          begin
545
            // vertex
546
            x := -MO.Vertices[FG.vertexindices[k + l]].V[0];
547
            y := MO.Vertices[FG.vertexindices[k + l]].V[1];
548
            z := MO.Vertices[FG.vertexindices[k + l]].V[2];
549

550
            // texcoords
551
            u1 := 0;
552
            v1 := 0;
553
            if FG is TFGVertexNormalTexIndexList then
554
            begin
555
              if MO.TexCoords.Count > TFGVertexNormalTexIndexList(FG)
556
                .texcoordIndices[k + l] then
557
              begin
558
                u1 := MO.TexCoords[TFGVertexNormalTexIndexList(FG)
559
                  .texcoordIndices[k + l]].V[0];
560
                v1 := -MO.TexCoords[TFGVertexNormalTexIndexList(FG)
561
                  .texcoordIndices[k + l]].V[1];
562
              end;
563
            end
564
            else if FG is TFGIndexTexCoordList then
565
            begin
566
              u1 := TFGIndexTexCoordList(FG).TexCoords[k + l].V[0];
567
              v1 := -TFGIndexTexCoordList(FG).TexCoords[k + l].V[1];
568
            end
569
            else if MO.TexCoords.Count > FG.vertexindices[k + l] then
570
            begin
571
              u1 := MO.TexCoords[FG.vertexindices[k + l]].V[0];
572
              v1 := -MO.TexCoords[FG.vertexindices[k + l]].V[1];
573
            end;
574

575
            // lightmap texcoords
576
            u2 := 0;
577
            v2 := 0;
578
            if MO.LightmapTexCoords.Count > FG.vertexindices[k + l] then
579
            begin
580
              u2 := MO.LightmapTexCoords[FG.vertexindices[k + l]].V[0];
581
              v2 := 1 - MO.LightmapTexCoords[FG.vertexindices[k + l]].V[1];
582
            end;
583
          end;
584
        end;
585
        setlength(tris, length(tris) + 3);
586

587
        tris[high(tris) - 2] := V[0];
588
        tris[high(tris) - 1] := V[2];
589
        tris[high(tris)] := V[1];
590

591
        inc(k, 3);
592
      end;
593
      inc(ss);
594
    end;
595
  end;
596

597
  setlength(Matinfo, 0);
598
  // store the material properties..
599
  if Assigned(owner.MaterialLibrary) then
600
  begin
601
    for i := 0 to high(texData) do
602
    begin
603
      libmat := owner.MaterialLibrary.Materials.GetLibMaterialByName
604
        (String(texData[i].fName));
605
      if Assigned(libmat) then
606
      begin
607
        setlength(Matinfo, length(Matinfo) + 1);
608
        with Matinfo[high(Matinfo)] do
609
        begin
610
          FShininess := libmat.Material.FrontProperties.Shininess;
611
          BShininess := libmat.Material.BackProperties.Shininess;
612
          FAmbient := libmat.Material.FrontProperties.Ambient.Color;
613
          FDiffuse := libmat.Material.FrontProperties.Diffuse.Color;
614
          FEmission := libmat.Material.FrontProperties.Emission.Color;
615
          FSpecular := libmat.Material.FrontProperties.Specular.Color;
616

617
          BAmbient := libmat.Material.BackProperties.Ambient.Color;
618
          BDiffuse := libmat.Material.BackProperties.Diffuse.Color;
619
          BEmission := libmat.Material.BackProperties.Emission.Color;
620
          BSpecular := libmat.Material.BackProperties.Specular.Color;
621

622
          ImageAlpha := libmat.Material.Texture.ImageAlpha;
623
          magFilter := libmat.Material.Texture.magFilter;
624
          minFilter := libmat.Material.Texture.minFilter;
625
          TextureMode := libmat.Material.Texture.TextureMode;
626
          TextureWrap := libmat.Material.Texture.TextureWrap;
627
          Blendingmode := libmat.Material.Blendingmode;
628
          FaceCulling := libmat.Material.FaceCulling;
629
          mathash := libmat.NameHashKey;
630
        end;
631
      end;
632
    end;
633
  end;
634

635
  // add the lightmap texture names to the texdata list
636
  C := length(texData);
637
  if Assigned(owner.LightmapLibrary) then
638
    for i := 0 to owner.MeshObjects.Count - 1 do
639
    begin
640
      MO := owner.MeshObjects[i];
641
      for j := 0 to MO.FaceGroups.Count - 1 do
642
      begin
643
        FG := TFGVertexIndexList(MO.FaceGroups[j]);
644
        if FG.lightmapindex > -1 then
645
        begin
646
          matname := AnsiString(owner.LightmapLibrary.Materials
647
            [FG.lightmapindex].Name);
648
          // no duplicate textures please
649
          matindex := -1;
650
          for k := C to high(texData) do
651
            if texData[k].fName = matname then
652
            begin
653
              matindex := k;
654
              break;
655
            end;
656
          if matindex = -1 then // not a duplicate, so add it
657
          begin
658
            setlength(texData, length(texData) + 1);
659
            with texData[high(texData)] do
660
            begin
661
              strpcopy(pansichar(@fName), matname);
662
              Flags := 1;
663
            end;
664
          end;
665
        end;
666
      end;
667
    end;
668

669
  // fill and write the file header
670
  with h do
671
  begin
672
    ID := C_LMTS_ID;
673
    Ver := C_LMTS_VER;
674
    headerSize := 24 + 8 + (length(Matinfo) * SizeOf(TMaterialInfo));
675
    nTexts := length(texData);
676
    nSubsets := length(subsets);
677
    nTris := length(tris) div 3;
678
    subSize := SizeOf(TLMTS_Subset);
679
    vtxSize := SizeOf(TLMTS_Vertex);
680
  end;
681
  aStream.Write(h, SizeOf(h));
682

683
  aStream.Write('MATI', 4);
684
  MatInfoCount := length(Matinfo);
685
  aStream.Write(MatInfoCount, SizeOf(MatInfoCount));
686
  // write the materials info
687
  for i := 0 to high(Matinfo) do
688
    aStream.Write(Matinfo[i], SizeOf(Matinfo[i]));
689

690
  // write the texture names
691
  _4cc := C_LMTS_TEXT;
692
  aStream.Write(_4cc, SizeOf(_4cc));
693
  for i := 0 to high(texData) do
694
    aStream.Write(texData[i], SizeOf(texData[i]));
695

696
  // fagegroups
697
  _4cc := C_LMTS_SUBS;
698
  aStream.Write(_4cc, SizeOf(_4cc));
699
  for i := 0 to high(subsets) do
700
    aStream.Write(subsets[i], SizeOf(subsets[i]));
701

702
  // vertex data
703
  _4cc := C_LMTS_TRIS;
704
  aStream.Write(_4cc, SizeOf(_4cc));
705
  for i := 0 to high(tris) do
706
    aStream.Write(tris[i], SizeOf(tris[i]));
707

708
  // free up used memory
709
  setlength(tris, 0);
710
  setlength(subsets, 0);
711
  setlength(texData, 0);
712
  setlength(Matinfo, 0);
713
end;
714

715
initialization
716

717
RegisterVectorFileFormat('lmts', 'Pulsar Studio LMTS File Format',
718
  TGLLMTSVectorFile);
719

720
end.
721

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.