📄 oxnewtonsmdragdoll.pas
字号:
{******************************************************************************}
procedure TOXNewtonRagdoll.BuildRagdoll( pRagdoll: PNewtonRagdoll; pParentdollBone: PNewtonRagdollBone;
pVelocity: TOXVector3; var pBone: TOXNewtonRagdollBone );
var
Body: PNewtonBody;
DollBone: PNewtonRagdollBone;
Collider: PNewtonCollision;
Size: TOXVector3;
Matrix: TOXMatrix;
ConeDir: TOXVector3;
LateralDir: TOXVector3;
i: Integer;
begin
Size:= pBone.Size;
Matrix:= pBone.Matrix;
Collider:= nil;
DollBone:= nil;
case pBone.GeomType of
mdBox:
begin
pBone.Box:= TOXNewtonBoneCube( RagdollDummy.AddNewChild( TOXNewtonBoneCube ) );
pBone.Box.CubeWidth:= Size[0]; pBone.Box.CubeHeight:= Size[1]; pBone.Box.CubeDepth:= Size[2];
pBone.Box.Material.FrontProperties.Diffuse.RandomColor;
Collider:= NewtonCreateBox( Manager.World, Size[0], Size[1], Size[2], nil );
DollBone:= NewtonRagdollAddBone( pRagdoll, pParentdollBone, pBone.Box, 10, @Matrix[0], Collider, @Size[0] );
end;
mdCylinder:
begin
pBone.Cylinder:= TOXNewtonBoneCylinder( RagdollDummy.AddNewChild( TOXNewtonBoneCylinder ) );
pBone.Cylinder.TopRadius:= Size[1] / 2; pBone.Cylinder.Height:= Size[0];
pBone.Cylinder.Material.FrontProperties.Diffuse.RandomColor;
Collider:= NewtonCreateCapsule( Manager.World, Size[1] / 2, Size[0], nil );
DollBone:= NewtonRagdollAddBone( pRagdoll, pParentdollBone, pBone.Cylinder, 10, @Matrix[0], Collider, @Size[0] );
end;
mdSphere:
begin
pBone.SPhere:= TOXNewtonBoneSphere( RagdollDummy.AddNewChild( TOXNewtonBoneSphere ) );
pBone.SPhere.Radius:= Size[0] / 2;
pBone.SPhere.Material.FrontProperties.Diffuse.RandomColor;
Collider:= NewtonCreateSphere( Manager.World, Size[0] / 2, Size[1] / 2, Size[2] / 2, nil );
DollBone:= NewtonRagdollAddBone( pRagdoll, pParentdollBone, pBone.SPhere, 10, @Matrix[0], Collider, @Size[0] );
end;
end;
ConeDir:= oxV3Make( 1, 0, 0 );
LateralDir:= oxV3Make( 0, 0, 1 );
oxTranslateM( pBone.Matrix, ConeDir );
oxTranslateM( pBone.Matrix, LateralDir );
NewtonRagdollBoneSetID( DollBone, pBone.ID );
NewtonRagdollBoneSetLimits( DollBone, @ConeDir[0], -PI*0.25, PI*0.25, -PI*0.5, @LateralDir[0], 0, 0 );
Body:= NewtonRagdollBoneGetBody( DollBone );
case pBone.GeomType of
mdBox: NewtonBodySetUserData( Body, pBone.Box );
mdCylinder: NewtonBodySetUserData( Body, pBone.Cylinder );
mdSphere: NewtonBodySetUserData( Body, pBone.SPhere );
end;
pBone.Body:= Body;
NewtonReleaseCollision( Manager.World, Collider );
if Length( pBone.Children ) > 0 then
for i := 0 to High( pBone.Children ) do BuildRagdoll( pRagdoll, DollBone, pVelocity, pBone.Children[i] );
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
procedure TOXNewtonRagdoll.CreateRagdoll( pPosition, pVelocity, pRotation: TOXVector3; pHangByHead: Boolean = False );
const
HeadSize = 0.5;
var
SpineSize: TOXVector3;
HeadBody: PNewtonBody;
HeadBone: PNewtonRagdollBone;
SpineBody: PNewtonBody;
SpineBone: PNewtonRagdollBone;
Mat: TOXMatrix;
Pivot: TOXVector3;
rMat: TOXMatrix;
i: Integer;
begin
RagdollDummy:= TOXNewtonDummy( Scene.Objects.AddNewChild( TOXNewtonDummy ) );
RagdollDummy.Visible:= False;
// root
Spine0_Bone:= TOXNewtonRagdollBone.create;
Spine0_Bone.CreateBone( mdBox );
SpineSize:= oxV3Make( HeadSize * 1.2, HeadSize, HeadSize * 1.2 );
Spine0_Bone.Size:= SpineSize;
oxSetM( Spine0_Bone.Matrix, oxIdentityM );
oxTranslateM( Spine0_Bone.Matrix, oxV3Make( pPosition[0], pPosition[1], pPosition[2] ) );
rMat:= oxCreateRotationM( oxV3Make( pRotation[0], pRotation[1], pRotation[2] ), 90 );
Spine0_Bone.Matrix:= oxMMultiply( rMat, Spine0_Bone.Matrix );
Spine0_Bone.ID:= 0;
Spine0_Bone.Name:= 'Spine0_Bone';
//
Spine1_Bone:= TOXNewtonRagdollBone.create;
Spine1_Bone.CreateBone( mdBox );
Spine1_Bone.Size:= SpineSize;
oxSetM( Spine1_Bone.Matrix, oxIdentityM );
oxTranslateM( Spine1_Bone.Matrix, oxV3Make( SpineSize[0], 0, 0 ) );
Spine1_Bone.ID:= 1;
Spine1_Bone.Name:= 'Spine1_Bone';
//
head_Bone:= TOXNewtonRagdollBone.create;
head_Bone.CreateBone( mdSphere );
head_Bone.Size:= oxV3Make( HeadSize, HeadSize, HeadSize );
oxSetM( head_Bone.Matrix, oxIdentityM );
oxTranslateM( head_Bone.Matrix, oxV3Make( SpineSize[0], 0, 0 ) );
head_Bone.ID:= 2;
head_Bone.Name:= 'head_Bone';
//
rUpperArm_Bone:= TOXNewtonRagdollBone.create;
rUpperArm_Bone.CreateBone( mdCylinder );
rUpperArm_Bone.Size:= oxV3Make( HeadSize * 1.5, HeadSize * 0.5, HeadSize * 0.5 );
oxSetM( rUpperArm_Bone.Matrix, oxIdentityM );
oxTranslateM( rUpperArm_Bone.Matrix, oxV3Make( SpineSize[0], 0, SpineSize[0] * 0.55 ) );
rMat:= oxCreateRotationM( oxV3Make( 0, 90, 0 ), 360 );
rUpperArm_Bone.Matrix:= oxMMultiply( rMat, rUpperArm_Bone.Matrix );
rUpperArm_Bone.ID:= 3;
rUpperArm_Bone.Name:= 'rUpperArm_Bone';
//
rLowerArm_Bone:= TOXNewtonRagdollBone.create;
rLowerArm_Bone.CreateBone( mdCylinder );
rLowerArm_Bone.Size:= oxV3Make( HeadSize * 1.5, HeadSize * 0.5, HeadSize * 0.5 );
oxSetM( rLowerArm_Bone.Matrix, oxIdentityM );
oxTranslateM( rLowerArm_Bone.Matrix, oxV3Make( HeadSize * 1.5, 0, 0 ) );
rLowerArm_Bone.ID:= 4;
rLowerArm_Bone.Name:= 'rLowerArm_Bone';
//
lUpperArm_Bone:= TOXNewtonRagdollBone.create;
lUpperArm_Bone.CreateBone( mdCylinder );
lUpperArm_Bone.Size:= oxV3Make( HeadSize * 1.5, HeadSize * 0.5, HeadSize * 0.5 );
oxSetM( lUpperArm_Bone.Matrix, oxIdentityM );
oxTranslateM( lUpperArm_Bone.Matrix, oxV3Make( SpineSize[0], 0, -SpineSize[0] * 0.55 ) );
rMat:= oxCreateRotationM( oxV3Make( 0, -90, 0 ), 360 );
lUpperArm_Bone.Matrix:= oxMMultiply( rMat, lUpperArm_Bone.Matrix );
lUpperArm_Bone.ID:= 5;
lUpperArm_Bone.Name:= 'lUpperArm_Bone';
//
lLowerArm_Bone:= TOXNewtonRagdollBone.create;
lLowerArm_Bone.CreateBone( mdCylinder );
lLowerArm_Bone.Size:= oxV3Make( HeadSize * 1.5, HeadSize * 0.5, HeadSize * 0.5 );
oxSetM( lLowerArm_Bone.Matrix, oxIdentityM );
oxTranslateM( lLowerArm_Bone.Matrix, oxV3Make( HeadSize * 1.5, 0, 0 ) );
lLowerArm_Bone.ID:= 6;
lLowerArm_Bone.Name:= 'lLowerArm_Bone';
//
rUpperLeg_Bone:= TOXNewtonRagdollBone.create;
rUpperLeg_Bone.CreateBone( mdCylinder );
rUpperLeg_Bone.Size:= oxV3Make(HeadSize * 2.0, HeadSize * 0.75, HeadSize * 0.75 );
oxSetM( rUpperleg_Bone.Matrix, oxIdentityM );
oxTranslateM( rUpperleg_Bone.Matrix, oxV3Make( 0, 0, SpineSize[0] * 0.35 ) );
rMat:= oxCreateRotationM( oxV3Make( 0, 0, 180 ), 15.5 );
rUpperleg_Bone.Matrix:= oxMMultiply( rMat, rUpperleg_Bone.Matrix );
rUpperleg_Bone.ID:= 7;
rUpperleg_Bone.Name:= 'rUpperleg_Bone';
//
rLowerleg_Bone:= TOXNewtonRagdollBone.create;
rLowerleg_Bone.CreateBone( mdCylinder );
rLowerleg_Bone.Size:= oxV3Make( HeadSize * 2.0, HeadSize * 0.65, HeadSize * 0.65 );
oxSetM( rLowerleg_Bone.Matrix, oxIdentityM );
oxTranslateM( rLowerleg_Bone.Matrix, oxV3Make( HeadSize * 2, 0, 0 ) );
rLowerleg_Bone.ID:= 8;
rLowerleg_Bone.Name:= 'rLowerleg_Bone';
//
lUpperleg_Bone:= TOXNewtonRagdollBone.create;
lUpperleg_Bone.CreateBone( mdCylinder );
lUpperleg_Bone.Size:= oxV3Make( HeadSize * 2.0, HeadSize * 0.75, HeadSize * 0.75 );
oxSetM( lUpperleg_Bone.Matrix, oxIdentityM );
oxTranslateM( lUpperleg_Bone.Matrix, oxV3Make( 0, 0, -SpineSize[0] * 0.35 ) );
rMat:= oxCreateRotationM( oxV3Make( 0, 0, 180 ), 15.5 );
lUpperleg_Bone.Matrix:= oxMMultiply( rMat, lUpperleg_Bone.Matrix );
lUpperleg_Bone.ID:= 9;
lUpperleg_Bone.Name:= 'lUpperleg_Bone';
//
lLowerleg_Bone:= TOXNewtonRagdollBone.create;
lLowerleg_Bone.CreateBone( mdCylinder );
lLowerleg_Bone.Size:= oxV3Make( HeadSize * 2.0, HeadSize * 0.65, HeadSize * 0.65 );
oxSetM( lLowerleg_Bone.Matrix, oxIdentityM );
oxTranslateM( lLowerleg_Bone.Matrix, oxV3Make( HeadSize * 2, 0, 0 ) );
lLowerleg_Bone.ID:= 10;
lLowerleg_Bone.Name:= 'lLowerleg_Bone';
//
AddChildren( Spine0_Bone, Spine1_Bone );
AddChildren( Spine1_Bone, Head_Bone );
AddChildren( Spine1_Bone, rUpperArm_Bone );
AddChildren( rUpperArm_Bone, rLowerArm_Bone );
AddChildren( Spine1_Bone, lUpperArm_Bone );
AddChildren( lUpperArm_Bone, lLowerArm_Bone );
AddChildren( Spine0_Bone, rUpperleg_Bone );
AddChildren( rUpperleg_Bone, rLowerleg_Bone );
AddChildren( Spine0_Bone, lUpperleg_Bone );
AddChildren( lUpperleg_Bone, lLowerleg_Bone );
//
SetLength( Bone, 11 );
Bone[0]:= Spine0_Bone;
Bone[1]:= Spine1_Bone;
Bone[2]:= Head_Bone;
Bone[3]:= rUpperArm_Bone;
Bone[4]:= rLowerArm_Bone;
Bone[5]:= lUpperArm_Bone;
Bone[6]:= lLowerArm_Bone;
Bone[7]:= rUpperleg_Bone;
Bone[8]:= rLowerleg_Bone;
Bone[9]:= lUpperleg_Bone;
Bone[10]:= lLowerleg_Bone;
//
Ragdoll:= NewtonCreateRagdoll( Manager.World );
NewtonRagdollBegin( Ragdoll );
NewtonRagdollSetForceAndTorqueCallback( Ragdoll, @oxRagdollForceAndTorque );
BuildRagdoll( Ragdoll, nil, pVelocity, Spine0_Bone );
NewtonRagdollEnd( Ragdoll );
if pHangByHead then
begin
HeadBone:= NewtonRagdollFindBone( Ragdoll, 2 );
HeadBody:= NewtonRagdollBoneGetBody( HeadBone );
SpineBone:= NewtonRagdollFindBone( Ragdoll, 1 );
SpineBody:= NewtonRagdollBoneGetBody( SpineBone );
NewtonBodyGetMatrix( HeadBody, @Mat[0, 0] );
Pivot:= oxV3Make( Mat[3,0], Mat[3,1], Mat[3,2] );
NewtonConstraintCreateBall( Manager.World, @Pivot[0], HeadBody, SpineBody );
end;
for i := 0 to High( Bone ) do
begin
oxSetRagdollMaterial( Bone[i].Body );
end;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
procedure TOXNewtonRagdoll.Render;
var
i: Integer;
begin
for i := 0 to High( Bone ) do
Bone[i].Render;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
procedure TOXNewtonRagdoll.AddChildren( var pParent: TOXNewtonRagdollBone; pChildren: TOXNewtonRagdollBone );
begin
SetLength( pParent.Children, Length( pParent.Children ) + 1 );
pParent.Children[High( pParent.Children )]:= pChildren;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
constructor TOXNewtonRagdoll.Create( aOwner: TComponent );
begin
inherited Create( aOwner );
FActived:= False;
OXVisual:= False;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
procedure TOXNewtonRagdoll.SetManager( const val: TOXNewtonManager );
begin
if ( val <> FManager ) then
FManager:= val;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
procedure TOXNewtonRagdoll.InitNewton;
begin
FManager:= TOXNewtonManager(Scene);
if FActived or ( FManager = nil ) then Exit;
CreateRagdoll( oxV3Make( Position.X, Position.Y, Position.Z ),
oxV3Make( 0, 0, 0 ),
oxV3Make( 0.0001 + PitchAngle, 0.0001 + RollAngle, 0.0001 + TurnAngle ),
False );
FActived:= True;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
procedure TOXNewtonRagdoll.DoProgress( const progressTime: TProgressTimes );
begin
inherited;
if FActived then begin
Render;
if RagdollDummy.Visible=False then RagdollDummy.Visible:=True;
end;
end;
{******************************************************************************}
// [15-9-2007]: TOXNewtonRagdoll last change by Dave Gravel. //
{******************************************************************************}
destructor TOXNewtonRagdoll.Destroy;
var i: integer;
begin
if FActived then begin
FActived:= False;
RagdollDummy.Free;
for i:= 0 to 10 do Bone[i].Free;
NewtonDestroyRagDoll( FManager.World, Ragdoll );
end;
FActived:= False;
inherited destroy;
end;
{******************************************************************************}
{$D '[15-9-2007]: TOXNewtonManager v1.55 by Dave Gravel under MPL-1.1 license.'}
{******************************************************************************}
initialization
RegisterClasses( [ TOXNewtonSkinRagdoll, TOXNewtonRagdoll ] );
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -