-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuCamera.pas
364 lines (296 loc) · 10.6 KB
/
uCamera.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
unit uCamera;
interface
uses u3DTypes;
const
DefaultPosition : TVector = (X:0.0;Y:1.0;Z:0.0;);
DefaultTarget : TVector = (X:0.0;Y:1.0;Z:1.0;);
DefaultUpY : TVector = (X:0.0;Y:1.0;Z:0.0;);
// minder gevoelig < 1 < gevoeliger
DefaultSensitivityX = 0.1;
DefaultSensitivityY = 0.5;
// bewegings-snelheid van een zwevende camera
DefaultCamSpeed = 100.0;
// De standaard boudingbox afmetingen (van een game-character)
DefaultBoundingBoxMin : TVector = (X:-12; Y:-56; Z:-12;);
DefaultBoundingBoxMax : TVector = (X:12; Y:8; Z:12;);
// BoundingBox
bbMin = 0;
bbMax = 1;
DefaultSmoothAngle = 10.0; // graden per frame
type
PCamera = ^TCamera; //Een pointer naar een TCamera
TCamera = class(TObject)
private
Collide_: boolean;
// interpolated cam movements
Smooth: boolean; //interpoleren??
SmoothPosition,
SmoothTarget,
SmoothUpY: TVector;
public
Position, //het camera-oogpunt (de huidige camera-positie)
Target, //het punt waar de camera naar kijkt (het huidige target)
UpY: TVector; //de vector voor de de richting om de bovenkant van de camera aan te duiden
//
SensitivityX, //de gevoeligheid bij bewegingen
SensitivityY: Single;
// tbv collision detection
SphereRadius: single; //de bol-straal bij collision-detection
BoundingBox: array[bbMin..bbMax] of TVector; // als VolumeType = ctBox [Min,Max]
//
Speed: Single; //de snelheid bij bewegingen van een zwevende camera
//
Floating: boolean;
MouseControlled: boolean; //true = camera besturen met de muis..
// object
constructor Create;
destructor Destroy; override;
//gebruik de opgegeven camera-instellingen
procedure Use(aPosition,aTarget,aUpY: TVector); overload;
procedure Use(aPosition,aTarget,aUpY: TVector; aSpeed: Single); overload;
procedure Use(aPosition,aTarget,aUpY: TVector; aSpeed: Single; XSensitivity,YSensitivity: Single); overload;
//gebruik de standaard camera-instellingen
procedure Default;
//de camera met de muis besturen
procedure ToggleMouseControl;
//botsingen
procedure ToggleCollide;
function GetCollide : boolean;
procedure SetCollide(State: boolean);
//
procedure ToggleFloating;
//de gevoeligheid bij bewegingen
procedure SetSensitivity(XSensitivity,YSensitivity: Single);
//de bol-straal bij botsingen
procedure SetSphereRadius(Radius: Single);
//snelheid bij bewegingen
procedure SetSpeed(aSpeed: Single);
//de positie (Eye)
procedure SetPosition(P: TVector);
procedure SetPositionY(Y: Single);
// interpoleren van bewegingen
procedure SetSmooth(Value: boolean);
function GetSmooth: boolean;
//de vector voor de richting waarin de camera kijkt
function LineOfSight : TVector;
//de camera draaien, camera-positie blijft gelijk
procedure RotateLineOfSight(R: TVector);
//de camera draaien, Center blijft gelijk
procedure RotateAboutTarget(R: TVector);
//de camera verplaatsen in een richting evenwijdig aan de kijkrichting
procedure Move(Factor: Single); //Factor<0 = achteruit, Factor>0 = vooruit
//Herleid de positie van de camera na een Move.
//(de verplaatsing wordt alleen uitgerekend, niet daadwerkelijk doorgevoerd)
function NextMove_Position(Factor: Single) : TVector; overload;
function NextMove_Position(FromPosition: TVector; Factor: Single) : TVector; overload;
//de camera verplaatsen in een richting loodrecht op de kijkrichting
procedure Strafe(Factor: Single); //Factor<0 = links, Factor>0 = rechts
//Herleid de positie van de camera na een Move.
//(de verplaatsing wordt alleen uitgerekend, niet daadwerkelijk doorgevoerd)
function NextStrafe_Position(Factor: Single) : TVector; overload;
function NextStrafe_Position(FromPosition: TVector; Factor: Single) : TVector; overload;
//de camera verplaatsen in een richting loodrecht op de kijkrichting
procedure StrafeUpDown(Factor: Single); //Factor<0 = links, Factor>0 = rechts
//Herleid de positie van de camera na een Move.
//(de verplaatsing wordt alleen uitgerekend, niet daadwerkelijk doorgevoerd)
function NextStrafeUpDown_Position(Factor: Single) : TVector; overload;
function NextStrafeUpDown_Position(FromPosition: TVector; Factor: Single) : TVector; overload;
end;
{var Camera: TCamera;}
implementation
uses OpenGL, uCalc;
{ TCamera }
constructor TCamera.Create;
begin
// Object initiëren
inherited;
// Data initialiseren
Floating := true;
MouseControlled := false;
Collide_ := false;
SphereRadius := 24.0;
BoundingBox[bbMin] := DefaultBoundingBoxMin;
BoundingBox[bbMax] := DefaultBoundingBoxMax;
Default;
end;
destructor TCamera.Destroy;
begin
// Data finaliseren
// Object finaliseren
inherited;
end;
procedure TCamera.Use(aPosition, aTarget, aUpY: TVector);
begin
Position := aPosition;
Target := aTarget;
UpY := aUpY;
end;
procedure TCamera.Use(aPosition, aTarget, aUpY: TVector; aSpeed: Single);
begin
Use(aPosition, aTarget, aUpY);
Speed := aSpeed;
end;
procedure TCamera.Use(aPosition, aTarget, aUpY: TVector; aSpeed: Single; XSensitivity,YSensitivity: Single);
begin
Use(aPosition, aTarget, aUpY, aSpeed);
SensitivityX := XSensitivity;
SensitivityY := YSensitivity;
end;
procedure TCamera.Default;
begin
Use(DefaultPosition,DefaultTarget,DefaultUpY, DefaultCamSpeed, DefaultSensitivityX,DefaultSensitivityY);
end;
procedure TCamera.ToggleMouseControl;
begin
MouseControlled := not MouseControlled;
end;
function TCamera.GetCollide: boolean;
begin
Result := Collide_;
end;
procedure TCamera.SetCollide(State: boolean);
begin
Collide_ := State;
end;
procedure TCamera.ToggleCollide;
begin
Collide_ := not Collide_;
Floating := (not Collide_);
end;
procedure TCamera.ToggleFloating;
begin
Floating := not Floating;
end;
procedure TCamera.SetSensitivity(XSensitivity, YSensitivity: Single);
begin
SensitivityX := XSensitivity;
SensitivityY := YSensitivity;
end;
procedure TCamera.SetSphereRadius(Radius: Single);
begin
SphereRadius := Radius;
end;
procedure TCamera.SetSpeed(aSpeed: Single);
begin
Speed := aSpeed;
end;
procedure TCamera.SetPosition(P: TVector);
var LOS: TVector;
begin
// met behoud van LineOfSight
LOS := LineOfSight;
Position := P;
Target := AddVector(Position, LOS);
end;
procedure TCamera.SetPositionY(Y: Single);
var LOS: TVector;
begin
// met behoud van LineOfSight
LOS := LineOfSight;
Position.Y := Y;
Target := AddVector(Position, LOS);
end;
function TCamera.GetSmooth: boolean;
begin
Result := Smooth;
end;
procedure TCamera.SetSmooth(Value: boolean);
begin
Smooth := Value;
end;
function TCamera.LineOfSight : TVector;
begin
Result := UnitVector(SubVector(Target, Position));
end;
procedure TCamera.RotateLineOfSight(R: TVector);
begin
// transformatie: transleer -Position, roteer R, transleer Position
Target := AddVector(Rotate(SubVector(Target,Position), Vector(0,0,0), R), Position);
end;
procedure TCamera.RotateAboutTarget(R: TVector);
begin
// transformatie: transleer -LookAt, roteer R, transleer LookAt
Position := AddVector(Rotate(SubVector(Position,Target), Vector(0,0,0), R), Target);
end;
procedure TCamera.Move(Factor: Single);
var V,LOS: TVector;
begin
LOS := LineOfSight;
if Floating then V := LOS // de camera zweeft..
else V := Vector(LOS.X, 0, LOS.Z); // de camera-positie kan niet in Y-richting omhoog worden gestuurd..
V := ScaleVector(V, Factor);
Position := AddVector(Position, V);
Target := AddVector(Position, LOS); //Target := AddVector(Target, V);
end;
function TCamera.NextMove_Position(Factor: Single): TVector;
var V,LOS: TVector;
begin
LOS := LineOfSight;
if Floating then V := LOS // de camera zweeft..
else V := Vector(LOS.X, 0, LOS.Z); // de camera-positie kan niet in Y-richting omhoog worden gestuurd..
V := ScaleVector(V, Factor);
Result := AddVector(Position, V);
end;
function TCamera.NextMove_Position(FromPosition: TVector; Factor: Single): TVector;
var V,LOS: TVector;
begin
LOS := LineOfSight;
if Floating then V := LOS // de camera zweeft..
else V := Vector(LOS.X, 0, LOS.Z); // de camera-positie kan niet in Y-richting omhoog worden gestuurd..
V := ScaleVector(V, Factor);
Result := AddVector(FromPosition, V);
end;
procedure TCamera.Strafe(Factor: Single);
var V: TVector;
begin
V := CrossProduct(UpY, LineOfSight);
V := ScaleVector(V, Factor);
Position := AddVector(Position, V);
Target := AddVector(Target, V);
end;
function TCamera.NextStrafe_Position(Factor: Single): TVector;
var V: TVector;
begin
V := CrossProduct(UpY, LineOfSight);
V := ScaleVector(V, Factor);
Result := AddVector(Position, V);
end;
function TCamera.NextStrafe_Position(FromPosition: TVector; Factor: Single): TVector;
var V: TVector;
begin
V := CrossProduct(UpY, LineOfSight);
V := ScaleVector(V, Factor);
Result := AddVector(FromPosition, V);
end;
procedure TCamera.StrafeUpDown(Factor: Single);
var V: TVector;
begin
V := CrossProduct(UpY, LineOfSight);
V := CrossProduct(LineOfSight, V);
V := ScaleVector(V, Factor);
Position := AddVector(Position, V);
Target := AddVector(Target, V);
end;
function TCamera.NextStrafeUpDown_Position(Factor: Single): TVector;
var V: TVector;
begin
V := CrossProduct(UpY, LineOfSight);
V := CrossProduct(LineOfSight, V);
V := ScaleVector(V, Factor);
Result := AddVector(Position, V);
end;
function TCamera.NextStrafeUpDown_Position(FromPosition: TVector; Factor: Single): TVector;
var V: TVector;
begin
V := CrossProduct(UpY, LineOfSight);
V := CrossProduct(LineOfSight, V);
V := ScaleVector(V, Factor);
Result := AddVector(FromPosition, V);
end;
(*
initialization
Camera := TCamera.Create;
finalization
Camera.Free
*)
end.