📄 colli3dx.pas
字号:
Fcoll_nr_objects[SeriesNr]);
Fcoll_radius[SeriesNr] := copy(Fcoll_radius[SeriesNr], 0,
Fcoll_nr_objects[SeriesNr]);
Fcoll_frac_at_top[SeriesNr] := copy(Fcoll_frac_at_top[SeriesNr], 0,
Fcoll_nr_objects[SeriesNr]);
Fcoll_objectnr[SeriesNr] := copy(Fcoll_objectnr[SeriesNr], 0,
Fcoll_nr_objects[SeriesNr]);
Fcoll_shootable[SeriesNr] := copy(Fcoll_shootable[SeriesNr], 0,
Fcoll_nr_objects[SeriesNr]);
Fcoll_pickable[SeriesNr] := copy(Fcoll_pickable[SeriesNr], 0,
Fcoll_nr_objects[SeriesNr]);
Fcoll_material[SeriesNr] := copy(Fcoll_material[SeriesNr], 0,
Fcoll_nr_objects[FSeriesNr]);
Fcoll_orientation[SeriesNr] := copy(Fcoll_orientation[SeriesNr], 0,
Fcoll_nr_objects[FSeriesNr]);
Fcoll_fixed3D[SeriesNr] := copy(Fcoll_fixed3D[SeriesNr], 0,
Fcoll_nr_objects[SeriesNr]);
end; //end of Remove_Collision_Object
procedure TCollisionTester3DX.GetTheBox;
var
box: TD3DRMBOX;
begin
if FNextAllOfMesh
then
begin
FNextAddMesh.GetBox(box);
FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := box.min;
FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := box.max;
end
else
begin
FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FBoxPartMin;
FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FBoxPartMax;
end;
end; //end of GetTheBox
procedure TCollisionTester3DX.BoxPartMin(xval, yval, zval : TD3DValue);
begin
FBoxPartMin.x := xval;
FBoxPartMin.y := yval;
FBoxPartMin.z := zval;
end; //end of BoxPartMin
procedure TCollisionTester3DX.BoxPartMax(xval, yval, zval : TD3DValue);
begin
FBoxPartMax.x := xval;
FBoxPartMax.y := yval;
FBoxPartMax.z := zval;
end; //end of BoxPartMax
procedure TCollisionTester3DX.AddBox;
begin
if add_space_for_one_more
then
begin
GetTheBox;
Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject;
Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := box3D;
FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement;
Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used
Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used
Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D;
Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D;
Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] -1)] := Fshootable;
Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable;
Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject;
end;
end; //end of AddBox
procedure TCollisionTester3DX.AddSphere;
begin
if add_space_for_one_more
then
begin
GetTheBox;
Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject;
Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := sphere3D;
FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement;
Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] :=
(FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x
+ FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y
+ FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].z)/2/3;
Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used
Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D;
Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D;
Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fshootable;
Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable;
Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject;
end;
end; //end of AddSphere
procedure TCollisionTester3DX.Addcylinder;
begin
//the sphere cowers whole of the 3D-object
if add_space_for_one_more
then
begin
GetTheBox;
Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject;
Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := cylinder3D;
FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement;
case Forientation3D of
symmetric_x : Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] :=
(FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].y
+ FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z)/2/2;
symmetric_y : Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] :=
(FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].x
+ FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z)/2/2;
symmetric_z : Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] :=
(FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].x
+ FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y)/2/2;
end;
Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used
Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D;
Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D;
Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fshootable;
Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable;
Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject;
end;
end; //end of Addcylinder
procedure TCollisionTester3DX.Addconus;
begin
//the conus cowers whole of or part of the 3D-object
//fraction_left_at_top = 0 if sharp tip
if add_space_for_one_more
then
begin
GettheBox;
Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject;
Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := conus3D;
FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement;
Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] :=
(FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x
+ FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z
- FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z)/2/2;
Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FPercentLeftAtTop/100;
Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D;
Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D;
Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] -1)] := Fshootable;
Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable;
Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject;
end;
end; //end of Addconus
procedure TCollisionTester3DX.AddEllipsoid;
begin
if add_space_for_one_more
then
begin
GetTheBox;
Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject;
Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Ellipsoid3D;
FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement;
Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used
Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used
Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D;
Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D;
Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fshootable;
Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable;
Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject;
end;
end; //end of AddEllipsoid
function TcollisionTester3DX.GetSeriesNr(Nr : integer): integer;
var
NrNow, i : integer;
begin
if FNrOfSeries = 0
then
NrNow := 0
else
begin
NrNow := -1;
for i := 0 to (FNrOfSeries - 1) do
begin
if Nr = FSeriesIndex_for_SeriesNr[i]
then
NrNow := i;
end;
if NrNow = -1
then
NrNow := FNrOfSeries; //make new series
end;
if NrNow = FNrOfSeries
then
MakeNewSeries;
result := NrNow;
end; //end of GetSeriesNr
function TcollisionTester3DX.CheckForSeriesIndex(indexnow : integer): boolean;
var
i : integer;
begin
if FNrOfSeries = 0
then
result := false
else
begin
FSeriesNr := -1;
for i := 0 to (FNrOfSeries - 1) do
begin
if indexnow = FSeriesIndex_for_SeriesNr[i]
then
FSeriesNr := i;
end;
result := (FSeriesNr <> -1);
end;
end; //end of CheckForSeriesIndex
procedure TcollisionTester3DX.AddCollisionObject;
begin
FSeriesNr := GetSeriesNr(FSeriesIndex);
case Fshape3D of
box3D : AddBox;
sphere3D : AddSphere;
cylinder3D : AddCylinder;
ellipsoid3D: AddEllipsoid;
Conus3D : AddConus;
end;
end; //end of AddCollisionObject
function TCollisionTester3DX.DestroyCollisionObject: boolean;
var
test_nr : integer;
begin
//remove all collision objects connected with the 3D-object
//with the index FnextDestroyNr
//Check whether series index exists
if CheckForSeriesIndex(FSeriesIndex)
then
begin
//FSeriesNr was found
test_nr := 0;
while (test_nr <= (Fcoll_nr_objects[FSeriesNr] - 1)) do
begin
if Fcoll_objectnr[FSeriesNr, test_nr] = FnextDestroyNr
then
remove_collision_object(FSeriesNr, FnextDestroyNr)
else
inc(test_nr);
end; //end of while loop
//now we have to decrement all Fcoll_objectnr values larger than object_nr
//because the main program does a similar decrementation when the 3D-object
//is removed
if Fcoll_nr_objects[FSeriesNr] > 0
then
begin
//the series is not empty
for test_nr := 0 to (Fcoll_nr_objects[FSeriesNr] - 1) do
begin
if Fcoll_objectnr[FSeriesNr, test_nr] > FNextDestroyNr
then
dec(Fcoll_objectnr[FSeriesNr, test_nr]);
end;
end
else
destroy_empty_Series(FSeriesNr);
result := true; //collision object was destroyed
end //end of CheckForSeriesIndex...
else
result := false; //unable to destroy
end; //end of DestroyCollisionObject
function TcollisionTester3DX.coll_test_sphere(coll_nr : byte;
old_attacker_position, attacker_position : TD3DVector;
bullet_radius : TD3DValue; longshot : boolean): boolean;
var
new_eye, old_eye : TD3DVector;
dstep, step, center : TD3DVector;
radius, d0, d1, d2, rod, rod2, t1, t2 : TD3DValue;
begin
result := false;
//Get the coordinates of the old eye_position in the actual coll frame
FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform
(old_eye, old_attacker_position);
//Get the coordinates of the eye_position in the actual coll frame
FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform
(new_eye, attacker_position);
center.x := (Fcoll_box_max[FSeriesNr, coll_nr].x
+ Fcoll_box_min[FSeriesNr, coll_nr].x)/2;
center.y := (Fcoll_box_max[FSeriesNr, coll_nr].y
+ Fcoll_box_min[FSeriesNr, coll_nr].y)/2;
center.z := (Fcoll_box_max[FSeriesNr, coll_nr].z
+ Fcoll_box_min[FSeriesNr, coll_nr].z)/2;
//radius of sphere enlarged with the radius of the bullet
//to cover the space where a collision may occure
radius := Fcoll_radius[FSeriesNr, coll_nr] + bullet_radius;
//eye to center distance
dstep.x := old_eye.x - center.x;
dstep.y := old_eye.y - center.y;
dstep.z := old_eye.z - center.z;
//step in eye position
step.x := new_eye.x - old_eye.x;
step.y := new_eye.y - old_eye.y;
step.z := new_eye.z - old_eye.z;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -