⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newtoncustomjoints.pas

📁 Newton Game Dynamic 1.52 Delphi下基于GLScene的OpenGL游戏开发控件。功能非常强大和易于使用。 Advanced physics engine for re
💻 PAS
📖 第 1 页 / 共 4 页
字号:
{*******************************************************************************}
{                                                                               }
{      Newton Game Dynamics Custom Joints Delphi-Headertranslation              }
{       Current SDK version 1.53                                                }
{                                                                               }
{      Copyright (c) 2005,06 Sascha Willems                                     }
{                            Jon Walton                                         }
{                                                                               }
{*******************************************************************************}
{                                                                               }
{ License :                                                                     }
{                                                                               }
{  The contents of this file are used with permission, 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/MPL-1.1.html                                      }
{                                                                               }
{  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.                                    }
{                                                                               }
{*******************************************************************************}
{  Custom Joints in SDK :             Implemented :                             }
{   - BallAndSocket                     Yes                                     }
{   - LimitedBallAndSocket              Yes                                     }
{   - CorkScrew                         Yes                                     }
{   - DryRollingFriction                Yes                                     }
{   - Gear                              Yes                                     }
{   - Hinge                             Yes                                     }
{   - Pulley                            Yes                                     }
{   - Slider                            Yes                                     }
{   - Universal                         Yes                                     }
{   - UpVector                          Yes                                     }
{   - WormGear                          Yes                                     }
{*******************************************************************************}

unit NewtonCustomJoints;

interface

uses
  Math,
  SysUtils,

  NewtonImport,
  NewtonCustomJoints_Math;
  
{$I delphinewton.inc}
{$IFDEF FPC}
 {$MODE DELPHI}
 {$APPTYPE GUI}
{$ENDIF}

type
 // TNewtonCustomBaseJoint =====================================================
 TNewtonCustomBaseJoint = Class(TObject)
  private
   FMaxDOF : Integer;
   FBody0  : PNewtonBody;
   FBody1  : PNewtonBody;
   FJoint  : PNewtonJoint;
   FWorld  : PNewtonWorld;
  public
   constructor Create(aMaxDOF : Integer; aBody0, aBody1 : PNewtonBody);
   destructor Destroy; override;
   procedure CalculateGlobalMatrix(const aLocalMatrix0, aLocalMatrix1 : TMatrix4f; out aMatrix0, aMatrix1 : TMatrix4f);
   procedure CalculateLocalMatrix(const aPivot, aDir : TVector3f; out aLocalMatrix0, aLocalMatrix1 : TMatrix4f);
   property Joint : PNewtonJoint read FJoint;
  protected
   procedure SubmitConstraint; virtual; abstract;
  end;                                 

 // TNewtonCustomJointUpVector =================================================
 TNewtonCustomJointUpVector = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0 : TMatrix4f;
   FLocalMatrix1 : TMatrix4f;
  public
   constructor Create(aPin: TVector3f; aBody : PNewtonBody);
   procedure SetPinDir(const aDir : TVector3f);
  protected
   procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointBallAndSocket ============================================
 TNewtonCustomJointBallAndSocket = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0 : TMatrix4f;
   FLocalMatrix1 : TMatrix4f;
  public
   constructor Create(aPivot : TVector3f; aChild, aParent : PNewtonBody);
  protected
   procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointLimitedBallAndSocket =====================================
 TNewtonCustomJointLimitedBallAndSocket = Class(TNewtonCustomJointBallAndSocket)
  private
   FConeAngle    : Single;
   FTwistAngle   : Single;
   FCosConeAngle : Single;
  public
    constructor Create(aPivot, aConeDir : TVector3f; aConeAngle, aTwistAngle : Single; aChild, aParent : PNewtonBody);
  protected
    procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointCorkScrew ================================================
 TNewtonCustomJointCorkScrew = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0   : TMatrix4f;
   FLocalMatrix1   : TMatrix4f;
   FLimitsOn       : Boolean;
   FMinDist        : Single;
   FMaxDist        : Single;
   FAngularMotorOn : Boolean;
   FAngularDamp    : Single;
   FAngularAccel   : Single;
  public
   constructor Create(aPivot, aPin : TVector3f; aChild, aParent : PNewtonBody);
   procedure EnableLimits(aEnabled : Boolean);
   procedure SetLimits(aMinDist, aMaxDist : Single);
  protected
    procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointSlider =============================================
 TNewtonCustomJointSlider = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0 : TMatrix4f;
   FLocalMatrix1 : TMatrix4f;
   FLimitsOn     : Boolean;
   FMinDist      : Single;
   FMaxDist      : Single;
  public
   constructor Create(aPivot, aPin : TVector3f; aChild, aParent : PNewtonBody);
   procedure EnableLimits(aEnabled : Boolean);
   procedure SetLimits(aMinDist, aMaxDist : Single);
  protected
   procedure SubmitConstraint; override;
  end;

  // TNewtonCustomJointHinge ===================================================
  TNewtonCustomJointHinge = Class(TNewtonCustomBaseJoint)
   private
    FLocalMatrix0   : TMatrix4f;
    FLocalMatrix1   : TMatrix4f;
    FLimitsOn       : Boolean;
    FMinAngle       : Single;
    FMaxAngle       : Single;
   public
    constructor Create(aPivot, aPin : TVector3f; aChild, aParent : PNewtonBody);
    procedure EnableLimits(aEnabled : Boolean);
    procedure SetLimits(aMinAngle, aMaxAngle : Single);
  protected
    procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointDryRollingFriction =======================================
 // This joint is usefull to simulate the rolling friction of a rolling ball over
 // a flat surface.
 // Normally this is not important for non spherical objects, but for games like
 // pool, pinball, bowling, golf or any other where the movement of balls is the
 // main objective, the rolling friction is a real big problem.
 TNewtonCustomJointDryRollingFriction = Class(TNewtonCustomBaseJoint)
  private
   FFrictionCoef   : Single;
   FFrictionTorque : Single;
  public
   constructor Create(aRadius, aCoefficient : Single; aChild : PNewtonBody);
  protected
   procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointUniversal ================================================
 TNewtonCustomJointUniversal = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0    : TMatrix4f;
   FLocalMatrix1    : TMatrix4f;
   FLimit0On        : Boolean;
   FLimit1On        : Boolean;
   FMinAngle0       : Single;
   FMaxAngle0       : Single;
   FMinAngle1       : Single;
   FMaxAngle1       : Single;
   FAngularMotor0On : Boolean;
   FAngularMotor1On : Boolean;
   FAngularDamp0    : Single;
   FAngularAccel0   : Single;
   FAngularDamp1    : Single;
   FAngularAccel1   : Single;
  public 
   constructor Create(aPivot, aPin0, aPin1 : TVector3f; aChild, aParent : PNewtonBody);
   procedure EnableLimit0(aEnabled : Boolean);
   procedure EnableLimit1(aEnabled : Boolean);
   procedure SetLimits0(aMinAngle, aMaxAngle : Single);
   procedure SetLimits1(aMinAngle, aMaxAngle : Single);
   procedure EnableMotor0(aEnabled : Boolean);
   procedure EnableMotor1(aEnabled : Boolean);
  protected
   procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointPulley ===================================================
 TNewtonCustomJointPulley = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0 : TMatrix4f;
   FLocalMatrix1 : TMatrix4f;
   FGearRatio    : Single;
  public
   property GearRatio : Single read FGearRatio write FGearRatio;
   constructor Create(aGearRatio : Single; aChildPin, aParentPin : TVector3f; aParentBody, aChildBody : PNewtonBody);
  protected
   procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointGear =====================================================
 TNewtonCustomJointGear = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0 : TMatrix4f;
   FLocalMatrix1 : TMatrix4f;
   FGearRatio    : Single;
  public
   property GearRatio : Single read FGearRatio write FGearRatio;
   constructor Create(aGearRatio : Single; aChildPin, aParentPin : TVector3f; aParentBody, aChildBody : PNewtonBody);
  protected
   procedure SubmitConstraint; override;
  end;

 // TNewtonCustomJointWormGear =================================================
 TNewtonCustomJointWormGear = Class(TNewtonCustomBaseJoint)
  private
   FLocalMatrix0 : TMatrix4f;
   FLocalMatrix1 : TMatrix4f;
   FGearRatio    : Single;
  public
   property GearRatio : Single read FGearRatio write FGearRatio;
   constructor Create(aGearRatio : Single; aRotationalPin, aLinearPin : TVector3f; aRotationalBody, aLinearBody : PNewtonBody);
  protected
   procedure SubmitConstraint; override;
  end;

