📄 colli3dx.pas
字号:
unit colli3DX;
{$include DelphiXcfg.inc}
//*************************************************************************
//* *
//* TCollisionTester3DX vs 1.3 *
//* *
//*************************************************************************
//
// This Delphi 4, 5, 6 component is CopyRight:
//
// Henrik Fabricius, August 1999, March 2000, June 2002
// http://users.cybercity.dk/~bbl6194/delphi3dx.htm
// E-mail: henrik_og_bodil@vip.cybercity.dk
//
// You may use this component for free on the following conditions:
// 1) this text must remain part of the unit.
// 2) Any proposals for changes or improvements should be addressed directly to
// the copyright owner Henrik Fabricius
// 3) The use of this component is on your own risk. The software is provided
// as is without any garanties and warranty. The CopyRight Owner is not
// responsible for any damage or losses of any kind caused by the use of this
// software or the software it is intended to be used with.
//
// To place a link for down-loads of this component on your homepage
// please place a link to the Delphi3DX page where the latest version
// is available.
//
// To use this component you must have
// 1) Delphi 4, 5 or 6
// 2) MS-DirectX 6.0 or higher
// 3) the DelphiX components from Hori in Japan
//
// MS-DirectX is a trademark of the Microsoft Corporation
// Delphi 4, 5 and 6 is a trademark of the Inprise Corporation
//
// Use this component to check for collisions between 3D objects in
// Direct3D games.
// Place your 3D-objects in a world described by :
// - DXDrawUsed -
//
// Group the 3D-objects in series with different material
// or functional properties
// The 3D-object series are named by the property:
// - Indexof3DSeries -
// 3D-objects are named by the property :
// - Indexof3Dobject -
// A 3D-object consist of one or more 3D-elements named by the property :
// - Indexof3DElement -
//
// Surround each of your 3D elements by at least one collision object
// which must be a member of the following primitives :
// - box3D - sphere3D - ellipsoid3D - cylinder3D - conus3D -
// available CollOrientations are :
// - Symmetric_X - Symmetric_Y - Symmetric_Z -
// available material properties are :
// - solid3D - water3D - air3D
// the size of the small end of the conus is described by the property
// - PercentLeftatTop -
// a negative value means that the top is downwards
// available functional properties are :
// - Pickable - Shootable - Fixed3DObject
// Add each object by specifying :
// - FrameSeries - NextAddMesh - CoverWholeMesh -
// - IndexOf3DSeries - IndexOf3DObject - IndexOf3DElement -
// if coverWholeMesh is false then specify a box containing the part of the
// 3D object which should be covered by the coll object by the commands
// - BoxPartMin(x,y,z) - BoxPartMax(x,y,z) -
// Finally add the collision object by executing the command
// - AddCollisionObject -
//
// Bullets are described by the following properties :
// - BulletRadius - BulletRange - BulletFrame - LongShots -
// LongShots moves with a unlimited speed reaching the objects immediately
//
// The actor is described by :
// - FrontDistance - HeadRadius -
//
// The camera-frame and the bullet-frames move each time the move command
// is used in the main program.
// Execute the following commands prior to each move command :
// - GetOldEyePos - GetOldBulletPos -
// The collisionTester needs this information to test for a possible collision
// in between the starting and the ending points of the Eye/bullet
//
// Test for collision with the following function calls :
// - if CollisionTester3DX1.Collision then ..
// - if CollisionTester3DX1.BulletCollision then ..
// On collision read the HitLinkNr and the properties of the collision object
//
// Destroy 3D collisionObjects by specifying :
// - NextDestroyNr - IndexOf3DSeries -
// and the executing command DestroyCollisionObject
//
// Initialize the collisionTester with the command :
// - CollisionTester3DX1.ZeroSetIt -
// This must always be done when DXDraw is initialized
//
// To install the component:
// 1) place this unit and the dcr file in the same directory as DelphiX
// 2) In Delphi you must click on Component - Install Component
// 3) Select the colli3DX.pas file and choose the Samples package to install it
// 4) Rebuild the library
// 5) Look for a new icon with a bomb on the page named DelphiX
//
// Tutorial programs are available for down-load at
// http://users.cybercity.dk/~bbl6194/delphi3dx.htm
//
// Good Luck
// Henrik Fabricius
//
//
//****************************************************************************
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, DXClass, DXDraws,
{$IfDef StandardDX}
DirectDraw, Direct3D, Direct3DRM;
{$Else}
DirectX;
{$EndIf}
Type
Tshapes3D = (box3D, sphere3D, ellipsoid3D, cylinder3D, conus3D);
Tmaterials3D = (solid3D, water3D, air3D);
TOrientation3D = (symmetric_x, symmetric_y, symmetric_z);
TFrames3D = Array of Array of IDirect3DRMFrame;
TCollisionTester3DX = class(TComponent)
private
{private declarations}
FDXDrawUsed : TDXDraw;
FFrameSeries : TFrames3D;
FNextAddMesh : IDirect3DRMMesh;
FBulletFrame : IDirect3DRMFrame;
FBoxPartMin : TD3DVector;
FBoxPartMax : TD3DVector;
FOldBulletPosition: TD3DVector;
FOldEyePosition : TD3DVector;
FNrOfSeries : integer;
FSeriesIndex : integer;
FSeriesNr : integer;
FOrientation3D : TOrientation3D;
Fshape3D : Tshapes3D;
Fmaterial3D : Tmaterials3D;
FPercentLeftAtTop : integer;
Fbullet_hitLinknr : integer;
FIndexOf3DObject : integer;
FIndexOf3DElement : integer;
FNextDestroyNr : integer;
FNextAllOfMesh : Boolean;
FFrontDistance : integer;
FBulletRange : integer;
FBulletRadius : integer;
FHeadRadius : integer;
FFixed3DObject : Boolean;
FShootable : Boolean;
FLongShots : Boolean;
FPickable : Boolean;
FCheckAllCollObj : Boolean;
Fcoll_Nr_Objects : Array of integer;
FSeriesIndex_for_SeriesNr : Array of integer;
FNrinFrameSeries : Array of Array of integer;
Fcoll_orientation : Array of Array of TOrientation3D;
Fcoll_shape : Array of Array of Tshapes3D;
Fcoll_material : Array of Array of Tmaterials3D;
Fcoll_box_min : Array of Array of TD3DVector;
Fcoll_box_max : Array of Array of TD3DVector;
Fcoll_radius : Array of Array of TD3DValue;
Fcoll_frac_at_top : Array of Array of TD3DValue;
Fcoll_shootable : Array of Array of boolean;
Fcoll_Pickable : Array of Array of boolean;
Fcoll_Fixed3D : Array of Array of boolean;
Fcoll_objectNr : Array of Array of integer;
procedure SetOrientation3D(Value : TOrientation3D);
procedure SetShape3D(Value: TShapes3D);
procedure SetMaterial3D(Value: Tmaterials3D);
procedure SetPercentLeftatTop(Value: integer);
procedure SetIndexOf3DObject(Value : integer);
procedure SetIndexOf3DElement(Value : integer);
procedure SetIndexOf3DSeries(Value : integer);
procedure SetNextDestroyNr(Value : Integer);
procedure SetBulletRadius(Value : Integer);
procedure SetHeadRadius(Value : Integer);
procedure SetFrontDistance(Value : Integer);
procedure SetBulletRange(Value : Integer);
function add_space_for_one_more : boolean;
procedure GetTheBox;
procedure AddBox;
procedure AddSphere;
procedure AddCylinder;
procedure AddConus;
procedure AddEllipsoid;
procedure MakeNewSeries;
procedure Destroy_empty_series(SeriesNr : integer);
function GetSeriesNr(Nr : integer): integer;
procedure remove_collision_object(seriesNr, Value : integer);
function CheckForSeriesIndex(indexnow : integer): boolean;
procedure ListDataForCollObject;
function coll_test_box(coll_nr : byte;
old_attacker_position, attacker_position : TD3DVector;
bullet_radius : TD3DValue; longshot : boolean): boolean;
function coll_test_cylinder(coll_nr : byte;
old_attacker_position, attacker_position : TD3DVector;
bullet_radius : TD3DValue; longshot : boolean): boolean;
function coll_test_sphere(coll_nr : byte;
old_attacker_position,
attacker_position : TD3DVector;
bullet_radius : TD3Dvalue; longshot : boolean): boolean;
function coll_test_ellipsoid(coll_nr : byte;
old_attacker_position, attacker_position : TD3DVector;
bullet_radius : TD3DValue; longshot : boolean): boolean;
function coll_test_conus(coll_nr : byte;
old_attacker_position, attacker_position : TD3DVector;
bullet_radius : TD3DValue; longshot : boolean): boolean;
protected
public
Constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
property DXDrawUsed : TDXDraw write FDXDrawUsed stored false;
property FrameSeries : TFrames3D write FFrameSeries stored false;
property NextAddMesh : IDirect3DRMMesh write FNextAddMesh stored false;
property BulletFrame : IDirect3DRMFrame write FBulletFrame stored false;
procedure ZeroSetIt;
procedure BoxPartMin(xval, yval, zval: TD3DValue);
procedure BoxPartMax(xval, yval, zval: TD3DValue);
procedure GetOldBulletPos;
procedure GetOldEyePos;
function HitLinkNr: integer;
function DestroyCollisionObject: boolean;
procedure AddCollisionObject;
function Collision: boolean;
function Bulletcollision: boolean;
function BulletDead : boolean;
published
property BulletRadius : Integer read FBulletRadius write SetBulletRadius
default 0;
property BulletRange : Integer read FbulletRange write SetBulletRange
Default 100;
property CollisionCheckAll: Boolean read FCheckAllCollObj
write FCheckAllCollObj Default true;
property CollOrientation : TOrientation3D read FOrientation3D
write SetOrientation3D default symmetric_y;
property CollObjectType : Tshapes3D read Fshape3D write SetShape3D
default box3D;
property CollObjMaterial : Tmaterials3D read Fmaterial3D write SetMaterial3D
default solid3D;
property CoverWholeMesh : boolean read FNextAllOfMesh
write FNextAllOfMesh default true;
Property Fixed3DObject : boolean read FFixed3DObject
write FFixed3DObject default true;
property FrontDistance : Integer read FFrontDistance
write SetFrontDistance default 0;
property HeadRadius : integer read FHeadRadius write SetHeadRadius
default 0;
property IndexOf3DSeries : integer read FSeriesIndex
write SetIndexOf3DSeries default 0;
property IndexOf3DObject : integer read FIndexOf3DObject
write SetIndexOf3DObject default 0;
property IndexOf3DElement : integer read FIndexOf3DElement
write SetIndexOf3DElement default 0;
property NextDestroyNr : Integer read FNextDestroyNr
write SetNextDestroyNr default 0;
Property PercentLeftAtTop : integer read FPercentLeftAtTop
write SetPercentLeftAtTop default 0;
Property Pickable : Boolean read FPickable write FPickable
default false;
Property Shootable : boolean read FShootable write FShootable
Default false;
Property LongShots : boolean read FLongShots write FLongShots
Default false;
end; //end of Class
//Registering of the Component
Procedure Register;
implementation
procedure Register;
begin
//Register the component together with the DelphiX components from Hori
RegisterComponents('DelphiX', [TCollisionTester3DX]);
end; //end of Register
constructor TCollisionTester3DX.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
//The constructor always clears the storage it allocates for a new object
//Hence there is no need to initialize fields except to nonzero or nonempty
//values
FDXDrawUsed := nil;
FFrameSeries := nil;
FNextAddMesh := nil;
FBulletFrame := nil;
FOrientation3D := symmetric_y;
FShape3D := box3D;
FMaterial3D := solid3D;
FBulletRange := 100;
FNrOfSeries := 0;
setlength(FSeriesIndex_for_SeriesNr, 0);
setlength(FColl_nr_objects, 0);
setlength(FNrinFrameSeries, 0);
setlength(Fcoll_shape, 0);
setlength(Fcoll_box_min, 0);
setlength(Fcoll_box_max, 0);
setlength(Fcoll_radius, 0);
setlength(Fcoll_frac_at_top, 0);
setlength(Fcoll_objectnr, 0);
setlength(Fcoll_shootable, 0);
setlength(Fcoll_pickable, 0);
setlength(Fcoll_orientation, 0);
setlength(Fcoll_material, 0);
setlength(Fcoll_Fixed3D, 0);
end; //end of creation
destructor TCollisionTester3DX.Destroy;
begin
//destroy any embedded objects and free resources allocated by the objects
FnrinFrameSeries := nil;
Fcoll_shape := nil;
Fcoll_box_min := nil;
Fcoll_box_max := nil;
Fcoll_radius := nil;
Fcoll_frac_at_top := nil;
Fcoll_objectnr := nil;
Fcoll_shootable := nil;
Fcoll_pickable := nil;
Fcoll_orientation := nil;
Fcoll_material := nil;
Fcoll_Fixed3D := nil;
FSeriesIndex_for_SeriesNr := nil;
Fcoll_nr_objects := nil;
inherited Destroy;
end; //end of Destroy
procedure TCollisionTester3DX.ZeroSetIt;
begin
//initialises the dynamic arrays
FnrinFrameSeries := nil;
Fcoll_shape := nil;
Fcoll_box_min := nil;
Fcoll_box_max := nil;
Fcoll_radius := nil;
Fcoll_frac_at_top := nil;
Fcoll_objectnr := nil;
Fcoll_shootable := nil;
Fcoll_pickable := nil;
Fcoll_orientation := nil;
Fcoll_material := nil;
Fcoll_Fixed3D := nil;
FSeriesIndex_for_SeriesNr := nil;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -