unit fdPhysXScatter; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Stage.VectorTypes, Stage.VectorGeometry, Stage.Keyboard, GLS.Scene, GLS.Objects, GLS.Coordinates, GLS.Cadencer, GLS.SceneViewer, GLS.Color, GLS.XCollection, GLS.BaseClasses, GLS.GeomObjects, GLS.Gui, GLS.Windows, PhysX.Import; type TFormPhysXScatter = class(TForm) GLScene: TGLScene; GLSV: TGLSceneViewer; Cadencer: TGLCadencer; Camera: TGLCamera; Center: TGLDummyCube; Light: TGLLightSource; Timer: TTimer; Edit1: TEdit; Plane: TGLPlane; Light1: TGLLightSource; procedure CadencerProgress(Sender: TObject; const deltaTime, newTime: Double); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure TimerTimer(Sender: TObject); procedure GLSVMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private public mx, my: Integer; end; var FormPhysXScatter: TFormPhysXScatter; Plane: dword; boxes, capsules, spheres: array [0 .. 100] of dword; GLCube: array [0 .. 100] of TGLCube; GLCapsule: array [0 .. 100] of TGLCapsule; GLSphere: array [0 .. 100] of TGLSphere; type TVec = packed record X, Y, Z: single; end; type TQuat = packed record X, Y, Z, W: single; end; implementation //============================================================= {$R *.dfm} function ByteToStr(b: byte): string; const t: array [0 .. 9] of char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); var e: byte; d: byte; s: byte; begin s := b div 100; b := b mod 100; d := b div 10; e := b mod 10; if s > 0 then begin result := t[s] + t[d] + t[e]; end else begin if d > 0 then result := t[d] + t[e] else result := t[e]; end; end; procedure DemoInit; var i: Integer; dMaj, dMin, dBug: dword; begin SDK_Version(@dMaj, @dMin, @dBug); FormPhysXScatter.Caption := 'PhysX SDK version ' + ByteToStr(dMaj) + '.' + ByteToStr(dMin) + '.' + ByteToStr(dBug); InitNx; CreateGroundPlane(@Plane); for i := 0 to High(boxes) do begin CreateBox(@boxes[i], 0.5, 0.5, 0.5, 10); SetActorMass(boxes[i], 10); SetActorGlobalPosition(boxes[i], 0, i * 2, i * 0.5 - 20); end; for i := 0 to High(capsules) do begin CreateCylinder(@capsules[i], 0.5, 1, 10); SetActorMass(capsules[i], 10); SetActorGlobalPosition(capsules[i], 5, i * 2, i * 0.5 - 20); end; for i := 0 to High(spheres) do begin CreateSphere(@spheres[i], 0.5, 10); SetActorMass(spheres[i], 10); SetActorGlobalPosition(spheres[i], -5, i * 2, i * 0.5 - 20); end; end; procedure DrawBox(b: dword; i: Integer); var v: TVec; q: TQuat; q1: TQuaternion; begin GetActorGlobalPosition(b, @v.X, @v.Y, @v.Z); GetActorGlobalOrientation(b, @q.X, @q.Y, @q.Z, @q.W); MakeVector(q1.ImagPart, q.X, q.Y, q.Z); q1.RealPart := q.W; NormalizeQuaternion(q1); GLCube[i].Matrix^ := QuaternionToMatrix(q1); GLCube[i].Position.SetPoint(v.X, v.Y, v.Z); end; procedure DrawCapsule(b: dword; i: Integer); var v: TVec; q: TQuat; q1: TQuaternion; begin GetActorGlobalPosition(b, @v.X, @v.Y, @v.Z); GetActorGlobalOrientation(b, @q.X, @q.Y, @q.Z, @q.W); MakeVector(q1.ImagPart, q.X, q.Y, q.Z); q1.RealPart := q.W; NormalizeQuaternion(q1); GLCapsule[i].Matrix^ := QuaternionToMatrix(q1); GLCapsule[i].Pitch(90); GLCapsule[i].Position.SetPoint(v.X, v.Y, v.Z); end; procedure DrawSphere(b: dword; i: Integer); var v: TVec; q: TQuat; q1: TQuaternion; begin GetActorGlobalPosition(b, @v.X, @v.Y, @v.Z); GetActorGlobalOrientation(b, @q.X, @q.Y, @q.Z, @q.W); MakeVector(q1.ImagPart, q.X, q.Y, q.Z); q1.RealPart := q.W; NormalizeQuaternion(q1); GLSphere[i].Matrix^ := QuaternionToMatrix(q1); GLSphere[i].Position.SetPoint(v.X, v.Y, v.Z); end; procedure DemoFree; begin ReleaseNx; end; procedure TFormPhysXScatter.CadencerProgress(Sender: TObject; const deltaTime, newTime: Double); var i: Integer; begin SimulateNx(deltaTime); GetResultsNx; for i := 0 to 100 do begin DrawBox(boxes[i], i); DrawCapsule(capsules[i], i); DrawSphere(spheres[i], i); end; if IsKeyDown(' ') then begin for i := 0 to 100 do begin ActorAddForce(boxes[i], 0, 100, 0); ActorAddForce(capsules[i], 0, 100, 0); ActorAddForce(spheres[i], 0, 100, 0); end; end; end; procedure TFormPhysXScatter.FormCreate(Sender: TObject); var i: Integer; begin for i := 0 to High(GLCube) do begin GLCube[i] := TGLCube.CreateAsChild(GLScene.Objects); end; for i := 0 to High(GLCapsule) do begin GLCapsule[i] := TGLCapsule.CreateAsChild(GLScene.Objects); end; for i := 0 to High(GLSphere) do begin GLSphere[i] := TGLSphere.CreateAsChild(GLScene.Objects); end; DemoInit; end; procedure TFormPhysXScatter.FormDestroy(Sender: TObject); begin DemoFree; end; procedure TFormPhysXScatter.TimerTimer(Sender: TObject); begin Edit1.Text := Format('%.1f FPS', [GLSV.FramesPerSecond]); GLSV.ResetPerformanceMonitor; end; procedure TFormPhysXScatter.GLSVMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Shift <> [] then begin Camera.MoveAroundTarget(my - Y, mx - X); mx := X; my := Y; end; end; end.