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 + -
显示快捷键?