2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Misc. lists of vectors and entities
8
10/12/14 - PW - Renamed VectorList unit to GLVectorList
9
23/02/11 - Yar - Added Revision mechanism to TAffineVectorList
10
15/12/10 - DaStr - Added Min() and Max() for TSingleList and TDoubleList
11
04/11/10 - DaStr - Restored Delphi5 and Delphi6 compatibility
12
24/08/10 - Yar - Added to T4ByteList more overload of Add method
13
11/06/10 - Yar - Bugfixed binary reading TTexPointList for FPC
14
20/05/10 - Yar - Fixes for Linux x64
15
27/02/10 - Yar - Added TLongWordList
16
06/02/10 - Yar - Added methods to TSingleList
18
25/11/09 - DanB - Fixed FastQuickSortLists for 64bit (thanks YarUnderoaker)
19
ASM code protected with IFDEFs
20
16/10/08 - UweR - Compatibility fix for Delphi 2009
21
01/03/08 - DaStr - Added Borland-style persistency support to TBaseList
22
29/03/07 - DaStr - Added more explicit pointer dereferencing
23
(thanks Burkhard Carstens) (Bugtracker ID = 1678644)
24
28/03/07 - DaStr - Renamed parameters in some methods
25
(thanks Burkhard Carstens) (Bugtracker ID = 1678658)
26
25/01/07 - DaStr - Reformated code according to VCL standard
27
Added explicit pointer dereferencing
28
(thanks Burkhard Carstens) (Bugtracker ID = 1678644)
29
23/01/07 - fig - Added FindOrAdd() or IndexOf() to TTexpointList
30
16/01/07 - DaStr - Added TDoubleList
31
28/06/04 - LR - Removed ..\ from the GLScene.inc
32
03/09/03 - EG - Added TBaseList.Move, faster TIntegerList.Offset
33
22/08/03 - EG - Faster FastQuickSortLists
34
13/08/03 - SG - Added TQuaternionList
35
05/06/03 - EG - Added MinInteger, some TIntegerList optimizations
36
03/06/03 - EG - Added TIntegerList.BinarySearch and AddSorted (Mattias Fagerlund)
37
22/01/03 - EG - Added AddIntegers
38
20/01/03 - EG - Added TIntegerList.SortAndRemoveDuplicates
39
22/10/02 - EG - Added TransformXxxx to TAffineVectorList
40
04/07/02 - EG - Fixed TIntegerList.Add( 2 at once )
41
15/06/02 - EG - Added TBaseListOption stuff
42
28/05/02 - EG - TBaseList.SetCount now properly resets new items
43
23/02/02 - EG - Added TBaseList.UseMemory
44
20/01/02 - EG - Now uses new funcs Add/ScaleVectorArray and VectorArrayAdd
45
06/12/01 - EG - Added Sort & MaxInteger to TIntegerList
46
04/12/01 - EG - Added TIntegerList.IndexOf
47
18/08/01 - EG - Fixed TAffineVectorList.Add (list)
48
03/08/01 - EG - Added TIntegerList.AddSerie
49
19/07/01 - EG - Added TAffineVectorList.Add (list variant)
50
18/03/01 - EG - Additions and enhancements
51
16/03/01 - EG - Introduced new PersistentClasses
52
04/03/01 - EG - Optimized TAffineVectorList.Normalize (x2 speed on K7)
53
26/02/01 - EG - VectorArrayLerp 3DNow optimized (x2 speed on K7)
54
08/08/00 - EG - Added TSingleList
55
20/07/00 - EG - Creation
67
GLVectorTypes, GLVectorGeometry, GLPersistentClasses, GLCrossPlatform;
72
TBaseListOption = (bloExternalMemory, bloSetCountResetsMemory);
73
TBaseListOptions = set of TBaseListOption;
77
{ Base class for lists, introduces common behaviours. }
78
TBaseList = class(TPersistentObject)
83
FGrowthDelta: Integer;
84
FBufferItem: PByteArray;
85
FOptions: TBaseListOptions;
90
// The base list pointer (untyped)
91
FBaseList: GLVectorGeometry.PByteArray;
92
// Must be defined by all subclasses in their constructor(s)
95
procedure SetCount(Val: Integer);
96
{ Only function where list may be alloc'ed & freed.
97
Resizes the array pointed by FBaseList, adjust the subclass's
98
typed pointer accordingly if any. }
99
procedure SetCapacity(NewCapacity: Integer); virtual;
100
function BufferItem: PByteArray;
101
function GetSetCountResetsMemory: Boolean;
102
procedure SetSetCountResetsMemory(const Val: Boolean);
104
// Borland-style persistency support.
105
procedure ReadItemsData(AReader : TReader); virtual;
106
procedure WriteItemsData(AWriter : TWriter); virtual;
107
procedure DefineProperties(AFiler: TFiler); override;
110
constructor Create; override;
111
destructor Destroy; override;
112
procedure Assign(Src: TPersistent); override;
114
procedure WriteToFiler(writer: TVirtualWriter); override;
115
procedure ReadFromFiler(reader: TVirtualReader); override;
117
procedure AddNulls(nbVals: Cardinal);
118
procedure InsertNulls(Index: Integer; nbVals: Cardinal);
120
procedure AdjustCapacityToAtLeast(const size: Integer);
121
function DataSize: Integer;
122
{ Tell the list to use the specified range instead of its own.
123
rangeCapacity should be expressed in bytes.
124
The allocated memory is NOT managed by the list, current content
125
if copied to the location, if the capacity is later changed, regular
126
memory will be allocated, and the specified range no longer used. }
127
procedure UseMemory(rangeStart: Pointer; rangeCapacity: Integer);
128
{ Empties the list without altering capacity. }
130
{ Empties the list and release. }
133
procedure Delete(Index: Integer);
134
procedure DeleteItems(Index: Integer; nbVals: Cardinal);
135
procedure Exchange(index1, index2: Integer);
136
procedure Move(curIndex, newIndex: Integer);
139
{ Nb of items in the list.
140
When assigning a Count, added items are reset to zero. }
141
property Count: Integer read FCount write SetCount;
142
{ Current list capacity.
144
property Capacity: Integer read FCapacity write SetCapacity;
145
{ List growth granularity.
147
property GrowthDelta: Integer read FGrowthDelta write FGrowthDelta;
148
{ If true (default value) adjusting count will reset added values.
149
Switching this option to true will turn off this memory reset,
150
which can improve performance is that having empty values isn't
152
property SetCountResetsMemory: Boolean read GetSetCountResetsMemory write SetSetCountResetsMemory;
153
property TagString: string read FTagString write FTagString;
154
{ Increase by one after every content changes. }
155
property Revision: LongWord read FRevision write FRevision;
160
{ Base class for vector lists, introduces common behaviours. }
161
TBaseVectorList = class(TBaseList)
166
function GetItemAddress(Index: Integer): PFloatArray;
170
procedure WriteToFiler(writer: TVirtualWriter); override;
171
procedure ReadFromFiler(reader: TVirtualReader); override;
173
procedure GetExtents(out min, max: TAffineVector); dynamic;
174
function Sum: TAffineVector; dynamic;
175
procedure Normalize; dynamic;
176
function MaxSpacing(list2: TBaseVectorList): Single; dynamic;
177
procedure Translate(const delta: TAffineVector); overload; dynamic;
178
procedure Translate(const delta: TBaseVectorList); overload; dynamic;
179
procedure TranslateInv(const delta: TBaseVectorList); overload; dynamic;
181
{ Replace content of the list with lerp results between the two given lists.
182
Note: you can't Lerp with Self!!! }
183
procedure Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single); dynamic; abstract;
184
{ Replace content of the list with angle lerp between the two given lists.
185
Note: you can't Lerp with Self!!! }
186
procedure AngleLerp(const list1, list2: TBaseVectorList; lerpFactor: Single);
187
procedure AngleCombine(const list1: TBaseVectorList; intensity: Single);
188
{ Linear combination of Self with another list.
189
Self[i]:=Self[i]+list2[i]*factor }
190
procedure Combine(const list2: TBaseVectorList; factor: Single); dynamic;
192
property ItemAddress[Index: Integer]: PFloatArray read GetItemAddress;
198
{ A list of TAffineVector.
199
Similar to TList, but using TAffineVector as items.
200
The list has stack-like push/pop methods. }
201
TAffineVectorList = class(TBaseVectorList)
204
FList: PAffineVectorArray;
208
function Get(Index: Integer): TAffineVector;
209
procedure Put(Index: Integer; const item: TAffineVector);
210
procedure SetCapacity(NewCapacity: Integer); override;
214
constructor Create; override;
215
procedure Assign(Src: TPersistent); override;
217
function Add(const item: TAffineVector): Integer; overload;
218
function Add(const item: TVector): Integer; overload;
219
procedure Add(const i1, i2: TAffineVector); overload;
220
procedure Add(const i1, i2, i3: TAffineVector); overload;
221
function Add(const item: TVector2f): Integer; overload;
222
function Add(const item: TTexPoint): Integer; overload;
223
function Add(const X, Y: Single): Integer; overload;
224
function Add(const X, Y, Z: Single): Integer; overload;
225
function Add(const X, Y, Z: Integer): Integer; overload;
226
function AddNC(const X, Y, Z: Integer): Integer; overload;
227
function Add(const xy: PIntegerArray; const Z: Integer): Integer; overload;
228
function AddNC(const xy: PIntegerArray; const Z: Integer): Integer; overload;
229
procedure Add(const list: TAffineVectorList); overload;
230
procedure Push(const Val: TAffineVector);
231
function Pop: TAffineVector;
232
procedure Insert(Index: Integer; const item: TAffineVector);
233
function IndexOf(const item: TAffineVector): Integer;
234
function FindOrAdd(const item: TAffineVector): Integer;
236
property Items[Index: Integer]: TAffineVector read Get write Put; default;
237
property List: PAffineVectorArray read FList;
239
procedure Translate(const delta: TAffineVector); overload; override;
240
procedure Translate(const delta: TAffineVector; base, nb: Integer); overload;
242
// Translates the given item
243
procedure TranslateItem(Index: Integer; const delta: TAffineVector);
244
// Translates given items
245
procedure TranslateItems(Index: Integer; const delta: TAffineVector; nb: Integer);
246
// Combines the given item
247
procedure CombineItem(Index: Integer; const vector: TAffineVector; const f: Single);
249
{ Transforms all items by the matrix as if they were points.
250
ie. the translation component of the matrix is honoured. }
251
procedure TransformAsPoints(const matrix: TMatrix);
252
{ Transforms all items by the matrix as if they were vectors.
253
ie. the translation component of the matrix is not honoured. }
254
procedure TransformAsVectors(const matrix: TMatrix); overload;
255
procedure TransformAsVectors(const matrix: TAffineMatrix); overload;
257
procedure Normalize; override;
258
procedure Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single); override;
260
procedure Scale(factor: Single); overload;
261
procedure Scale(const factors: TAffineVector); overload;
267
Similar to TList, but using TVector as items.
268
The list has stack-like push/pop methods. }
269
TVectorList = class(TBaseVectorList)
276
function Get(Index: Integer): TVector;
277
procedure Put(Index: Integer; const item: TVector);
278
procedure SetCapacity(NewCapacity: Integer); override;
282
constructor Create; override;
283
procedure Assign(Src: TPersistent); override;
285
function Add(const item: TVector): Integer; overload;
286
function Add(const item: TAffineVector; w: Single): Integer; overload;
287
function Add(const X, Y, Z, w: Single): Integer; overload;
288
procedure Add(const i1, i2, i3: TAffineVector; w: Single); overload;
289
function AddVector(const item: TAffineVector): Integer; overload;
290
function AddPoint(const item: TAffineVector): Integer; overload;
291
function AddPoint(const X, Y: Single; const Z: Single = 0): Integer; overload;
292
procedure Push(const Val: TVector);
293
function Pop: TVector;
294
function IndexOf(const item: TVector): Integer;
295
function FindOrAdd(const item: TVector): Integer;
296
function FindOrAddPoint(const item: TAffineVector): Integer;
297
procedure Insert(Index: Integer; const item: TVector);
299
property Items[Index: Integer]: TVector read Get write Put; default;
300
property List: PVectorArray read FList;
302
procedure Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single); override;
307
{ A list of TTexPoint.
308
Similar to TList, but using TTexPoint as items.
309
The list has stack-like push/pop methods. }
310
TTexPointList = class(TBaseVectorList)
313
FList: PTexPointArray;
317
function Get(Index: Integer): TTexPoint;
318
procedure Put(Index: Integer; const item: TTexPoint);
319
procedure SetCapacity(NewCapacity: Integer); override;
323
constructor Create; override;
324
procedure Assign(Src: TPersistent); override;
326
function IndexOf(const item: TTexpoint): Integer;
327
function FindOrAdd(const item: TTexpoint): Integer;
329
function Add(const item: TTexPoint): Integer; overload;
330
function Add(const item: TVector2f): Integer; overload;
331
function Add(const texS, Text: Single): Integer; overload;
332
function Add(const texS, Text: Integer): Integer; overload;
333
function AddNC(const texS, Text: Integer): Integer; overload;
334
function Add(const texST: PIntegerArray): Integer; overload;
335
function AddNC(const texST: PIntegerArray): Integer; overload;
336
procedure Push(const Val: TTexPoint);
337
function Pop: TTexPoint;
338
procedure Insert(Index: Integer; const item: TTexPoint);
340
property Items[Index: Integer]: TTexPoint read Get write Put; default;
341
property List: PTexPointArray read FList;
343
procedure Translate(const delta: TTexPoint);
344
procedure ScaleAndTranslate(const scale, delta: TTexPoint); overload;
345
procedure ScaleAndTranslate(const scale, delta: TTexPoint; base, nb: Integer); overload;
347
procedure Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single); override;
352
{ A list of Integers.
353
Similar to TList, but using TTexPoint as items.
354
The list has stack-like push/pop methods. }
355
TIntegerList = class(TBaseList)
358
FList: PIntegerArray;
362
function Get(Index: Integer): Integer;
363
procedure Put(Index: Integer; const item: Integer);
364
procedure SetCapacity(newCapacity: Integer); override;
368
constructor Create; override;
369
procedure Assign(src: TPersistent); override;
371
function Add(const item: Integer): Integer; overload;
372
function AddNC(const item: Integer): Integer; overload;
373
procedure Add(const i1, i2: Integer); overload;
374
procedure Add(const i1, i2, i3: Integer); overload;
375
procedure Add(const AList: TIntegerList); overload;
376
procedure Push(const Val: Integer);
377
function Pop: Integer;
378
procedure Insert(Index: Integer; const item: Integer);
379
procedure Remove(const item: Integer);
380
function IndexOf(item: Integer): Integer;
382
property Items[Index: Integer]: Integer read Get write Put; default;
383
property List: PIntegerArray read FList;
385
{ Adds count items in an arithmetic serie.
386
Items are (aBase), (aBase+aDelta) ... (aBase+(aCount-1)*aDelta) }
387
procedure AddSerie(aBase, aDelta, aCount: Integer);
388
{ Add n integers at the address starting at (and including) first. }
389
procedure AddIntegers(const First: PInteger; n: Integer); overload;
390
{ Add all integers from aList into the list. }
391
procedure AddIntegers(const aList: TIntegerList); overload;
392
{ Add all integers from anArray into the list. }
393
procedure AddIntegers(const anArray: array of Integer); overload;
395
{ Returns the minimum integer item, zero if list is empty. }
396
function MinInteger: Integer;
397
{ Returns the maximum integer item, zero if list is empty. }
398
function MaxInteger: Integer;
399
{ Sort items in ascending order. }
401
{ Sort items in ascending order and remove duplicated integers. }
402
procedure SortAndRemoveDuplicates;
404
{ Locate a value in a sorted list. }
405
function BinarySearch(const Value: Integer): Integer; overload;
406
{ Locate a value in a sorted list.
407
If ReturnBestFit is set to true, the routine will return the position
408
of the largest value that's smaller than the sought value. Found will
409
be set to True if the exact value was found, False if a "BestFit"
411
function BinarySearch(const Value: Integer; returnBestFit: Boolean; var found: Boolean): Integer; overload;
413
{ Add integer to a sorted list.
414
Maintains the list sorted. If you have to add "a lot" of integers
415
at once, use the Add method then Sort the list for better performance. }
416
function AddSorted(const Value: Integer; const ignoreDuplicates: Boolean = False): Integer;
417
{ Removes an integer from a sorted list. }
418
procedure RemoveSorted(const Value: Integer);
420
{ Adds delta to all items in the list. }
421
procedure Offset(delta: Integer); overload;
422
procedure Offset(delta: Integer; const base, nb: Integer); overload;
425
TSingleArrayList = array[0..MaxInt shr 4] of Single;
426
PSingleArrayList = ^TSingleArrayList;
431
Similar to TList, but using Single as items.
432
The list has stack-like push/pop methods. }
433
TSingleList = class(TBaseList)
436
FList: PSingleArrayList;
440
function Get(Index: Integer): Single;
441
procedure Put(Index: Integer; const item: Single);
442
procedure SetCapacity(NewCapacity: Integer); override;
446
constructor Create; override;
447
procedure Assign(Src: TPersistent); override;
449
function Add(const item: Single): Integer; overload;
450
procedure Add(const i1, i2: Single); overload;
451
procedure AddSingles(const First: PSingle; n: Integer); overload;
452
procedure AddSingles(const anArray: array of Single); overload;
453
procedure Push(const Val: Single);
454
function Pop: Single;
455
procedure Insert(Index: Integer; const item: Single);
457
property Items[Index: Integer]: Single read Get write Put; default;
458
property List: PSingleArrayList read FList;
460
procedure AddSerie(aBase, aDelta: Single; aCount: Integer);
462
{ Adds delta to all items in the list. }
463
procedure Offset(delta: Single); overload;
465
{ Adds to each item the corresponding item in the delta list.
466
Performs 'Items[i]:=Items[i]+delta[i]'.
467
If both lists don't have the same item count, an exception is raised. }
468
procedure Offset(const delta: TSingleList); overload;
470
{ Multiplies all items by factor. }
471
procedure Scale(factor: Single);
473
{ Square all items. }
476
{ SquareRoot all items. }
479
{ Computes the sum of all elements. }
480
function Sum: Single;
482
function Min: Single;
483
function Max: Single;
486
TDoubleArrayList = array[0..MaxInt shr 4] of Double;
487
PDoubleArrayList = ^TDoubleArrayList;
490
Similar to TList, but using Double as items.
491
The list has stack-like push/pop methods. }
492
TDoubleList = class(TBaseList)
495
FList: PDoubleArrayList;
499
function Get(Index: Integer): Double;
500
procedure Put(Index: Integer; const item: Double);
501
procedure SetCapacity(NewCapacity: Integer); override;
505
constructor Create; override;
506
procedure Assign(Src: TPersistent); override;
508
function Add(const item: Double): Integer;
509
procedure Push(const Val: Double);
510
function Pop: Double;
511
procedure Insert(Index: Integer; const item: Double);
513
property Items[Index: Integer]: Double read Get write Put; default;
514
property List: PDoubleArrayList read FList;
516
procedure AddSerie(aBase, aDelta: Double; aCount: Integer);
518
{ Adds delta to all items in the list. }
519
procedure Offset(delta: Double); overload;
520
{ Adds to each item the corresponding item in the delta list.
521
Performs 'Items[i]:=Items[i]+delta[i]'.
522
If both lists don't have the same item count, an exception is raised. }
523
procedure Offset(const delta: TDoubleList); overload;
524
{ Multiplies all items by factor. }
525
procedure Scale(factor: Double);
526
{ Square all items. }
528
{ SquareRoot all items. }
531
{ Computes the sum of all elements. }
532
function Sum: Double;
534
function Min: Single;
535
function Max: Single;
541
Similar to TList, but using Byte as items. }
542
TByteList = class(TBaseList)
549
function Get(Index: Integer): Byte;
550
procedure Put(Index: Integer; const item: Byte);
551
procedure SetCapacity(NewCapacity: Integer); override;
555
constructor Create; override;
556
procedure Assign(Src: TPersistent); override;
558
function Add(const item: Byte): Integer;
559
procedure Insert(Index: Integer; const item: Byte);
561
property Items[Index: Integer]: Byte read Get write Put; default;
562
property List: PByteArray read FList;
568
{ A list of TQuaternion.
569
Similar to TList, but using TQuaternion as items.
570
The list has stack-like push/pop methods. }
571
TQuaternionList = class(TBaseVectorList)
574
FList: PQuaternionArray;
578
function Get(Index: Integer): TQuaternion;
579
procedure Put(Index: Integer; const item: TQuaternion);
580
procedure SetCapacity(NewCapacity: Integer); override;
584
constructor Create; override;
585
procedure Assign(Src: TPersistent); override;
587
function Add(const item: TQuaternion): Integer; overload;
588
function Add(const item: TAffineVector; w: Single): Integer; overload;
589
function Add(const X, Y, Z, W: Single): Integer; overload;
590
procedure Push(const Val: TQuaternion);
591
function Pop: TQuaternion;
592
function IndexOf(const item: TQuaternion): Integer;
593
function FindOrAdd(const item: TQuaternion): Integer;
594
procedure Insert(Index: Integer; const item: TQuaternion);
596
property Items[Index: Integer]: TQuaternion read Get write Put; default;
597
property List: PQuaternionArray read FList;
599
{ Lerps corresponding quaternions from both lists using QuaternionSlerp. }
600
procedure Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single); override;
601
{ Multiplies corresponding quaternions after the second quaternion is
602
slerped with the IdentityQuaternion using factor. This allows for weighted
603
combining of rotation transforms using quaternions. }
604
procedure Combine(const list2: TBaseVectorList; factor: Single); override;
607
// 4 byte union contain access like Integer, Single and four Byte
608
T4ByteData = packed record
610
0 : (Bytes : record Value : array[0..3] of Byte; end);
611
1 : (Int : record Value : Integer; end);
612
2 : (UInt : record Value : Cardinal; end);
613
3 : (Float : record Value : Single; end);
614
4 : (Word : record Value : array[0..1] of Word; end);
617
T4ByteArrayList = array[0..MaxInt shr 4] of T4ByteData;
618
P4ByteArrayList = ^T4ByteArrayList;
622
{ A list of T4ByteData. }
624
T4ByteList = class(TBaseList)
627
FList: P4ByteArrayList;
630
function Get(Index: Integer): T4ByteData;
631
procedure Put(Index: Integer; const item: T4ByteData);
632
procedure SetCapacity(NewCapacity: Integer); override;
635
constructor Create; override;
636
procedure Assign(Src: TPersistent); override;
638
function Add(const item: T4ByteData): Integer; overload;
639
procedure Add(const i1: Single); overload;
640
procedure Add(const i1, i2: Single); overload;
641
procedure Add(const i1, i2, i3: Single); overload;
642
procedure Add(const i1, i2, i3, i4: Single); overload;
643
procedure Add(const i1: Integer); overload;
644
procedure Add(const i1, i2: Integer); overload;
645
procedure Add(const i1, i2, i3: Integer); overload;
646
procedure Add(const i1, i2, i3, i4: Integer); overload;
647
procedure Add(const i1: Cardinal); overload;
648
procedure Add(const i1, i2: Cardinal); overload;
649
procedure Add(const i1, i2, i3: Cardinal); overload;
650
procedure Add(const i1, i2, i3, i4: Cardinal); overload;
651
procedure Add(const AList: T4ByteList); overload;
652
procedure Push(const Val: T4ByteData);
653
function Pop: T4ByteData;
654
procedure Insert(Index: Integer; const item: T4ByteData);
656
property Items[Index: Integer]: T4ByteData read Get write Put; default;
657
property List: P4ByteArrayList read FList;
662
TLongWordList = class(TBaseList)
665
FList: PLongWordArray;
669
function Get(Index: Integer): LongWord;
670
procedure Put(Index: Integer; const item: LongWord);
671
procedure SetCapacity(newCapacity: Integer); override;
675
constructor Create; override;
676
procedure Assign(src: TPersistent); override;
678
function Add(const item: LongWord): Integer; overload;
679
function AddNC(const item: LongWord): Integer; overload;
680
procedure Add(const i1, i2: LongWord); overload;
681
procedure Add(const i1, i2, i3: LongWord); overload;
682
procedure Add(const AList: TLongWordList); overload;
683
procedure Push(const Val: LongWord);
684
function Pop: LongWord;
685
procedure Insert(Index: Integer; const item: LongWord);
686
procedure Remove(const item: LongWord);
687
function IndexOf(item: Integer): LongWord;
689
property Items[Index: Integer]: LongWord read Get write Put; default;
690
property List: PLongWordArray read FList;
692
{ Add n integers at the address starting at (and including) first. }
693
procedure AddLongWords(const First: PLongWord; n: Integer); overload;
694
{ Add all integers from aList into the list. }
695
procedure AddLongWords(const aList: TLongWordList); overload;
696
{ Add all integers from anArray into the list. }
697
procedure AddLongWords(const anArray: array of LongWord); overload;
700
{ Sort the refList in ascending order, ordering objList (TList) on the way. }
701
procedure QuickSortLists(startIndex, endIndex: Integer; refList: TSingleList; objList: TList); overload;
703
{ Sort the refList in ascending order, ordering objList (TBaseList) on the way. }
704
procedure QuickSortLists(startIndex, endIndex: Integer; refList: TSingleList; objList: TBaseList); overload;
706
{ Sort the refList in ascending order, ordering objList on the way.
707
Use if, and *ONLY* if refList contains only values superior or equal to 1. }
708
procedure FastQuickSortLists(startIndex, endIndex: Integer; refList: TSingleList; objList: TPersistentObjectList);
710
// ------------------------------------------------------------------
711
// ------------------------------------------------------------------
712
// ------------------------------------------------------------------
714
// ------------------------------------------------------------------
715
// ------------------------------------------------------------------
716
// ------------------------------------------------------------------
719
cDefaultListGrowthDelta = 16;
721
// QuickSortLists (TList)
723
procedure QuickSortLists(startIndex, endIndex: Integer; refList: TSingleList; objList: TList);
728
if endIndex - startIndex > 1 then
733
P := refList.List^[(I + J) shr 1];
735
while Single(refList.List^[I]) < P do
737
while Single(refList.List^[J]) > P do
741
refList.Exchange(I, J);
742
objList.Exchange(I, J);
747
if startIndex < J then
748
QuickSortLists(startIndex, J, refList, objList);
753
if endIndex - startIndex > 0 then
755
p := refList.List^[startIndex];
756
if refList.List^[endIndex] < p then
758
refList.Exchange(startIndex, endIndex);
759
objList.Exchange(startIndex, endIndex);
764
// QuickSortLists (TBaseList)
766
procedure QuickSortLists(startIndex, endIndex: Integer; refList: TSingleList; objList: TBaseList);
771
if endIndex - startIndex > 1 then
776
P := refList.List^[(I + J) shr 1];
778
while Single(refList.List^[I]) < P do
780
while Single(refList.List^[J]) > P do
784
refList.Exchange(I, J);
785
objList.Exchange(I, J);
790
if startIndex < J then
791
QuickSortLists(startIndex, J, refList, objList);
796
if endIndex - startIndex > 0 then
798
p := refList.List^[startIndex];
799
if refList.List^[endIndex] < p then
801
refList.Exchange(startIndex, endIndex);
802
objList.Exchange(startIndex, endIndex);
809
procedure FastQuickSortLists(startIndex, endIndex: Integer; refList: TSingleList; objList: TPersistentObjectList);
815
oppl : PPointerArray;
817
// All singles are >=1, so IEEE format allows comparing them as if they were integers
818
ppl := PIntegerArray(@refList.List[0]);
819
oppl := PPointerArray(objList.List);
820
if endIndex > startIndex + 1 then
825
p := PInteger(@refList.List[(I + J) shr 1])^;
839
oppl^[I] := oppl^[J];
845
if startIndex < J then
846
FastQuickSortLists(startIndex, J, refList, objList);
851
if endIndex > startIndex then
853
if ppl^[endIndex] < ppl^[startIndex] then
863
oppl^[I] := oppl^[J];
870
// ------------------ TBaseList ------------------
875
constructor TBaseList.Create;
878
FOptions := [bloSetCountResetsMemory];
883
destructor TBaseList.Destroy;
886
if Assigned(FBufferItem) then
887
FreeMem(FBufferItem);
893
procedure TBaseList.Assign(Src: TPersistent);
895
if (Src is TBaseList) then
897
SetCapacity(TBaseList(Src).Count);
898
FGrowthDelta := TBaseList(Src).FGrowthDelta;
900
FTagString := TBaseList(Src).FTagString;
908
procedure TBaseList.DefineProperties(AFiler: TFiler);
910
inherited DefineProperties(AFiler);
911
AFiler.DefineProperty('Items', ReadItemsData, WriteItemsData, True);
915
procedure TBaseList.ReadItemsData(AReader: TReader);
920
lOutputText := AReader.ReadString;
921
SetLength(lData, Length(lOutputText) div 2 + 1);
922
HexToBin(PChar(lOutputText), PAnsiChar(lData), Length(lData));
923
LoadFromString(string(lData));
927
procedure TBaseList.WriteItemsData(AWriter: TWriter);
932
lData := AnsiString(SaveToString);
933
SetLength(lOutputText, Length(lData) * 2);
934
BinToHex(PAnsiChar(lData), PChar(lOutputText), Length(lData));
935
AWriter.WriteString(lOutputText);
940
procedure TBaseList.WriteToFiler(writer: TVirtualWriter);
945
WriteInteger(0); // Archive Version 0
947
WriteInteger(FItemSize);
949
write(FBaseList[0], Count * FItemSize);
955
procedure TBaseList.ReadFromFiler(reader: TVirtualReader);
957
archiveVersion: Integer;
960
archiveVersion := reader.ReadInteger;
961
if archiveVersion = 0 then
964
FCount := ReadInteger;
965
FItemSize := ReadInteger;
968
read(FBaseList[0], Count * FItemSize);
971
RaiseFilerException(archiveVersion);
977
procedure TBaseList.SetCount(Val: Integer);
980
if Val > FCapacity then
982
if (Val > FCount) and (bloSetCountResetsMemory in FOptions) then
983
FillChar(FBaseList[FItemSize * FCount], (Val - FCount) * FItemSize, 0);
990
procedure TBaseList.SetCapacity(newCapacity: Integer);
992
if newCapacity <> FCapacity then
994
if bloExternalMemory in FOptions then
996
Exclude(FOptions, bloExternalMemory);
999
ReallocMem(FBaseList, newCapacity * FItemSize);
1000
FCapacity := newCapacity;
1007
procedure TBaseList.AddNulls(nbVals: Cardinal);
1009
if Integer(nbVals) + Count > Capacity then
1010
SetCapacity(Integer(nbVals) + Count);
1011
FillChar(FBaseList[FCount * FItemSize], Integer(nbVals) * FItemSize, 0);
1012
FCount := FCount + Integer(nbVals);
1018
procedure TBaseList.InsertNulls(Index: Integer; nbVals: Cardinal);
1023
Assert(Cardinal(Index) < Cardinal(FCount));
1027
nc := FCount + Integer(nbVals);
1028
if nc > FCapacity then
1030
if Index < FCount then
1031
System.Move(FBaseList[Index * FItemSize],
1032
FBaseList[(Index + Integer(nbVals)) * FItemSize],
1033
(FCount - Index) * FItemSize);
1034
FillChar(FBaseList[Index * FItemSize], Integer(nbVals) * FItemSize, 0);
1040
// AdjustCapacityToAtLeast
1042
procedure TBaseList.AdjustCapacityToAtLeast(const size: Integer);
1044
if Capacity < size then
1051
function TBaseList.DataSize: Integer;
1053
Result := FItemSize * FCount;
1058
function TBaseList.BufferItem: PByteArray;
1060
if not Assigned(FBufferItem) then
1061
GetMem(FBufferItem, FItemSize);
1062
Result := FBufferItem;
1065
// GetSetCountResetsMemory
1067
function TBaseList.GetSetCountResetsMemory: Boolean;
1069
Result := (bloSetCountResetsMemory in FOptions);
1072
// SetSetCountResetsMemory
1074
procedure TBaseList.SetSetCountResetsMemory(const Val: Boolean);
1077
Include(FOptions, bloSetCountResetsMemory)
1079
Exclude(FOptions, bloSetCountResetsMemory);
1084
procedure TBaseList.UseMemory(rangeStart: Pointer; rangeCapacity: Integer);
1086
rangeCapacity := rangeCapacity div FItemSize;
1087
if rangeCapacity < FCount then
1090
System.Move(FBaseList^, rangeStart^, FCount * FItemSize);
1091
if not (bloExternalMemory in FOptions) then
1094
Include(FOptions, bloExternalMemory);
1096
FBaseList := rangeStart;
1097
FCapacity := rangeCapacity;
1098
SetCapacity(FCapacity); // notify subclasses
1103
procedure TBaseList.Flush;
1105
if Assigned(Self) then
1113
procedure TBaseList.Clear;
1115
if Assigned(Self) then
1124
procedure TBaseList.Delete(Index: Integer);
1127
Assert(Cardinal(index) < Cardinal(FCount));
1130
if Index < FCount then
1131
System.Move(FBaseList[(Index + 1) * FItemSize],
1132
FBaseList[Index * FItemSize],
1133
(FCount - Index) * FItemSize);
1139
procedure TBaseList.DeleteItems(Index: Integer; nbVals: Cardinal);
1142
Assert(Cardinal(index) < Cardinal(FCount));
1146
if Index + Integer(nbVals) < FCount then
1148
System.Move(FBaseList[(Index + Integer(nbVals)) * FItemSize],
1149
FBaseList[Index * FItemSize],
1150
(FCount - Index - Integer(nbVals)) * FItemSize);
1152
Dec(FCount, nbVals);
1159
procedure TBaseList.Exchange(index1, index2: Integer);
1165
Assert((Cardinal(index1) < Cardinal(FCount)) and (Cardinal(index2) < Cardinal(FCount)));
1167
if FItemSize = 4 then
1169
p := PIntegerArray(FBaseList);
1171
p^[index1] := p^[index2];
1176
System.Move(FBaseList[index1 * FItemSize], BufferItem[0], FItemSize);
1177
System.Move(FBaseList[index2 * FItemSize], FBaseList[index1 * FItemSize], FItemSize);
1178
System.Move(BufferItem[0], FBaseList[index2 * FItemSize], FItemSize);
1185
procedure TBaseList.Move(curIndex, newIndex: Integer);
1187
if curIndex <> newIndex then
1190
Assert(Cardinal(newIndex) < Cardinal(Count));
1191
Assert(Cardinal(curIndex) < Cardinal(Count));
1193
if FItemSize = 4 then
1194
PInteger(BufferItem)^ := PInteger(@FBaseList[curIndex * FItemSize])^
1196
System.Move(FBaseList[curIndex * FItemSize], BufferItem[0], FItemSize);
1197
if curIndex < newIndex then
1199
// curIndex+1 necessarily exists since curIndex<newIndex and newIndex<Count
1200
System.Move(FBaseList[(curIndex + 1) * FItemSize], FBaseList[curIndex * FItemSize],
1201
(newIndex - curIndex - 1) * FItemSize);
1205
// newIndex+1 necessarily exists since newIndex<curIndex and curIndex<Count
1206
System.Move(FBaseList[newIndex * FItemSize], FBaseList[(newIndex + 1) * FItemSize],
1207
(curIndex - newIndex - 1) * FItemSize);
1209
if FItemSize = 4 then
1210
PInteger(@FBaseList[newIndex * FItemSize])^ := PInteger(BufferItem)^
1212
System.Move(BufferItem[0], FBaseList[newIndex * FItemSize], FItemSize);
1219
procedure TBaseList.Reverse;
1234
// ------------------
1235
// ------------------ TBaseVectorList ------------------
1236
// ------------------
1240
procedure TBaseVectorList.WriteToFiler(writer: TVirtualWriter);
1243
if Self is TTexPointList then
1247
WriteInteger(0); // Archive Version 0
1254
procedure TBaseVectorList.ReadFromFiler(reader: TVirtualReader);
1256
archiveVersion: Integer;
1259
if Self is TTexPointList then
1261
archiveVersion := reader.ReadInteger;
1262
if archiveVersion = 0 then
1268
RaiseFilerException(archiveVersion);
1273
procedure TBaseVectorList.GetExtents(out min, max: TAffineVector);
1279
cBigValue: Single = 1E50;
1280
cSmallValue: Single = -1E50;
1282
SetVector(min, cBigValue, cBigValue, cBigValue);
1283
SetVector(max, cSmallValue, cSmallValue, cSmallValue);
1284
for I := 0 to Count - 1 do
1286
ref := ItemAddress[I];
1290
if f < min.V[K] then
1292
if f > max.V[K] then
1300
function TBaseVectorList.Sum: TAffineVector;
1304
Result := NullVector;
1305
for I := 0 to Count - 1 do
1306
AddVector(Result, PAffineVector(ItemAddress[I])^);
1311
procedure TBaseVectorList.Normalize;
1315
for I := 0 to Count - 1 do
1316
NormalizeVector(PAffineVector(ItemAddress[I])^);
1322
function TBaseVectorList.MaxSpacing(list2: TBaseVectorList): Single;
1327
Assert(list2.Count = Count);
1329
for I := 0 to Count - 1 do
1331
s := VectorSpacing(PAffineVector(ItemAddress[I])^,
1332
PAffineVector(list2.ItemAddress[I])^);
1340
procedure TBaseVectorList.Translate(const delta: TAffineVector);
1344
for I := 0 to Count - 1 do
1345
AddVector(PAffineVector(ItemAddress[I])^, delta);
1349
// Translate (TBaseVectorList)
1351
procedure TBaseVectorList.Translate(const delta: TBaseVectorList);
1355
Assert(Count <= delta.Count);
1356
for I := 0 to Count - 1 do
1357
AddVector(PAffineVector(ItemAddress[I])^, PAffineVector(delta.ItemAddress[I])^);
1361
// TranslateInv (TBaseVectorList)
1363
procedure TBaseVectorList.TranslateInv(const delta: TBaseVectorList);
1367
Assert(Count <= delta.Count);
1368
for I := 0 to Count - 1 do
1369
SubtractVector(PAffineVector(ItemAddress[I])^, PAffineVector(delta.ItemAddress[I])^);
1375
procedure TBaseVectorList.AngleLerp(const list1, list2: TBaseVectorList; lerpFactor: Single);
1379
Assert(list1.Count = list2.Count);
1380
if list1 <> list2 then
1382
if lerpFactor = 0 then
1385
if lerpFactor = 1 then
1389
Capacity := list1.Count;
1390
FCount := list1.Count;
1391
for I := 0 to list1.Count - 1 do
1392
PAffineVector(ItemAddress[I])^ := VectorAngleLerp(PAffineVector(list1.ItemAddress[I])^,
1393
PAffineVector(list2.ItemAddress[I])^,
1404
procedure TBaseVectorList.AngleCombine(const list1: TBaseVectorList; intensity: Single);
1408
Assert(list1.Count = Count);
1409
for I := 0 to Count - 1 do
1410
PAffineVector(ItemAddress[I])^ := VectorAngleCombine(PAffineVector(ItemAddress[I])^,
1411
PAffineVector(list1.ItemAddress[I])^,
1418
procedure TBaseVectorList.Combine(const list2: TBaseVectorList; factor: Single);
1422
Assert(list2.Count >= Count);
1423
for I := 0 to Count - 1 do
1424
CombineVector(PAffineVector(ItemAddress[I])^,
1425
PAffineVector(list2.ItemAddress[I])^,
1432
function TBaseVectorList.GetItemAddress(Index: Integer): PFloatArray;
1435
Assert(Cardinal(Index) < Cardinal(FCount));
1437
Result := PFloatArray(@FBaseList[Index * FItemSize]);
1440
// ------------------
1441
// ------------------ TAffineVectorList ------------------
1442
// ------------------
1446
constructor TAffineVectorList.Create;
1448
FItemSize := SizeOf(TAffineVector);
1450
FGrowthDelta := cDefaultListGrowthDelta;
1455
procedure TAffineVectorList.Assign(Src: TPersistent);
1457
if Assigned(Src) then
1460
if (Src is TAffineVectorList) then
1461
System.Move(TAffineVectorList(Src).FList^, FList^, FCount * SizeOf(TAffineVector));
1469
function TAffineVectorList.Add(const item: TAffineVector): Integer;
1472
if Result = FCapacity then
1473
SetCapacity(FCapacity + FGrowthDelta);
1474
FList^[Result] := Item;
1481
function TAffineVectorList.Add(const item: TVector): Integer;
1483
Result := Add(PAffineVector(@item)^);
1488
procedure TAffineVectorList.Add(const i1, i2: TAffineVector);
1491
while FCount > FCapacity do
1492
SetCapacity(FCapacity + FGrowthDelta);
1493
FList^[FCount - 2] := i1;
1494
FList^[FCount - 1] := i2;
1500
procedure TAffineVectorList.Add(const i1, i2, i3: TAffineVector);
1503
while FCount > FCapacity do
1504
SetCapacity(FCapacity + FGrowthDelta);
1505
FList^[FCount - 3] := i1;
1506
FList^[FCount - 2] := i2;
1507
FList^[FCount - 1] := i3;
1513
function TAffineVectorList.Add(const item: TVector2f): Integer;
1515
Result := Add(AffineVectorMake(item.V[0], item.V[1], 0));
1520
function TAffineVectorList.Add(const item: TTexPoint): Integer;
1522
Result := Add(AffineVectorMake(item.S, item.T, 0));
1527
function TAffineVectorList.Add(const X, Y: Single): Integer;
1533
while FCount > FCapacity do
1534
SetCapacity(FCapacity + FGrowthDelta);
1544
function TAffineVectorList.Add(const X, Y, Z: Single): Integer;
1550
while FCount > FCapacity do
1551
SetCapacity(FCapacity + FGrowthDelta);
1561
function TAffineVectorList.Add(const X, Y, Z: Integer): Integer;
1566
if Result = FCapacity then
1567
SetCapacity(FCapacity + FGrowthDelta);
1576
// Add (3 ints, no capacity check)
1578
function TAffineVectorList.AddNC(const X, Y, Z: Integer): Integer;
1591
// Add (2 ints in array + 1)
1593
function TAffineVectorList.Add(const xy: PIntegerArray; const Z: Integer): Integer;
1598
if Result = FCapacity then
1599
SetCapacity(FCapacity + FGrowthDelta);
1608
// AddNC (2 ints in array + 1, no capacity check)
1610
function TAffineVectorList.AddNC(const xy: PIntegerArray; const Z: Integer): Integer;
1625
procedure TAffineVectorList.Add(const list: TAffineVectorList);
1627
if Assigned(list) and (list.Count > 0) then
1629
if Count + list.Count > Capacity then
1630
Capacity := Count + list.Count;
1631
System.Move(list.FList[0], FList[Count], list.Count * SizeOf(TAffineVector));
1632
Inc(FCount, list.Count);
1639
function TAffineVectorList.Get(Index: Integer): TAffineVector;
1642
Assert(Cardinal(Index) < Cardinal(FCount));
1644
Result := FList^[Index];
1649
procedure TAffineVectorList.Insert(Index: Integer; const Item: TAffineVector);
1652
Assert(Cardinal(Index) < Cardinal(FCount));
1654
if FCount = FCapacity then
1655
SetCapacity(FCapacity + FGrowthDelta);
1656
if Index < FCount then
1657
System.Move(FList[Index], FList[Index + 1],
1658
(FCount - Index) * SizeOf(TAffineVector));
1659
FList^[Index] := Item;
1666
function TAffineVectorList.IndexOf(const item: TAffineVector): Integer;
1671
for I := 0 to Count - 1 do
1672
if VectorEquals(item, FList^[I]) then
1681
function TAffineVectorList.FindOrAdd(const item: TAffineVector): Integer;
1683
Result := IndexOf(item);
1686
Result := Add(item);
1693
procedure TAffineVectorList.Put(Index: Integer; const Item: TAffineVector);
1696
Assert(Cardinal(Index) < Cardinal(FCount));
1698
FList^[Index] := Item;
1704
procedure TAffineVectorList.SetCapacity(NewCapacity: Integer);
1707
FList := PAffineVectorArray(FBaseList);
1712
procedure TAffineVectorList.Push(const Val: TAffineVector);
1719
function TAffineVectorList.Pop: TAffineVector;
1723
Result := Get(FCount - 1);
1728
Result := NullVector;
1733
procedure TAffineVectorList.Translate(const delta: TAffineVector);
1735
VectorArrayAdd(FList, delta, Count, FList);
1739
// Translate (delta, range)
1741
procedure TAffineVectorList.Translate(const delta: TAffineVector; base, nb: Integer);
1743
VectorArrayAdd(@FList[base], delta, nb, @FList[base]);
1750
procedure TAffineVectorList.TranslateItem(Index: Integer; const delta: TAffineVector);
1753
Assert(Cardinal(Index) < Cardinal(FCount));
1755
AddVector(FList^[Index], delta);
1761
procedure TAffineVectorList.TranslateItems(Index: Integer; const delta: TAffineVector; nb: Integer);
1765
Assert(Cardinal(index) < Cardinal(FCount));
1769
VectorArrayAdd(@FList[Index], delta, nb - Index, @FList[Index]);
1775
procedure TAffineVectorList.CombineItem(Index: Integer; const vector: TAffineVector; const f: Single);
1778
Assert(Cardinal(Index) < Cardinal(FCount));
1780
CombineVector(FList^[Index], vector, @f);
1786
procedure TAffineVectorList.TransformAsPoints(const matrix: TMatrix);
1790
for I := 0 to FCount - 1 do
1791
FList^[I] := VectorTransform(FList^[I], matrix);
1795
// TransformAsVectors (hmg)
1797
procedure TAffineVectorList.TransformAsVectors(const matrix: TMatrix);
1803
SetMatrix(m, matrix);
1804
TransformAsVectors(m);
1808
// TransformAsVectors (affine)
1811
procedure TAffineVectorList.TransformAsVectors(const matrix: TAffineMatrix);
1815
for I := 0 to FCount - 1 do
1816
FList^[I] := VectorTransform(FList^[I], matrix);
1822
procedure TAffineVectorList.Normalize;
1824
NormalizeVectorArray(List, Count);
1830
procedure TAffineVectorList.Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single);
1832
if (list1 is TAffineVectorList) and (list2 is TAffineVectorList) then
1834
Assert(list1.Count = list2.Count);
1835
Capacity := list1.Count;
1836
FCount := list1.Count;
1837
VectorArrayLerp(TAffineVectorList(list1).List, TAffineVectorList(list2).List,
1838
lerpFactor, FCount, List);
1845
procedure TAffineVectorList.Scale(factor: Single);
1847
if (Count > 0) and (factor <> 1) then
1849
ScaleFloatArray(@FList[0].V[0], Count * 3, factor);
1856
procedure TAffineVectorList.Scale(const factors: TAffineVector);
1860
for I := 0 to Count - 1 do
1861
ScaleVector(FList^[I], factors);
1865
// ------------------
1866
// ------------------ TVectorList ------------------
1867
// ------------------
1872
constructor TVectorList.Create;
1874
FItemSize := SizeOf(TVector);
1876
FGrowthDelta := cDefaultListGrowthDelta;
1882
procedure TVectorList.Assign(Src: TPersistent);
1884
if Assigned(Src) then
1887
if (Src is TVectorList) then
1888
System.Move(TVectorList(Src).FList^, FList^, FCount * SizeOf(TVector));
1897
function TVectorList.Add(const item: TVector): Integer;
1900
if Result = FCapacity then
1901
SetCapacity(FCapacity + FGrowthDelta);
1902
FList^[Result] := Item;
1909
function TVectorList.Add(const item: TAffineVector; w: Single): Integer;
1911
Result := Add(VectorMake(item, w));
1917
function TVectorList.Add(const X, Y, Z, w: Single): Integer;
1919
Result := Add(VectorMake(X, Y, Z, w));
1925
procedure TVectorList.Add(const i1, i2, i3: TAffineVector; w: Single);
1928
while FCount > FCapacity do
1929
SetCapacity(FCapacity + FGrowthDelta);
1930
PAffineVector(@FList[FCount - 3])^ := i1;
1931
FList^[FCount - 3].V[3] := w;
1932
PAffineVector(@FList[FCount - 2])^ := i2;
1933
FList^[FCount - 2].V[3] := w;
1934
PAffineVector(@FList[FCount - 1])^ := i3;
1935
FList^[FCount - 1].V[3] := w;
1941
function TVectorList.AddVector(const item: TAffineVector): Integer;
1943
Result := Add(VectorMake(item));
1949
function TVectorList.AddPoint(const item: TAffineVector): Integer;
1951
Result := Add(PointMake(item));
1957
function TVectorList.AddPoint(const X, Y: Single; const Z: Single = 0): Integer;
1959
Result := Add(PointMake(X, Y, Z));
1965
function TVectorList.Get(Index: Integer): TVector;
1968
Assert(Cardinal(Index) < Cardinal(FCount));
1970
Result := FList^[Index];
1976
procedure TVectorList.Insert(Index: Integer; const Item: TVector);
1979
Assert(Cardinal(Index) < Cardinal(FCount));
1981
if FCount = FCapacity then
1982
SetCapacity(FCapacity + FGrowthDelta);
1983
if Index < FCount then
1984
System.Move(FList[Index], FList[Index + 1],
1985
(FCount - Index) * SizeOf(TVector));
1986
FList^[Index] := Item;
1993
procedure TVectorList.Put(Index: Integer; const Item: TVector);
1996
Assert(Cardinal(Index) < Cardinal(FCount));
1998
FList^[Index] := Item;
2004
procedure TVectorList.SetCapacity(NewCapacity: Integer);
2007
FList := PVectorArray(FBaseList);
2013
procedure TVectorList.Push(const Val: TVector);
2021
function TVectorList.Pop: TVector;
2025
Result := Get(FCount - 1);
2029
Result := NullHmgVector;
2035
function TVectorList.IndexOf(const item: TVector): Integer;
2040
for I := 0 to Count - 1 do
2041
if VectorEquals(item, FList^[I]) then
2051
function TVectorList.FindOrAdd(const item: TVector): Integer;
2053
Result := IndexOf(item);
2055
Result := Add(item);
2061
function TVectorList.FindOrAddPoint(const item: TAffineVector): Integer;
2065
MakePoint(ptItem, item);
2066
Result := IndexOf(ptItem);
2068
Result := Add(ptItem);
2074
procedure TVectorList.Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single);
2076
if (list1 is TVectorList) and (list2 is TVectorList) then
2078
Assert(list1.Count = list2.Count);
2079
Capacity := list1.Count;
2080
FCount := list1.Count;
2081
VectorArrayLerp(TVectorList(list1).List, TVectorList(list2).List,
2082
lerpFactor, FCount, List);
2086
// ------------------
2087
// ------------------ TTexPointList ------------------
2088
// ------------------
2093
constructor TTexPointList.Create;
2095
FItemSize := SizeOf(TTexPoint);
2097
FGrowthDelta := cDefaultListGrowthDelta;
2103
procedure TTexPointList.Assign(Src: TPersistent);
2105
if Assigned(Src) then
2108
if (Src is TTexPointList) then
2109
System.Move(TTexPointList(Src).FList^, FList^, FCount * SizeOf(TTexPoint));
2118
function TTexPointList.IndexOf(const item: TTexpoint): Integer;
2123
for I := 0 to Count - 1 do
2124
if TexpointEquals(FList^[I], item) then
2134
function TTexPointList.FindOrAdd(const item: TTexPoint): Integer;
2136
Result := IndexOf(item);
2138
Result := Add(item);
2144
function TTexPointList.Add(const item: TTexPoint): Integer;
2147
if Result = FCapacity then
2148
SetCapacity(FCapacity + FGrowthDelta);
2149
FList^[Result] := Item;
2156
function TTexPointList.Add(const item: TVector2f): Integer;
2159
if Result = FCapacity then
2160
SetCapacity(FCapacity + FGrowthDelta);
2161
FList^[Result] := PTexPoint(@Item)^;
2168
function TTexPointList.Add(const texS, Text: Single): Integer;
2171
if Result = FCapacity then
2172
SetCapacity(FCapacity + FGrowthDelta);
2173
with FList^[Result] do
2184
function TTexPointList.Add(const texS, Text: Integer): Integer;
2187
if Result = FCapacity then
2188
SetCapacity(FCapacity + FGrowthDelta);
2189
with FList^[Result] do
2200
function TTexPointList.AddNC(const texS, Text: Integer): Integer;
2203
with FList^[Result] do
2214
function TTexPointList.Add(const texST: PIntegerArray): Integer;
2217
if Result = FCapacity then
2218
SetCapacity(FCapacity + FGrowthDelta);
2219
with FList^[Result] do
2230
function TTexPointList.AddNC(const texST: PIntegerArray): Integer;
2233
with FList^[Result] do
2244
function TTexPointList.Get(Index: Integer): TTexPoint;
2247
Assert(Cardinal(Index) < Cardinal(FCount));
2249
Result := FList^[Index];
2255
procedure TTexPointList.Insert(Index: Integer; const Item: TTexPoint);
2258
Assert(Cardinal(Index) < Cardinal(FCount));
2260
if FCount = FCapacity then
2261
SetCapacity(FCapacity + FGrowthDelta);
2262
if Index < FCount then
2263
System.Move(FList[Index], FList[Index + 1],
2264
(FCount - Index) * SizeOf(TTexPoint));
2265
FList^[Index] := Item;
2272
procedure TTexPointList.Put(Index: Integer; const Item: TTexPoint);
2275
Assert(Cardinal(Index) < Cardinal(FCount));
2277
FList^[Index] := Item;
2283
procedure TTexPointList.SetCapacity(NewCapacity: Integer);
2286
FList := PTexPointArray(FBaseList);
2292
procedure TTexPointList.Push(const Val: TTexPoint);
2300
function TTexPointList.Pop: TTexPoint;
2304
Result := Get(FCount - 1);
2308
Result := NullTexPoint;
2314
procedure TTexPointList.Translate(const delta: TTexPoint);
2316
TexPointArrayAdd(List, delta, FCount, FList);
2322
procedure TTexPointList.ScaleAndTranslate(const scale, delta: TTexPoint);
2324
TexPointArrayScaleAndAdd(FList, delta, FCount, scale, FList);
2330
procedure TTexPointList.ScaleAndTranslate(const scale, delta: TTexPoint; base, nb: Integer);
2335
TexPointArrayScaleAndAdd(p, delta, nb, scale, p);
2341
procedure TTexPointList.Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single);
2343
if (list1 is TTexPointList) and (list2 is TTexPointList) then
2345
Assert(list1.Count = list2.Count);
2346
Capacity := list1.Count;
2347
FCount := list1.Count;
2348
VectorArrayLerp(TTexPointList(list1).List, TTexPointList(list2).List,
2349
lerpFactor, FCount, List);
2353
// ------------------
2354
// ------------------ TIntegerList ------------------
2355
// ------------------
2360
constructor TIntegerList.Create;
2362
FItemSize := SizeOf(Integer);
2364
FGrowthDelta := cDefaultListGrowthDelta;
2370
procedure TIntegerList.Assign(Src: TPersistent);
2372
if Assigned(Src) then
2375
if (Src is TIntegerList) then
2376
System.Move(TIntegerList(Src).FList^, FList^, FCount * SizeOf(Integer));
2385
function TIntegerList.Add(const item: Integer): Integer;
2388
if Result = FCapacity then
2389
SetCapacity(FCapacity + FGrowthDelta);
2390
FList^[Result] := Item;
2394
// AddNC (simple, no capacity check)
2397
function TIntegerList.AddNC(const item: Integer): Integer;
2400
FList^[Result] := Item;
2407
procedure TIntegerList.Add(const i1, i2: Integer);
2409
tmpList : PIntegerArray;
2412
while FCount > FCapacity do
2413
SetCapacity(FCapacity + FGrowthDelta);
2414
tmpList := @FList[FCount - 2];
2419
// Add (three at once)
2422
procedure TIntegerList.Add(const i1, i2, i3: Integer);
2424
tmpList : PIntegerArray;
2427
while FCount > FCapacity do
2428
SetCapacity(FCapacity + FGrowthDelta);
2429
tmpList := @FList[FCount - 3];
2438
procedure TIntegerList.Add(const AList: TIntegerList);
2440
if Assigned(AList) and (AList.Count > 0) then
2442
if Count + AList.Count > Capacity then
2443
Capacity := Count + AList.Count;
2444
System.Move(AList.FList[0], FList[Count], AList.Count * SizeOf(Integer));
2445
Inc(FCount, AList.Count);
2452
function TIntegerList.Get(Index: Integer): Integer;
2455
Assert(Cardinal(Index) < Cardinal(FCount));
2457
Result := FList^[Index];
2463
procedure TIntegerList.Insert(Index: Integer; const Item: Integer);
2466
Assert(Cardinal(Index) < Cardinal(FCount));
2468
if FCount = FCapacity then
2469
SetCapacity(FCapacity + FGrowthDelta);
2470
if Index < FCount then
2471
System.Move(FList[Index], FList[Index + 1], (FCount - Index) * SizeOf(Integer));
2472
FList^[Index] := Item;
2479
procedure TIntegerList.Remove(const item: Integer);
2483
for I := 0 to Count - 1 do
2485
if FList^[I] = item then
2487
System.Move(FList[I + 1], FList[I], (FCount - 1 - I) * SizeOf(Integer));
2497
procedure TIntegerList.Put(Index: Integer; const Item: Integer);
2500
Assert(Cardinal(Index) < Cardinal(FCount));
2502
FList^[Index] := Item;
2508
procedure TIntegerList.SetCapacity(NewCapacity: Integer);
2511
FList := PIntegerArray(FBaseList);
2517
procedure TIntegerList.Push(const Val: Integer);
2525
function TIntegerList.Pop: Integer;
2529
Result := FList^[FCount - 1];
2539
procedure TIntegerList.AddSerie(aBase, aDelta, aCount: Integer);
2546
AdjustCapacityToAtLeast(Count + aCount);
2547
tmpList := @FList[Count];
2548
for I := Count to Count + aCount - 1 do
2552
aBase := aBase + aDelta;
2554
FCount := Count + aCount;
2557
// AddIntegers (pointer & n)
2560
procedure TIntegerList.AddIntegers(const First: PInteger; n: Integer);
2564
AdjustCapacityToAtLeast(Count + n);
2565
System.Move(First^, FList[FCount], n * SizeOf(Integer));
2566
FCount := FCount + n;
2569
// AddIntegers (TIntegerList)
2572
procedure TIntegerList.AddIntegers(const aList: TIntegerList);
2574
if not Assigned(aList) then
2576
AddIntegers(@aList.List[0], aList.Count);
2579
// AddIntegers (array)
2582
procedure TIntegerList.AddIntegers(const anArray: array of Integer);
2586
n := Length(anArray);
2588
AddIntegers(@anArray[0], n);
2594
function IntegerSearch(item: Integer; list: PIntegerVector; Count: Integer): Integer; register;
2599
for i := 0 to Count-1 do begin
2600
if list^[i]=item then begin
2636
function TIntegerList.IndexOf(item: Integer): Integer; register;
2638
Result := IntegerSearch(item, FList, FCount);
2644
function TIntegerList.MinInteger: Integer;
2647
locList: PIntegerVector;
2652
Result := locList^[0];
2653
for I := 1 to FCount - 1 do
2654
if locList^[I] < Result then
2655
Result := locList^[I];
2664
function TIntegerList.MaxInteger: Integer;
2667
locList: PIntegerVector;
2672
Result := locList^[0];
2673
for I := 1 to FCount - 1 do
2674
if locList^[I] > Result then
2675
Result := locList^[I];
2684
procedure IntegerQuickSort(sortList: PIntegerArray; left, right: Integer);
2692
p := sortList^[(left + right) shr 1];
2694
while sortList^[I] < p do
2696
while sortList^[J] > p do
2701
sortList^[I] := sortList^[J];
2708
IntegerQuickSort(sortList, left, J);
2716
procedure TIntegerList.Sort;
2718
if (FList <> nil) and (Count > 1) then
2719
IntegerQuickSort(FList, 0, Count - 1);
2722
// SortAndRemoveDuplicates
2725
procedure TIntegerList.SortAndRemoveDuplicates;
2727
I, J, lastVal: Integer;
2728
localList: PIntegerArray;
2730
if (FList <> nil) and (Count > 1) then
2732
IntegerQuickSort(FList, 0, Count - 1);
2735
lastVal := localList^[J];
2736
for I := 1 to Count - 1 do
2738
if localList^[I] <> lastVal then
2740
lastVal := localList^[I];
2742
localList^[J] := lastVal;
2752
function TIntegerList.BinarySearch(const Value: Integer): Integer;
2756
Result := BinarySearch(Value, False, found);
2762
function TIntegerList.BinarySearch(const Value: Integer; returnBestFit: Boolean; var found: Boolean): Integer;
2765
min, max, mid: Integer;
2766
intList: PIntegerArray;
2768
// Assume we won't find it
2770
// If the list is empty, we won't find the sought value!
2777
min := -1; // ONE OFF!
2778
max := Count; // ONE OFF!
2780
// We now know that Min and Max AREN'T the values!
2784
// Find the middle of the current scope
2785
mid := (min + max) shr 1;
2786
// Reduce the search scope by half
2787
if intList^[mid] <= Value then
2790
if intList^[mid] = Value then
2801
until min + 1 = max;
2803
if returnBestFit then
2817
function TIntegerList.AddSorted(const Value: Integer; const ignoreDuplicates: Boolean = False): Integer;
2822
Index := BinarySearch(Value, True, found);
2823
if ignoreDuplicates and Found then
2827
Insert(Index + 1, Value);
2828
Result := Index + 1;
2835
procedure TIntegerList.RemoveSorted(const Value: Integer);
2839
Index := BinarySearch(Value);
2847
procedure TIntegerList.Offset(delta: Integer);
2850
locList: PIntegerArray;
2853
for I := 0 to FCount - 1 do
2854
locList^[I] := locList^[I] + delta;
2860
procedure TIntegerList.Offset(delta: Integer; const base, nb: Integer);
2863
locList: PIntegerArray;
2866
for I := base to base + nb - 1 do
2867
locList^[I] := locList^[I] + delta;
2870
// ------------------
2871
// ------------------ TSingleList ------------------
2872
// ------------------
2877
constructor TSingleList.Create;
2879
FItemSize := SizeOf(Single);
2881
FGrowthDelta := cDefaultListGrowthDelta;
2887
procedure TSingleList.Assign(Src: TPersistent);
2889
if Assigned(Src) then
2892
if (Src is TSingleList) then
2893
System.Move(TSingleList(Src).FList^, FList^, FCount * SizeOf(Single));
2902
function TSingleList.Add(const item: Single): Integer;
2905
if Result = FCapacity then
2906
SetCapacity(FCapacity + FGrowthDelta);
2907
FList^[Result] := Item;
2911
procedure TSingleList.Add(const i1, i2: Single);
2913
tmpList : PSingleArray;
2916
while FCount > FCapacity do
2917
SetCapacity(FCapacity + FGrowthDelta);
2918
tmpList := @FList[FCount - 2];
2923
procedure TSingleList.AddSingles(const First: PSingle; n: Integer);
2927
AdjustCapacityToAtLeast(Count + n);
2928
System.Move(First^, FList[FCount], n * SizeOf(Single));
2929
FCount := FCount + n;
2932
procedure TSingleList.AddSingles(const anArray: array of Single);
2936
n := Length(anArray);
2938
AddSingles(@anArray[0], n);
2944
function TSingleList.Get(Index: Integer): Single;
2947
Assert(Cardinal(Index) < Cardinal(FCount));
2949
Result := FList^[Index];
2955
procedure TSingleList.Insert(Index: Integer; const Item: Single);
2958
Assert(Cardinal(Index) < Cardinal(FCount));
2960
if FCount = FCapacity then
2961
SetCapacity(FCapacity + FGrowthDelta);
2962
if Index < FCount then
2963
System.Move(FList[Index], FList[Index + 1],
2964
(FCount - Index) * SizeOf(Single));
2965
FList^[Index] := Item;
2972
procedure TSingleList.Put(Index: Integer; const Item: Single);
2975
Assert(Cardinal(Index) < Cardinal(FCount));
2977
FList^[Index] := Item;
2983
procedure TSingleList.SetCapacity(NewCapacity: Integer);
2986
FList := PSingleArrayList(FBaseList);
2992
procedure TSingleList.Push(const Val: Single);
3000
function TSingleList.Pop: Single;
3004
Result := Get(FCount - 1);
3014
procedure TSingleList.AddSerie(aBase, aDelta: Single; aCount: Integer);
3021
AdjustCapacityToAtLeast(Count + aCount);
3022
tmpList := @FList[Count];
3023
for I := Count to Count + aCount - 1 do
3027
aBase := aBase + aDelta;
3029
FCount := Count + aCount;
3035
procedure TSingleList.Offset(delta: Single);
3037
OffsetFloatArray(PFloatVector(FList), FCount, delta);
3043
procedure TSingleList.Offset(const delta: TSingleList);
3045
if FCount = delta.FCount then
3046
OffsetFloatArray(PFloatVector(FList), PFloatVector(delta.FList), FCount)
3048
raise Exception.Create('SingleList count do not match');
3054
procedure TSingleList.Scale(factor: Single);
3056
ScaleFloatArray(PFloatVector(FList), FCount, factor);
3062
procedure TSingleList.Sqr;
3065
locList: PSingleArrayList;
3068
for I := 0 to Count - 1 do
3069
locList^[I] := locList^[I] * locList^[I];
3075
procedure TSingleList.Sqrt;
3078
locList: PSingleArrayList;
3081
for I := 0 to Count - 1 do
3082
locList^[I] := System.Sqrt(locList^[I]);
3088
function TSingleList.Sum: Single;
3090
function ComputeSum(list: PSingleArrayList; nb: Integer): Single; register;
3095
fadd dword ptr [eax+edx*4]
3101
Result := ComputeSum(FList, FCount)
3109
for i := 0 to FCount-1 do
3110
Result := Result + FList^[i];
3116
function TSingleList.Min: Single;
3119
locList: PSingleArrayList;
3124
Result := locList^[0];
3125
for I := 1 to FCount - 1 do
3126
if locList^[I] < Result then
3127
Result := locList^[I];
3135
function TSingleList.Max: Single;
3138
locList: PSingleArrayList;
3143
Result := locList^[0];
3144
for I := 1 to FCount - 1 do
3145
if locList^[I] > Result then
3146
Result := locList^[I];
3152
// ------------------
3153
// ------------------ TByteList ------------------
3154
// ------------------
3159
constructor TByteList.Create;
3161
FItemSize := SizeOf(Byte);
3163
FGrowthDelta := cDefaultListGrowthDelta;
3169
procedure TByteList.Assign(Src: TPersistent);
3171
if Assigned(Src) then
3174
if (Src is TByteList) then
3175
System.Move(TByteList(Src).FList^, FList^, FCount * SizeOf(Byte));
3184
function TByteList.Add(const item: Byte): Integer;
3187
if Result = FCapacity then
3188
SetCapacity(FCapacity + FGrowthDelta);
3189
FList^[Result] := Item;
3196
function TByteList.Get(Index: Integer): Byte;
3199
Assert(Cardinal(Index) < Cardinal(FCount));
3201
Result := FList^[Index];
3207
procedure TByteList.Insert(Index: Integer; const Item: Byte);
3210
Assert(Cardinal(Index) < Cardinal(FCount));
3212
if FCount = FCapacity then
3213
SetCapacity(FCapacity + FGrowthDelta);
3214
if Index < FCount then
3215
System.Move(FList[Index], FList[Index + 1],
3216
(FCount - Index) * SizeOf(Byte));
3217
FList^[Index] := Item;
3224
procedure TByteList.Put(Index: Integer; const Item: Byte);
3227
Assert(Cardinal(Index) < Cardinal(FCount));
3229
FList^[Index] := Item;
3235
procedure TByteList.SetCapacity(NewCapacity: Integer);
3238
FList := PByteArray(FBaseList);
3241
// ------------------
3242
// ------------------ TDoubleList ------------------
3243
// ------------------
3248
constructor TDoubleList.Create;
3250
FItemSize := SizeOf(Double);
3252
FGrowthDelta := cDefaultListGrowthDelta;
3258
procedure TDoubleList.Assign(Src: TPersistent);
3260
if Assigned(Src) then
3263
if (Src is TDoubleList) then
3264
System.Move(TDoubleList(Src).FList^, FList^, FCount * SizeOf(Double));
3273
function TDoubleList.Add(const item: Double): Integer;
3276
if Result = FCapacity then
3277
SetCapacity(FCapacity + FGrowthDelta);
3278
FList^[Result] := Item;
3285
function TDoubleList.Get(Index: Integer): Double;
3288
Assert(Cardinal(Index) < Cardinal(FCount));
3290
Result := FList^[Index];
3296
procedure TDoubleList.Insert(Index: Integer; const Item: Double);
3299
Assert(Cardinal(Index) < Cardinal(FCount));
3301
if FCount = FCapacity then
3302
SetCapacity(FCapacity + FGrowthDelta);
3303
if Index < FCount then
3304
System.Move(FList[Index], FList[Index + 1],
3305
(FCount - Index) * SizeOf(Double));
3306
FList^[Index] := Item;
3313
procedure TDoubleList.Put(Index: Integer; const Item: Double);
3316
Assert(Cardinal(Index) < Cardinal(FCount));
3318
FList^[Index] := Item;
3324
procedure TDoubleList.SetCapacity(NewCapacity: Integer);
3327
FList := PDoubleArrayList(FBaseList);
3333
procedure TDoubleList.Push(const Val: Double);
3341
function TDoubleList.Pop: Double;
3345
Result := Get(FCount - 1);
3355
procedure TDoubleList.AddSerie(aBase, aDelta: Double; aCount: Integer);
3362
AdjustCapacityToAtLeast(Count + aCount);
3363
tmpList := @FList[Count];
3364
for I := Count to Count + aCount - 1 do
3368
aBase := aBase + aDelta;
3370
FCount := Count + aCount;
3376
procedure TDoubleList.Offset(delta: Double);
3380
for I := 0 to Count - 1 do
3381
FList^[I] := FList^[I] + delta;
3387
procedure TDoubleList.Offset(const delta: TDoubleList);
3391
if FCount = delta.FCount then
3392
for I := 0 to Count - 1 do
3393
FList^[I] := FList^[I] + delta[I]
3395
raise Exception.Create('DoubleList count do not match');
3401
procedure TDoubleList.Scale(factor: Double);
3405
for I := 0 to Count - 1 do
3406
FList^[I] := FList^[I] * factor;
3412
procedure TDoubleList.Sqr;
3415
locList: PDoubleArrayList;
3418
for I := 0 to Count - 1 do
3419
locList^[I] := locList^[I] * locList^[I];
3425
procedure TDoubleList.Sqrt;
3428
locList: PDoubleArrayList;
3431
for I := 0 to Count - 1 do
3432
locList^[I] := System.Sqrt(locList^[I]);
3438
function TDoubleList.Sum: Double;
3440
function ComputeSum(list: PDoubleArrayList; nb: Integer): Double; register;
3445
fadd dword ptr [eax+edx*4]
3451
Result := ComputeSum(FList, FCount)
3459
for i := 0 to FCount-1 do
3460
Result := Result + FList^[i];
3466
function TDoubleList.Min: Single;
3469
locList: PDoubleArrayList;
3474
Result := locList^[0];
3475
for I := 1 to FCount - 1 do
3476
if locList^[I] < Result then
3477
Result := locList^[I];
3485
function TDoubleList.Max: Single;
3488
locList: PDoubleArrayList;
3493
Result := locList^[0];
3494
for I := 1 to FCount - 1 do
3495
if locList^[I] > Result then
3496
Result := locList^[I];
3502
// ------------------
3503
// ------------------ TQuaternionList ------------------
3504
// ------------------
3509
constructor TQuaternionList.Create;
3511
FItemSize := SizeOf(TQuaternion);
3513
FGrowthDelta := cDefaultListGrowthDelta;
3519
procedure TQuaternionList.Assign(Src: TPersistent);
3521
if Assigned(Src) then
3524
if (Src is TQuaternionList) then
3525
System.Move(TQuaternionList(Src).FList^, FList^, FCount * SizeOf(TQuaternion));
3534
function TQuaternionList.Add(const item: TQuaternion): Integer;
3537
if Result = FCapacity then
3538
SetCapacity(FCapacity + FGrowthDelta);
3539
FList^[Result] := Item;
3546
function TQuaternionList.Add(const item: TAffineVector; w: Single): Integer;
3548
Result := Add(QuaternionMake(item.V, w));
3554
function TQuaternionList.Add(const X, Y, Z, w: Single): Integer;
3556
Result := Add(QuaternionMake([X, Y, Z], w));
3562
function TQuaternionList.Get(Index: Integer): TQuaternion;
3565
Assert(Cardinal(Index) < Cardinal(FCount));
3567
Result := FList^[Index];
3573
procedure TQuaternionList.Insert(Index: Integer; const Item: TQuaternion);
3576
Assert(Cardinal(Index) < Cardinal(FCount));
3578
if FCount = FCapacity then
3579
SetCapacity(FCapacity + FGrowthDelta);
3580
if Index < FCount then
3581
System.Move(FList[Index], FList[Index + 1],
3582
(FCount - Index) * SizeOf(TQuaternion));
3583
FList^[Index] := Item;
3590
procedure TQuaternionList.Put(Index: Integer; const Item: TQuaternion);
3593
Assert(Cardinal(Index) < Cardinal(FCount));
3595
FList^[Index] := Item;
3601
procedure TQuaternionList.SetCapacity(NewCapacity: Integer);
3604
FList := PQuaternionArray(FBaseList);
3610
procedure TQuaternionList.Push(const Val: TQuaternion);
3618
function TQuaternionList.Pop: TQuaternion;
3622
Result := Get(FCount - 1);
3626
Result := IdentityQuaternion;
3632
function TQuaternionList.IndexOf(const item: TQuaternion): Integer;
3635
curItem: PQuaternion;
3637
for I := 0 to Count - 1 do
3639
curItem := @FList[I];
3640
if (item.RealPart = curItem^.RealPart) and VectorEquals(item.ImagPart, curItem^.ImagPart) then
3652
function TQuaternionList.FindOrAdd(const item: TQuaternion): Integer;
3654
Result := IndexOf(item);
3656
Result := Add(item);
3662
procedure TQuaternionList.Lerp(const list1, list2: TBaseVectorList; lerpFactor: Single);
3666
if (list1 is TQuaternionList) and (list2 is TQuaternionList) then
3668
Assert(list1.Count = list2.Count);
3669
Capacity := list1.Count;
3670
FCount := list1.Count;
3671
for I := 0 to FCount - 1 do
3672
Put(I, QuaternionSlerp(TQuaternionList(list1)[I], TQuaternionList(list2)[I], lerpFactor));
3679
procedure TQuaternionList.Combine(const list2: TBaseVectorList; factor: Single);
3681
procedure CombineQuaternion(var q1: TQuaternion; const q2: TQuaternion; factor: Single);
3683
q1 := QuaternionMultiply(q1, QuaternionSlerp(IdentityQuaternion, q2, factor));
3689
Assert(list2.Count >= Count);
3690
if list2 is TQuaternionList then
3692
for I := 0 to Count - 1 do
3694
CombineQuaternion(PQuaternion(ItemAddress[I])^,
3695
PQuaternion(list2.ItemAddress[I])^,
3703
// ------------------
3704
// ------------------ T4ByteList ------------------
3705
// ------------------
3710
constructor T4ByteList.Create;
3712
FItemSize := SizeOf(T4ByteList);
3714
FGrowthDelta := cDefaultListGrowthDelta;
3720
procedure T4ByteList.Assign(Src: TPersistent);
3722
if Assigned(Src) then
3725
if (Src is T4ByteList) then
3726
System.Move(T4ByteList(Src).FList^, FList^, FCount * SizeOf(T4ByteData));
3735
function T4ByteList.Add(const item: T4ByteData): Integer;
3738
if Result = FCapacity then
3739
SetCapacity(FCapacity + FGrowthDelta);
3740
FList^[Result] := Item;
3745
procedure T4ByteList.Add(const i1: Single);
3750
if FCount >= FCapacity then
3751
SetCapacity(FCapacity + FGrowthDelta);
3752
tmpList := @FList[FCount - 1];
3757
procedure T4ByteList.Add(const i1, i2: Single);
3759
tmpList: PSingleArray;
3762
while FCount > FCapacity do
3763
SetCapacity(FCapacity + FGrowthDelta);
3764
tmpList := @FList[FCount - 2];
3771
procedure T4ByteList.Add(const i1, i2, i3: Single);
3773
tmpList: PSingleArray;
3776
while FCount > FCapacity do
3777
SetCapacity(FCapacity + FGrowthDelta);
3778
tmpList := @FList[FCount - 3];
3786
procedure T4ByteList.Add(const i1, i2, i3, i4: Single);
3788
tmpList: PSingleArray;
3791
while FCount > FCapacity do
3792
SetCapacity(FCapacity + FGrowthDelta);
3793
tmpList := @FList[FCount - 4];
3801
procedure T4ByteList.Add(const i1: Integer);
3806
while FCount > FCapacity do
3807
SetCapacity(FCapacity + FGrowthDelta);
3808
tmpList := @FList[FCount - 1];
3813
procedure T4ByteList.Add(const i1, i2: Integer);
3815
tmpList: PIntegerArray;
3818
while FCount > FCapacity do
3819
SetCapacity(FCapacity + FGrowthDelta);
3820
tmpList := @FList[FCount - 2];
3827
procedure T4ByteList.Add(const i1, i2, i3: Integer);
3829
tmpList: PIntegerArray;
3832
while FCount > FCapacity do
3833
SetCapacity(FCapacity + FGrowthDelta);
3834
tmpList := @FList[FCount - 3];
3842
procedure T4ByteList.Add(const i1, i2, i3, i4: Integer);
3844
tmpList: PIntegerArray;
3847
while FCount > FCapacity do
3848
SetCapacity(FCapacity + FGrowthDelta);
3849
tmpList := @FList[FCount - 4];
3857
procedure T4ByteList.Add(const i1: Cardinal);
3862
while FCount > FCapacity do
3863
SetCapacity(FCapacity + FGrowthDelta);
3864
tmpList := @FList[FCount - 1];
3869
procedure T4ByteList.Add(const i1, i2: Cardinal);
3871
tmpList: PLongWordArray;
3874
while FCount > FCapacity do
3875
SetCapacity(FCapacity + FGrowthDelta);
3876
tmpList := @FList[FCount - 2];
3883
procedure T4ByteList.Add(const i1, i2, i3: Cardinal);
3885
tmpList: PLongWordArray;
3888
while FCount > FCapacity do
3889
SetCapacity(FCapacity + FGrowthDelta);
3890
tmpList := @FList[FCount - 3];
3898
procedure T4ByteList.Add(const i1, i2, i3, i4: Cardinal);
3900
tmpList: PLongWordArray;
3903
while FCount > FCapacity do
3904
SetCapacity(FCapacity + FGrowthDelta);
3905
tmpList := @FList[FCount - 4];
3913
procedure T4ByteList.Add(const AList: T4ByteList);
3915
if Assigned(AList) and (AList.Count > 0) then
3917
if Count + AList.Count > Capacity then
3918
Capacity := Count + AList.Count;
3919
System.Move(AList.FList[0], FList[Count], AList.Count * SizeOf(T4ByteData));
3920
Inc(FCount, AList.Count);
3928
function T4ByteList.Get(Index: Integer): T4ByteData;
3931
Assert(Cardinal(Index) < Cardinal(FCount));
3933
Result := FList^[Index];
3939
procedure T4ByteList.Insert(Index: Integer; const Item: T4ByteData);
3942
Assert(Cardinal(Index) < Cardinal(FCount));
3944
if FCount = FCapacity then
3945
SetCapacity(FCapacity + FGrowthDelta);
3946
if Index < FCount then
3947
System.Move(FList[Index], FList[Index + 1],
3948
(FCount - Index) * SizeOf(T4ByteData));
3949
FList^[Index] := Item;
3957
procedure T4ByteList.Put(Index: Integer; const Item: T4ByteData);
3960
Assert(Cardinal(Index) < Cardinal(FCount));
3962
FList^[Index] := Item;
3969
procedure T4ByteList.SetCapacity(NewCapacity: Integer);
3972
FList := P4ByteArrayList(FBaseList);
3978
procedure T4ByteList.Push(const Val: T4ByteData);
3986
function T4ByteList.Pop: T4ByteData;
3988
Zero : T4ByteData = ( Int: (Value:0) );
3992
Result := Get(FCount - 1);
3999
// ------------------
4000
// ------------------ TLongWordList ------------------
4001
// ------------------
4006
constructor TLongWordList.Create;
4008
FItemSize := SizeOf(LongWord);
4010
FGrowthDelta := cDefaultListGrowthDelta;
4016
procedure TLongWordList.Assign(Src: TPersistent);
4018
if Assigned(Src) then
4021
if (Src is TLongWordList) then
4022
System.Move(TLongWordList(Src).FList^, FList^, FCount * SizeOf(LongWord));
4031
function TLongWordList.Add(const item: LongWord): Integer;
4034
if Result = FCapacity then
4035
SetCapacity(FCapacity + FGrowthDelta);
4036
FList^[Result] := Item;
4040
// AddNC (simple, no capacity check)
4043
function TLongWordList.AddNC(const item: LongWord): Integer;
4046
FList^[Result] := Item;
4053
procedure TLongWordList.Add(const i1, i2: LongWord);
4055
tmpList : PLongWordArray;
4058
while FCount > FCapacity do
4059
SetCapacity(FCapacity + FGrowthDelta);
4060
tmpList := @FList[FCount - 2];
4065
// Add (three at once)
4068
procedure TLongWordList.Add(const i1, i2, i3: LongWord);
4070
tmpList : PLongWordArray;
4073
while FCount > FCapacity do
4074
SetCapacity(FCapacity + FGrowthDelta);
4075
tmpList := @FList[FCount - 3];
4084
procedure TLongWordList.Add(const AList: TLongWordList);
4086
if Assigned(AList) and (AList.Count > 0) then
4088
if Count + AList.Count > Capacity then
4089
Capacity := Count + AList.Count;
4090
System.Move(AList.FList[0], FList[Count], AList.Count * SizeOf(LongWord));
4091
Inc(FCount, AList.Count);
4098
function TLongWordList.Get(Index: Integer): LongWord;
4101
Assert(Cardinal(Index) < Cardinal(FCount));
4103
Result := FList^[Index];
4109
procedure TLongWordList.Insert(Index: Integer; const Item: LongWord);
4112
Assert(Cardinal(Index) < Cardinal(FCount));
4114
if FCount = FCapacity then
4115
SetCapacity(FCapacity + FGrowthDelta);
4116
if Index < FCount then
4117
System.Move(FList[Index], FList[Index + 1], (FCount - Index) * SizeOf(LongWord));
4118
FList^[Index] := Item;
4125
procedure TLongWordList.Remove(const item: LongWord);
4129
for I := 0 to Count - 1 do
4131
if FList^[I] = item then
4133
System.Move(FList[I + 1], FList[I], (FCount - 1 - I) * SizeOf(LongWord));
4143
procedure TLongWordList.Put(Index: Integer; const Item: LongWord);
4146
Assert(Cardinal(Index) < Cardinal(FCount));
4148
FList^[Index] := Item;
4154
procedure TLongWordList.SetCapacity(NewCapacity: Integer);
4157
FList := PLongWordArray(FBaseList);
4163
procedure TLongWordList.Push(const Val: LongWord);
4171
function TLongWordList.Pop: LongWord;
4175
Result := FList^[FCount - 1];
4182
// AddLongWords (pointer & n)
4185
procedure TLongWordList.AddLongWords(const First: PLongWord; n: Integer);
4189
AdjustCapacityToAtLeast(Count + n);
4190
System.Move(First^, FList[FCount], n * SizeOf(LongWord));
4191
FCount := FCount + n;
4194
// AddLongWords (TLongWordList)
4197
procedure TLongWordList.AddLongWords(const aList: TLongWordList);
4199
if not Assigned(aList) then
4201
AddLongWords(@aList.List[0], aList.Count);
4204
// AddLongWords (array)
4207
procedure TLongWordList.AddLongWords(const anArray: array of LongWord);
4211
n := Length(anArray);
4213
AddLongWords(@anArray[0], n);
4219
function LongWordSearch(item: LongWord; list: PLongWordVector; Count: Integer): Integer; register;
4224
for i := 0 to Count-1 do begin
4225
if list^[i]=item then begin
4258
function TLongWordList.IndexOf(item: Integer): LongWord; register;
4260
Result := LongWordSearch(item, FList, FCount);
4263
// ------------------------------------------------------------------
4264
// ------------------------------------------------------------------
4265
// ------------------------------------------------------------------
4267
// ------------------------------------------------------------------
4268
// ------------------------------------------------------------------
4269
// ------------------------------------------------------------------
4271
RegisterClasses([TAffineVectorList, TVectorList, TTexPointList, TSingleList,
4272
TDoubleList, T4ByteList, TLongWordList]);