14
{ GLRigidBodyInertia};
18
TGLUniformGravityEmitter = class(TGLBaseForceFieldEmitter)
20
fGravity:TGLCoordinates;
22
procedure SetGravity(const val : TGLCoordinates);
24
constructor Create(aOwner : TGLXCollection); override;
25
destructor Destroy;override;
26
procedure Assign(Source: TPersistent); override;
27
procedure WriteToFiler(writer : TWriter); override;
28
procedure ReadFromFiler(reader : TReader); override;
29
class function FriendlyName : String; override;
30
class function FriendlyDescription : String; override;
31
class function UniqueItem : Boolean; override;
32
function CalculateForceField(Body:TGLBaseSceneObject):TAffineVector;override;
34
property Gravity:TGLCoordinates read fGravity write SetGravity;
37
TGLRadialGravityEmitter = class(TGLBaseForceFieldEmitter)
42
constructor Create(aOwner : TGLXCollection); override;
43
destructor Destroy;override;
44
procedure Assign(Source: TPersistent); override;
45
procedure WriteToFiler(writer : TWriter); override;
46
procedure ReadFromFiler(reader : TReader); override;
47
class function FriendlyName : String; override;
48
class function FriendlyDescription : String; override;
49
class function UniqueItem : Boolean; override;
50
function CalculateForceField(Body:TGLBaseSceneObject):TAffineVector;override;
52
property Mass:Real read fMass write fMass;
55
TGLDampingFieldEmitter = class(TGLBaseForceFieldEmitter)
59
procedure SetDamping(const val: TGLDamping);
61
constructor Create(aOwner : TGLXCollection); override;
62
destructor Destroy;override;
63
procedure Assign(Source: TPersistent); override;
64
procedure WriteToFiler(writer : TWriter); override;
65
procedure ReadFromFiler(reader : TReader); override;
66
class function FriendlyName : String; override;
67
class function FriendlyDescription : String; override;
68
class function UniqueItem : Boolean; override;
69
function CalculateForceField(Body:TGLBaseSceneObject):TAffineVector;override;
71
property Damping:TGLDamping read fDamping write SetDamping;
74
const GravitationalConstant=6.6726E-11;
76
//==================================================================
78
//==================================================================
80
//-------------------------------------
81
//---- TGLUniformGravityEmitter
82
//-------------------------------------
83
constructor TGLUniformGravityEmitter.Create(aOwner : TGLXCollection);
85
inherited Create(aOwner);
86
fGravity:=TGLCoordinates.CreateInitialized(Self,nullHmgVector,csVector);
89
destructor TGLUniformGravityEmitter.Destroy;
95
procedure TGLUniformGravityEmitter.Assign(Source: TPersistent);
97
if Source.ClassType=Self.ClassType then begin
98
fGravity := TGLUniformGravityEmitter(Source).fGravity;
102
class function TGLUniformGravityEmitter.FriendlyName : String;
104
Result := 'Uniform Gravity';
107
class function TGLUniformGravityEmitter.FriendlyDescription : String;
109
Result := 'Uniform Gravity, appropriate near surface of planet';
112
class function TGLUniformGravityEmitter.UniqueItem : Boolean;
117
procedure TGLUniformGravityEmitter.WriteToFiler(writer : TWriter);
122
fGravity.WriteToFiler(writer);
126
procedure TGLUniformGravityEmitter.ReadFromFiler(reader : TReader);
131
fGravity.ReadFromFiler(reader);
135
procedure TGLUniformGravityEmitter.SetGravity(const val : TGLCoordinates);
137
fGravity.Assign(val);
140
// CalculateForceField (TODO: ParticleInertia -> BaseInertia, add BaseInertia.ApplyAcceleration)
141
function TGLUniformGravityEmitter.CalculateForceField(Body:TGLBaseSceneObject):TAffineVector;
143
inertia1:TGLParticleInertia;
145
Inertia1:=TGLParticleInertia(Body.Behaviours.GetByClass(TGLParticleInertia));
146
if Assigned(inertia1) then
148
Result:=VectorScale(fGravity.AsAffineVector,Inertia1.Mass);
149
inertia1.ApplyForce(Result);
155
//------------------------------------------------------------------------------
156
//------------------------------Radial Gravity Emitter -------------------------
157
//------------------------------------------------------------------------------
159
constructor TGLRadialGravityEmitter.Create(aOwner : TGLXCollection);
161
inherited Create(aOwner);
164
destructor TGLRadialGravityEmitter.Destroy;
169
procedure TGLRadialGravityEmitter.Assign(Source: TPersistent);
171
if Source.ClassType=Self.ClassType then
173
fMass:=TGLRadialGravityEmitter(Source).fMass;
177
class function TGLRadialGravityEmitter.FriendlyName : String;
179
Result:='Radial Gravity';
182
class function TGLRadialGravityEmitter.FriendlyDescription : String;
184
Result:='Radial Gravity, can be applied anywhere (use for planets)';
187
class function TGLRadialGravityEmitter.UniqueItem : Boolean;
192
procedure TGLRadialGravityEmitter.WriteToFiler(writer : TWriter);
201
procedure TGLRadialGravityEmitter.ReadFromFiler(reader : TReader);
210
// CalculateForceField (TODO: ParticleInertia -> BaseInertia if possible)
211
function TGLRadialGravityEmitter.CalculateForceField(Body:TGLBaseSceneObject):TAffineVector;
213
inertia1:TGLParticleInertia;
217
Inertia1:=TGLParticleInertia(Body.Behaviours.GetByClass(TGLParticleInertia));
218
if Assigned(inertia1) then
220
R:=VectorSubtract(Body.Position.AsAffineVector,Self.OwnerBaseSceneObject.Position.AsAffineVector);
222
Result:=VectorScale(R,-GravitationalConstant*(fMass/L));
223
inertia1.ApplyForce(Result);
229
//-----------------------------------------------------------------------------
230
//------------------------------Damping Field Emitter -------------------------
231
//-----------------------------------------------------------------------------
233
constructor TGLDampingFieldEmitter.Create(aOwner : TGLXCollection);
235
inherited Create(aOwner);
236
fDamping:=TGLDamping.Create(Self);
239
destructor TGLDampingFieldEmitter.Destroy;
245
procedure TGLDampingFieldEmitter.Assign(Source: TPersistent);
247
if Source.ClassType=Self.ClassType then
249
fDamping:=TGLDampingFieldEmitter(Source).fDamping;
253
class function TGLDampingFieldEmitter.FriendlyName : String;
255
Result := 'Damping Field';
258
class function TGLDampingFieldEmitter.FriendlyDescription : String;
260
Result := 'Damping Field, to approximate air/fluid resistance';
263
class function TGLDampingFieldEmitter.UniqueItem : Boolean;
268
procedure TGLDampingFieldEmitter.WriteToFiler(writer : TWriter);
273
fDamping.WriteToFiler(writer);
277
procedure TGLDampingFieldEmitter.ReadFromFiler(reader : TReader);
282
fDamping.ReadFromFiler(reader);
286
procedure TGLDampingFieldEmitter.SetDamping(const val : TGLDamping);
288
fDamping.Assign(val);
291
// CalculateForceField (TODO: ParticleInertia -> BaseInertia, BaseInertia.ApplyDamping?)
292
function TGLDampingFieldEmitter.CalculateForceField(Body:TGLBaseSceneObject):TAffineVector;
294
inertia1:TGLParticleInertia;
295
velocity:TAffineVector;
298
Inertia1:=TGLParticleInertia(Body.Behaviours.GetByClass(TGLParticleInertia));
299
if Assigned(inertia1) then
300
Inertia1.ApplyDamping(Damping);
303
Inertia1:=TGLParticleInertia(Body.Behaviours.GetByClass(TGLParticleInertia));
304
if Assigned(inertia1) then
306
velocity:=VectorScale(inertia1.LinearMomentum, 1/Inertia1.Mass); // v = p/m
307
//apply force in opposite direction to velocity
308
v:=VectorLength(velocity);
309
// F = -Normalised(V)*( Constant + (Linear)*(V) + (Quadtratic)*(V)*(V) )
310
Result:=VectorScale(VectorNormalize(velocity),-(fDamping.Constant+fDamping.Linear*v+fDamping.Quadratic*v*v));
311
inertia1.ApplyForce(Result);
318
//-------------------------------------------------------------------------
320
//-------------------------------------------------------------------------
322
RegisterXCollectionItemClass(TGLUniformGravityEmitter);
323
RegisterXCollectionItemClass(TGLRadialGravityEmitter);
324
RegisterXCollectionItemClass(TGLDampingFieldEmitter);