| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- unit fNGDWalkShootD;
- interface
- uses
- Winapi.Windows,
- System.SysUtils,
- System.Variants,
- System.Classes,
- Vcl.Graphics,
- Vcl.Controls,
- Vcl.Forms,
- Vcl.Dialogs,
- GLS.Scene,
- GLScene.VectorTypes,
- GLS.VectorLists,
- GLS.PersistentClasses,
- GLS.Objects,
- GLS.Coordinates,
- GLS.Cadencer,
- GLS.NGDManager,
- GLS.SimpleNavigation,
- GLS.SceneViewer,
-
- GLS.BaseClasses,
- GLS.VectorFileObjects,
- GLS.GeomObjects,
- GLS.HUDObjects,
- GLS.File3DS,
- GLScene.VectorGeometry,
- GLS.Material,
- GLS.Keyboard,
- GLScene.Utils;
- type
- TFormNewtonWalkShoot = class(TForm)
- GLScene1: TGLScene;
- GLSceneViewer1: TGLSceneViewer;
- GLSimpleNavigation1: TGLSimpleNavigation;
- GLNGDManager1: TGLNGDManager;
- GLCadencer1: TGLCadencer;
- GLCamera1: TGLCamera;
- GLLightSource1: TGLLightSource;
- GLDummyCube1: TGLDummyCube;
- World: TGLDummyCube;
- GLLines1: TGLLines;
- Beer: TGLFreeForm;
- Mushroom: TGLFreeForm;
- Chair: TGLFreeForm;
- Teapot: TGLFreeForm;
- Map: TGLFreeForm;
- GLHUDCross: TGLHUDSprite;
- Body: TGLTorus;
- procedure GLCadencer1Progress(Sender: TObject;
- const deltaTime, newTime: Double);
- procedure FormCreate(Sender: TObject);
- procedure FormKeyPress(Sender: TObject; var Key: Char);
- procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- private
- procedure ScaleMesh(freeform: TGLFreeForm; val: Single);
- procedure MoveCam(const deltaTime, newTime: Double);
- procedure MoveGrab;
- public
- grabJoint: TGLNGDJoint;
- end;
- var
- FormNewtonWalkShoot: TFormNewtonWalkShoot;
- implementation
- {$R *.dfm}
- procedure TFormNewtonWalkShoot.FormCreate(Sender: TObject);
- begin
- var Path: TFileName := GetCurrentAssetPath();
- SetCurrentDir(Path + '\model');
- // Set Mesh and scale their vertice position
- // because matrix scale is not supported in newton
- Map.LoadFromFile('ngdmap1.3ds');
- Map.Direction.SetVector(0, 1, 0);
- Map.Translate(0, -3, 0);
- Beer.LoadFromFile('beer.3ds');
- ScaleMesh(Beer, 0.25);
- Beer.Translate(-5, 10, 10);
- Mushroom.LoadFromFile('mushroom.3ds');
- ScaleMesh(Mushroom, 0.1);
- Mushroom.Direction.SetVector(0, 1, 0);
- Mushroom.Translate(0, 0, -10);
- Mushroom.Material.FaceCulling := fcNoCull;
- Mushroom.Material.FrontProperties.Emission.SetColor(1, 0.5, 0.5, 0.5);
- Chair.LoadFromFile('ngdchair.3ds');
- Chair.Direction.SetVector(0, 1, 0);
- Chair.Translate(0, 0, -5);
- Teapot.LoadFromFile('teapot.3ds');
- ScaleMesh(Teapot, 0.05);
- Teapot.Direction.SetVector(0, 1, 0);
- Teapot.Translate(0, 0, 10);
- // Create Physic behavior
- GetOrCreateNGDStatic(Map).NGDNewtonCollisions := nc_Tree;
- GetNGDStatic(Map).Manager := GLNGDManager1;
- // nc_Convex use ConvexCollisionTolerance at creation wich is the resolution
- // for collision shape. Bigger the value, lower the collision match,
- // but give higher performance (use mdShowGeometry to see the difference at runtime)
- GetOrCreateNGDDynamic(Chair).NGDNewtonCollisions := nc_Convex;
- GetNGDDynamic(Chair).Manager := GLNGDManager1;
- GetOrCreateNGDDynamic(Beer).NGDNewtonCollisions := nc_Convex;
- GetNGDDynamic(Beer).Manager := GLNGDManager1;
- GetOrCreateNGDDynamic(Teapot).NGDNewtonCollisions := nc_Convex;
- GetNGDDynamic(Teapot).Manager := GLNGDManager1;
- GetOrCreateNGDDynamic(Mushroom).NGDNewtonCollisions := nc_Convex;
- GetNGDDynamic(Mushroom).Manager := GLNGDManager1;
- // Move camera in target
- GLCamera1.Parent := GLCamera1.TargetObject;
- // Create the PickJoint
- grabJoint := TGLNGDJoint.Create(GLNGDManager1.NewtonJoint);
- grabJoint.JointType := nj_KinematicController;
- grabJoint.KinematicControllerOptions.PickModeLinear := True;
- grabJoint.KinematicControllerOptions.LinearFriction := 100;
- // Set some parameters
- GetNGDDynamic(Body).AutoSleep := False;
- GLHUDCross.Height := 2;
- GLHUDCross.Width := 2;
- GLCamera1.NearPlaneBias := 0.1;
- GLCamera1.DepthOfView := 1E15;
- end;
- procedure TFormNewtonWalkShoot.FormKeyPress(Sender: TObject; var Key: Char);
- var
- newFreeform: TGLFreeForm;
- I, rand: Integer;
- begin
- if Key = 'x' then
- begin
- newFreeform := TGLFreeForm.CreateAsChild(GLDummyCube1);
- newFreeform.LoadFromFile('HighPolyObject.3ds');
- ScaleMesh(newFreeform, 0.05);
- // Keep only one mesh in this newFreeform
- for I := 0 to newFreeform.MeshObjects.Count - 2 do
- begin
- rand := Random(newFreeform.MeshObjects.Count);
- newFreeform.MeshObjects.Delete(rand);
- end;
- GetOrCreateNGDDynamic(newFreeform).NGDNewtonCollisions := nc_Convex;
- GetNGDDynamic(newFreeform).Manager := GLNGDManager1;
- end;
- if Key = 'c' then
- GetNGDDynamic(Body).NewtonBodyMatrix := IdentityHmgMatrix;
- end;
- procedure TFormNewtonWalkShoot.GLCadencer1Progress(Sender: TObject;
- const deltaTime, newTime: Double);
- begin
- GLNGDManager1.Step(deltaTime);
- MoveCam(deltaTime, newTime);
- MoveGrab;
- // Set a point on screen to see where you shoot or grab
- GLHUDCross.Position.X := GLSceneViewer1.Width div 2;
- GLHUDCross.Position.Y := GLSceneViewer1.Height div 2;
- end;
- procedure TFormNewtonWalkShoot.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- var
- Ball: TGLSphere;
- delta: TGLVector;
- PickedSceneObject: TGLBaseSceneObject;
- point3d: TGLVector;
- MyX, MyY: Integer;
- begin
- // Shoot a Bullet
- if Button = TMouseButton(mbLeft) then
- begin
- Ball := TGLSphere.CreateAsChild(GLDummyCube1);
- Ball.Radius := 0.1;
- Ball.AbsolutePosition := GLCamera1.TargetObject.AbsolutePosition;
- delta := VectorScale(GLCamera1.AbsoluteVectorToTarget, 2);
- Ball.Translate(delta.X, delta.Y, delta.Z);
- GetOrCreateNGDDynamic(Ball);
- GetNGDDynamic(Ball).Manager := GLNGDManager1;
- GetNGDDynamic(Ball).Density := 100;
- GetNGDDynamic(Ball).LinearDamping := 0.5;
- // Add impulse in the camera direction
- GetNGDDynamic(Ball).AddImpulse
- (VectorScale(GLCamera1.AbsoluteVectorToTarget, 100),
- Ball.AbsolutePosition);
- end;
- // Start Grab
- if Button = TMouseButton(mbMiddle) then
- begin
- MyX := GLSceneViewer1.Width div 2;
- MyY := GLSceneViewer1.Height div 2;
- PickedSceneObject := GLSceneViewer1.Buffer.GetPickedObject(MyX, MyY);
- if Assigned(PickedSceneObject) and Assigned
- (GetNGDDynamic(PickedSceneObject)) then
- grabJoint.ParentObject := PickedSceneObject
- else
- exit;
- point3d := PickedSceneObject.AbsolutePosition;
- // Attach the body
- grabJoint.KinematicControllerPick(point3d, paAttach);
- end;
- end;
- procedure TFormNewtonWalkShoot.GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- begin
- // Detach the body
- if Button = TMouseButton(mbMiddle) then
- grabJoint.KinematicControllerPick(NullHmgVector, paDetach);
- end;
- procedure TFormNewtonWalkShoot.ScaleMesh(freeform: TGLFreeForm; val: Single);
- var
- I, J: Integer;
- begin
- for J := 0 to freeform.MeshObjects.Count - 1 do
- for I := 0 to freeform.MeshObjects[J].Vertices.Count - 1 do
- begin
- freeform.MeshObjects[J].Vertices[I] := VectorScale
- (freeform.MeshObjects[J].Vertices[I], val);
- end;
- end;
- procedure TFormNewtonWalkShoot.MoveCam(const deltaTime, newTime: Double);
- var
- f: TGLVector;
- fup, fdn, flf, frg: TGLVector;
- Bup, Bdn, Blf, Brg: Boolean;
- NGDDyn: TGLNGDDynamic;
- begin
- Bup := IsKeyDown('w') or IsKeyDown('z') or IsKeyDown(VK_UP);
- Bdn := IsKeyDown('s') or IsKeyDown(VK_DOWN);
- Blf := IsKeyDown('d') or IsKeyDown(VK_LEFT);
- Brg := IsKeyDown('a') or IsKeyDown('q') or IsKeyDown(VK_RIGHT);
- if Bup then
- fup := GLCamera1.AbsoluteVectorToTarget
- else
- fup := VectorMake(0, 0, 0, 0);
- if Bdn then
- fdn := VectorNegate(GLCamera1.AbsoluteVectorToTarget)
- else
- fdn := VectorMake(0, 0, 0, 0);
- if Blf then
- frg := GLCamera1.AbsoluteRightVectorToTarget
- else
- frg := VectorMake(0, 0, 0, 0);
- if Brg then
- flf := VectorNegate(GLCamera1.AbsoluteRightVectorToTarget)
- else
- flf := VectorMake(0, 0, 0, 0);
- NGDDyn := GetNGDDynamic(GLCamera1.TargetObject);
- if Bup or Bdn or Blf or Brg then
- begin
- // Add every vector
- f := VectorAdd(fup, fdn);
- f := VectorAdd(f, frg);
- f := VectorAdd(f, flf);
- f.Y := 0; // Do not allow the body to go up or down
- NormalizeVector(f);
- // Move the body
- if NGDDyn.Force.VectorLength < 5 then //before - AppliedVelocity
- NGDDyn.AddImpulse(f, GLCamera1.TargetObject.AbsolutePosition);
- end
- else
- begin
- // Slow down the body if the user stop pushing keys
- if NGDDyn.Force.VectorLength > 3 then //before - AppliedVelocity
- NGDDyn.AddImpulse(VectorScale(NGDDyn.AppliedForce.AsVector, 0.5), f); //before - SetVector
- end;
- end;
- procedure TFormNewtonWalkShoot.MoveGrab;
- var
- point3d: TGLVector;
- delta: TGLVector;
- begin
- // Move the object in 3 unit front of GLCamera1.TargetObject
- if IsKeyDown(VK_MBUTTON) then
- begin
- point3d := GLCamera1.TargetObject.AbsolutePosition;
- delta := GLCamera1.AbsoluteVectorToTarget;
- while VectorLength(delta) < 3 do
- delta := VectorScale(delta, 2);
- point3d := VectorAdd(point3d, delta);
- grabJoint.KinematicControllerPick(point3d, paMove);
- end;
- end;
- end.
|