oxnewtonsimplevehicle.pas

来自「Newton Game Dynamic 1.52 Delphi下基于GLSce」· PAS 代码 · 共 290 行

PAS
290
字号
// I working on different vehicle types in coming very soon...
unit oxNewtonSimpleVehicle;
{******************************************************************************}
// [15-9-2007]: oxNewtonSimpleVehicle last change by Dave Gravel.               //
{******************************************************************************}
{===============================================================================

 Version: MPL 1.1

 The contents of this file are subject to the Mozilla Public License Version
 1.1 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/


 Software distributed under the License is distributed on an "AS IS" basis,
 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.

 The Original Code is "oxNewton opengl-Dynamics-delphi-component".

 The Initial Developer of the Original Code is
 Dave Gravel, OrionX3D Opengl & Delphi Programming, dave.gravel@cgocable.ca.
                       http://www.Dave.ServeUsers.com
                       http://www.k00m.sexidude.com

 Portions created by Dave Gravel are Copyright (C) 2004 - 2006.
 Dave Gravel. All Rights Reserved.

 Contributor(s): GLScene (http://www.glscene.org) -
 Julio Jerez and Alain Suero (http://www.newtondynamics.com) -
 Sascha Willems (www.delphigl.de)
 Skinned part based on the Lucas Goraieb code.
 This he have create the skinned part based on my old ode ragdoll box demo good work.
 This work is unfinished in the moment I working on the bones editor.
 The ragdoll is build with custom joints and in smd format file loaded from the
 nice GLScene tools and Newton dynamics. 

================================================================================
 oxNewton v1.55 by Dave Gravel.

PS: I request only one thing from the users of my oxNewton Component,
it is to put on your about or your help a comment saying you using the
oxNewton Component with my name Dave Gravel and my
e-mail: dave.gravel@cgocable.ca
Don't modify or remove any comment or information on my file
if you do some modification on my code please contact me.
Read the Newton license too, it is realy important.

================================================================================}
interface
uses Windows, Dialogs, SysUtils, Classes, GLMisc, GLVectorFileObjects, GLKeyboard,
     //
     oxNewtonImport, oxNewtondll, oxNewtonUtils, oxNewtonJoint, oxNewtonCustomJoints,
     oxNewtonHelpDouble, oxNewtonDynamicMesh;

type
  TOXNewtonRayCar = class;
  TOXWheel = class;
  //
  TOXWheel = class( TOXNewtonDummy )
    private
      FMainFrame: TOXNewtonRayCar;
      FMesh: TGLFreeForm;
    public
      //
      constructor Create( aOwner: TComponent ); override;
      destructor Destroy; override;
    published
      property Mesh: TGLFreeForm read FMesh write FMesh;
  end;

  TOXNewtonRayCar = class( TOXNewtonDynMesh )
    private
      deltatime: double;
      FSter: Float;
      FAccel: boolean;
      FDistance: Float;
      FMaxDistance: Float;
      FWheelID: integer;
      FForce: TOXVector3;
      FTorque: TOXVector3;
      FVeloc: TOXVector3;
      FOmeg: TOXVector3;
      FVForce: Float;
      FGlobalSpeed: Float;
      FWheels: array[0..3] of TOXWheel;
      procedure AddForceAndTorque( Body: PNewtonBody );
      function PushRayOnFloor: Float;
      procedure Process(delta,newtime: double);
    public
      constructor Create( aOwner: TComponent ); override;
      destructor Destroy; override;
      procedure DoProgress( const progressTime: TProgressTimes ); override;
      //
      procedure InitNewton; override;
      procedure AddWheels( wFMesh, wRMesh: string; wFr, wFl, wRr, wRl: TOXVector3; wDebugView: boolean );
      property MaxDistance: Float read FMaxDistance write FMaxDistance;
      property Distance: Float read FDistance write FDistance;
      property VForce: Float read FVForce write FVForce;
      property Wheel1: TOXWheel read FWheels[0] write FWheels[0];
      property Wheel2: TOXWheel read FWheels[1] write FWheels[1];
      property Wheel3: TOXWheel read FWheels[2] write FWheels[2];
      property Wheel4: TOXWheel read FWheels[3] write FWheels[3];
  end;

function VehicleFloorRayCast( const body: PNewtonBody; const hitNormal: PFloat; collisionID: Unsigned_int; userData: Pointer; intersectParam: Float ): Float; cdecl;

implementation

function VehicleFloorRayCast( const body: PNewtonBody; const hitNormal: PFloat; collisionID: Unsigned_int; userData: Pointer; intersectParam: Float ): Float;
begin
  Result:= IntersectParam;
  TOXNewtonRayCar( userData ).FDistance:= IntersectParam;
end;

constructor TOXWheel.Create( aOwner: TComponent );
begin
  inherited Create( aOwner );
  FMesh:= TGLFreeForm( AddNewChild( TGLFreeForm ) );
end;

destructor TOXWheel.Destroy;
begin

  inherited Destroy;
end;

constructor TOXNewtonRayCar.Create( aOwner: TComponent );
begin
  inherited Create( aOwner );
  FWheelID:= 0;
  FDistance:= 0;
  FMaxDistance:= 0;
  FVForce:= 0;
  FSter:= 0;
  FForce:= oxV3Make( 0, 0, 0 );
  FTorque:= oxV3Make( 0, 0, 0 );
  FVeloc:= oxV3Make( 0, 0, 0 );
end;

function TOXNewtonRayCar.PushRayOnFloor: Float;
var
  Mat: TOXMatrix;
  P1, P2: TOXVector3;
begin
  result:= 0;
  if not Actived then exit;
  Mat:= oxMFToMD( AbsoluteMatrix );
  P1:= oxV3Make( Mat[3, 0], Mat[3, 1], Mat[3, 2] );
  P2:= oxV3Make( Mat[3, 0], Mat[3, 1], Mat[3, 2]-FMaxDistance );
  NewtonWorldRayCast( Manager.World, @P1[0], @P2[0], @VehicleFloorRayCast, self, nil );
  result:= FDistance;
end;

procedure TOXNewtonRayCar.DoProgress( const progressTime: TProgressTimes );
begin
  if not Actived then exit;
  deltatime:= progressTime.deltaTime;
  Process(progressTime.deltaTime,progressTime.newTime);
end;

procedure TOXNewtonRayCar.AddWheels( wFMesh, wRMesh: string; wFr, wFl, wRr, wRl: TOXVector3; wDebugView: boolean );
begin
  FWheels[0]:= TOXWheel( AddNewChild( TOXWheel ) );
  FWheels[1]:= TOXWheel( AddNewChild( TOXWheel ) );
  FWheels[2]:= TOXWheel( AddNewChild( TOXWheel ) );
  FWheels[3]:= TOXWheel( AddNewChild( TOXWheel ) );
  FWheels[0].Mesh.MaterialLibrary:= MaterialLibrary;
  FWheels[1].Mesh.MaterialLibrary:= MaterialLibrary;
  FWheels[2].Mesh.MaterialLibrary:= MaterialLibrary;
  FWheels[3].Mesh.MaterialLibrary:= MaterialLibrary;
  FWheels[0].Mesh.LoadFromFile( wFMesh );
  FWheels[1].Mesh.LoadFromFile( wFMesh );
  FWheels[2].Mesh.LoadFromFile( wRMesh );
  FWheels[3].Mesh.LoadFromFile( wRMesh );
  FWheels[0].VisibleAtRunTime:= wDebugView;
  FWheels[1].VisibleAtRunTime:= wDebugView;
  FWheels[2].VisibleAtRunTime:= wDebugView;
  FWheels[3].VisibleAtRunTime:= wDebugView;
  FWheels[0].Position.SetPoint( wFr[0], wFr[1], wFr[2] );
  FWheels[1].Position.SetPoint( wFl[0], wFl[1], wFl[2] );
  FWheels[2].Position.SetPoint( wRr[0], wRr[1], wRr[2] );
  FWheels[3].Position.SetPoint( wRl[0], wRl[1], wRl[2] );
  FWheels[1].Mesh.RollAngle:= 180;
  FWheels[3].Mesh.RollAngle:= 180;
  FWheels[0].FMainFrame:= self;
  FWheels[1].FMainFrame:= self;
  FWheels[2].FMainFrame:= self;
  FWheels[3].FMainFrame:= self;
end;                         

procedure TOXNewtonRayCar.InitNewton;
begin
  inherited;
  ApplyForceAndTorque:= AddForceAndTorque;
end;

procedure TOXNewtonRayCar.Process(delta,newtime: double);
var cCorVel: TOXVector3;
    i: integer;
begin
  cCorVel:= oxV3Make( AbsoluteRight[0] * FVeloc[0], AbsoluteRight[1] * FVeloc[1], 0 );
  FGlobalSpeed:= Abs( oxVLength( cCorVel ) );
  FDistance:= FMaxDistance;
  //
  FDistance:= FMaxDistance;
  if PushRayOnFloor < FMaxDistance then begin
    FForce:= oxV3Make( 0, 0, (1300*deltatime+0.5)+1150 );
  end;
  // Only in test normaly keyboard stuff is called from the form unit.
  if IsKeyDown( vk_up ) then begin
    FForce:= oxV3Make( AbsoluteRight[0] * -1000, AbsoluteRight[1] * -1000, FForce[2] );
    FAccel:= True;
  end else
  if IsKeyDown( vk_down ) then begin
    FForce:= oxV3Make( AbsoluteRight[0] * 1000, AbsoluteRight[1] * 1000, FForce[2] );
    FAccel:= True;
  end else
  if not IsKeyDown( vk_up ) and not IsKeyDown( vk_down ) then begin
    FAccel:= False;
  end;
  //
  if IsKeyDown( vk_left ) then begin
    FTorque:= oxV3Make( AbsoluteDirection[0] * 1000, 0, 360 );
  end;
    //
  if IsKeyDown( vk_right ) then begin
    FTorque:= oxV3Make( AbsoluteDirection[0] * -1000, 0, -360 ) ;
  end;
  for i:= 0 to 4 -1 do begin
    FWheels[i].Mesh.Turn( -FGlobalSpeed );
  end;
end;

procedure TOXNewtonRayCar.AddForceAndTorque( Body: PNewtonBody );
var
  fCorrection: TOXVector3;
  fOmegaCorrection: TOXVector3;
begin
  NewtonBodyGetVelocity( self.Body, @FVeloc[0] );
  NewtonBodyGetOmega( self.Body, @FOmeg[0] );
  if FDistance < (FMaxDistance-0.2) then
    FForce:= oxV3Make( FForce[0], FForce[1], FForce[2]+75+deltatime ) else
  if FDistance > FMaxDistance then
    FForce:= oxV3Make( FForce[0], FForce[1], FForce[2]-75+deltatime );
  NewtonBodyAddForce( self.Body, @FForce[0] );
  FForce:= oxV3Make( 0, 0, 0 );
  if FDistance < FMaxDistance then begin
    if FGlobalSpeed > 0.1 then
      NewtonBodyAddTorque( self.Body, @FTorque[0] );
    FTorque:= oxV3Make( 0, 0, 0 );
  end;
  if FDistance >= FMaxDistance then begin
    AddForceAtPos( self.Body,oxV3Make(0,0,75), oxV3Make( FWheels[0].FMesh.AbsolutePosition[0],
                                                          FWheels[0].FMesh.AbsolutePosition[1],
                                                          FWheels[0].FMesh.AbsolutePosition[2] ) );
    AddForceAtPos( self.Body,oxV3Make(0,0,75), oxV3Make( FWheels[1].FMesh.AbsolutePosition[0],
                                                          FWheels[1].FMesh.AbsolutePosition[1],
                                                          FWheels[1].FMesh.AbsolutePosition[2] ) );
    AddForceAtPos( self.Body,oxV3Make(0,0,85), oxV3Make( FWheels[2].FMesh.AbsolutePosition[0],
                                                          FWheels[2].FMesh.AbsolutePosition[1],
                                                          FWheels[2].FMesh.AbsolutePosition[2] ) );
    AddForceAtPos( self.Body,oxV3Make(0,0,85), oxV3Make( FWheels[3].FMesh.AbsolutePosition[0],
                                                          FWheels[3].FMesh.AbsolutePosition[1],
                                                          FWheels[3].FMesh.AbsolutePosition[2] ) );
  end;
  if ( FGlobalSpeed > 0.1 ) then begin
    fCorrection[0]:= ( FVeloc[0] / 1.0075 );
    fCorrection[1]:= ( FVeloc[1] / 1.0075 );
    fCorrection[2]:= FVeloc[2];
    NewtonBodySetVelocity( self.Body, @fCorrection[0] );
  end;
  fOmegaCorrection[0]:= ( FOmeg[0] / 1.075 );
  fOmegaCorrection[1]:= ( FOmeg[1] / 1.075 );
  fOmegaCorrection[2]:= ( FOmeg[2] / 1.0175 );
  NewtonBodySetOmega( self.Body, @fOmegaCorrection[0] );
end;

destructor TOXNewtonRayCar.Destroy;
begin

  inherited Destroy;
end;
{******************************************************************************}
{$D '[15-9-2007]: TOXNewtonManager v1.55 by Dave Gravel under MPL-1.1 license.'}
{******************************************************************************}
end.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?