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

📄 colli3dx.pas

📁 传奇源代码的delphi版本
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                                 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 + -