implementation

const
  MIN_JOINT_PIN_LENGTH : Single = 50.0;

// =============================================================================
//  MatrixGrammSchmidt
// =============================================================================
function MatrixGrammSchmidt(const aDir: TVector3f): TMatrix4f;
var
 LUp    : TVector4f;
 LRight : TVector4f;
 LFront : TVector4f;
Begin
LFront := V4(aDir[0], aDir[1], aDir[2], 0);
LFront := VScale(LFront, 1.0 / sqrt(VDot(LFront, LFront)));
if abs(LFront[2]) > 0.577 then
 LRight := VCross(LFront, V4(-LFront[1], LFront[2], 0, 0))
else
 LRight := VCross(LFront, V4(-LFront[1], LFront[0], 0, 0));
LRight := VScale(LRight, 1.0 / sqrt(VDot(LRight, LRight)));
LUp    := VCross(LRight, LFront);
LFront[3] := 0;
LUp[3]    := 0;
LRight[3] := 0;
Matrix_SetColumn(Result, 0, LFront);
Matrix_SetColumn(Result, 1, LUp);
Matrix_SetColumn(Result, 2, LRight);
Matrix_SetColumn(Result, 3, V4(0,0,0,1));
end;

// =============================================================================
//  JointDestructor
// =============================================================================
procedure JointDestructor(const aJoint: PNewtonJoint); cdecl;
var
 LBaseJoint : TNewtonCustomBaseJoint;
Begin
LBaseJoint := TNewtonCustomBaseJoint(NewtonJointGetUserData(aJoint));
NewtonJointSetDestructor(aJoint, nil);
NewtonJointSetUserData(aJoint, nil);
FreeAndNil(LBaseJoint);
end;

// =============================================================================
//  SubmitJointConstraint
// =============================================================================
function SubmitJointConstraint(const aJoint: PNewtonJoint): unsigned_int; cdecl;
var
 LBaseJoint: TNewtonCustomBaseJoint;
begin
Result := 0;
LBaseJoint := TNewtonCustomBaseJoint(NewtonJointGetUserData(aJoint));
if LBaseJoint <> nil then
 LBaseJoint.SubmitConstraint;
end;


// *****************************************************************************
// *****************************************************************************
//  Base Joint
// *****************************************************************************
// *****************************************************************************
constructor TNewtonCustomBaseJoint.Create(aMaxDOF: Integer; aBody0, aBody1: PNewtonBody);
begin
FBody0  := aBody0;
FBody1  := aBody1;
FMaxDOF := aMaxDOF;

FWorld := NewtonBodyGetWorld(aBody0);
// @SubmitJointConstraint not working in FP
FJoint := NewtonConstraintCreateUserJoint(FWorld, FMaxDOF, @SubmitJointConstraint, FBody0, FBody1);
//FJoint := NewtonConstraintCreateUserJoint(FWorld, FMaxDOF, @SubmitJointConstraint, FBody0, FBody1);

NewtonJointSetStiffness(FJoint, 1);
NewtonJointSetUserData(FJoint, Self);
NewtonJointSetDestructor(FJoint, @JointDestructor);
end;

destructor TNewtonCustomBaseJoint.Destroy;
begin
if NewtonJointGetUserData(FJoint) <> nil then
 begin
 NewtonJointSetDestructor(FJoint, nil);
 NewtonDestroyJoint(FWorld, FJoint);
 end;

⌨️ 快捷键说明

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