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

📄 model.pas

📁 3D火焰效果好程序好的很
💻 PAS
📖 第 1 页 / 共 2 页
字号:

  AssignFile(F, filename);
  Reset(F,1);

  // copy name
  MD3Name :=Filename;

  // read header
  BlockRead(F, Header, Sizeof(Header));
  if (Uppercase(Header.ID) <> 'IDP3') OR (Header.Version <> 15) then
  begin
    CloseFile(F);
    exit;
  end;

  // read boneframes
  SetLength(BoneFrames, Header.numBoneFrames);
  BlockRead(F, BoneFrames[0], Header.numBoneFrames*sizeof(TBoneFrame));

  // read tags
  SetLength(Tags, Header.numBoneFrames * Header.numTags);
  BlockRead(F, Tags[0], Header.numBoneFrames*Header.numTags*sizeof(TTag));

  // init links
  SetLength(Links, Header.numTags);
  for I :=0 to Header.NumTags-1 do
    Links[I] :=nil;

  // read meshes
  SetLength(Meshes, Header.numMeshes);
  MeshOffset := FilePos(F);

  For I :=0 to Header.numMeshes-1 do
  begin
    Seek(F, MeshOffset);
    BlockRead(F, Meshes[I].MeshHeader, sizeOf(TMeshHeader));

    // Load the Skins
    SetLength(Meshes[I].Skins, Meshes[I].MeshHeader.numSkins);
    BlockRead(F, Meshes[I].Skins[0], 68 * Meshes[I].MeshHeader.numSkins);

    // Triangles
    Seek(F, MeshOffset + Meshes[I].MeshHeader.triStart);
    SetLength(Meshes[I].Triangle, Meshes[I].MeshHeader.numTriangles);
    BlockRead(F, Meshes[I].Triangle[0], sizeOf(TTriangle)*Meshes[I].MeshHeader.numTriangles);

    // Texture Coordiantes
    Seek(F, MeshOffset + Meshes[I].MeshHeader.TexVectorStart);
    SetLength(Meshes[I].TexCoord, Meshes[I].MeshHeader.numVertexes);
    BlockRead(F, Meshes[I].TexCoord[0], sizeOf(TTexCoord)*Meshes[I].MeshHeader.numVertexes);

    // Vertices
    Seek(F, MeshOffset + Meshes[I].MeshHeader.VertexStart);
    SetLength(Meshes[I].Vertex, Meshes[I].MeshHeader.numVertexes * Meshes[I].MeshHeader.numMeshFrames);
    BlockRead(F, Meshes[I].Vertex[0], sizeOf(TVertex)*Meshes[I].MeshHeader.numVertexes * Meshes[I].MeshHeader.numMeshFrames);

    MeshOffset :=MeshOffset + Meshes[I].MeshHeader.MeshSize;
  end;

  CloseFile(F);

  // set the start, end frame
  Header.numBoneFrames :=Header.numBoneFrames - 1;
  startFrame := 0;
  endFrame := Header.numBoneFrames;
end;


{-------------------------------------------------------------}
{--- Draws the model and other models linked to this model ---}
{-------------------------------------------------------------}
procedure TMD3Model.DrawSkeleton(var Mdl : TMD3Model);
var I    : Integer;
    pMdl : PMD3Model;
    m    : Array[0..15] of glFloat;
    Rotation : TRotationMatrix;
    Position : TVector;
begin
  Mdl.DrawModel;
  for I :=0 to Mdl.Header.numTags-1 do
  begin
    pMdl :=Mdl.Links[i];
    if pMdl <> nil then
    begin
      Position :=Mdl.tags[Mdl.frame * Mdl.Header.numTags + i].Position;
      Rotation :=Mdl.Tags[Mdl.Frame * Mdl.Header.numTags + i].Rotation;

      m[0] := Rotation[0, 0];
      m[1] := Rotation[0, 1];
      m[2] := Rotation[0, 2];
      m[3] := 0;
      m[4] := Rotation[1, 0];
      m[5] := Rotation[1, 1];
      m[6] := Rotation[1, 2];
      m[7] := 0;
      m[8] := Rotation[2, 0];
      m[9] := Rotation[2, 1];
      m[10]:= Rotation[2, 2];
      m[11]:= 0;
      m[12] := position[0];
      m[13] := position[1];
      m[14] := position[2];
      m[15] := 1;

      glPushMatrix();
      glMultMatrixf(@m);
      DrawSkeleton(pMdl^);
      glPopMatrix();
    end;
  end;
end;


{---------------------------------------------------------}
{--- Loads the skins for the model from the .skin file ---}
{---------------------------------------------------------}
procedure TMD3Model.LoadSkin(Imagepath, filename : String);
var F : TextFile;
    I : Integer;
    S : String;
    MeshName, ImageName : String;
begin
  if FileExists(Imagepath + filename) then
  begin
    AssignFile(F,Imagepath + filename);
    Reset(F);
    while EOF(F) = FALSE do
    begin
      Readln(F, S);
      if Length(S) > 1 then
      begin
        if Pos(',', S)+1 < Length(S) then   // there must be something after the comma
        begin
          MeshName :=Copy(S, 1, Pos(',', S)-1);
          if Copy(MeshName, 1, 4) <> 'tag_' then   // tags dont have skins
          begin
            ImageName :=Copy(S, Pos(',', S)+1, Length(S));     // get the full image and path name
            ImageName :=StrRScan(PChar(S), '/');               // get name from last / (i.e only filename)
            ImageName :=Copy(ImageName, 2, Length(ImageName)); // lose the starting /

            // if its a TGA or JPG, then load the skin
            if (pos('.JPG', UpperCase(ImageName)) > 0) OR (pos('.TGA', UpperCase(ImageName)) > 0) then
            begin
              // Find the right mesh item to assign the skin to
              for I :=0 to header.numMeshes-1 do
              begin
                // check it the two names are the same
                if UpperCase(CharArrToStr(meshes[i].MeshHeader.Name)) = Uppercase(meshname) then
                begin
                  LoadTexture(ImagePath + ImageName, meshes[i].Texture, FALSE);
                  meshes[i].SetTexture :=TRUE;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
    CloseFile(F);
  end;
end;


{---------------------------------------------------------}
{---  Updates the active frame for the model           ---}
{---------------------------------------------------------}
procedure TMD3Model.UpdateFrame(Time : glFLoat);
begin
  Poll :=(Time - LastUpdate);
  if Poll > 1/FPS then
  begin
    frame :=NextFrame;
    Inc(NextFrame);
    if NextFrame > EndFrame then
       NextFrame :=StartFrame;
    LastUpdate :=Time;
  end;
end;


{---  Q3Player  ---}


{---------------------------------------------------------}
{---  Draws the models associated with the Players     ---}
{---------------------------------------------------------}
procedure Q3Player.Draw(time : glFLoat);
begin
  Lower.UpdateFrame(time);
  Upper.UpdateFrame(time);
  Head.UpdateFrame(time);

  Lower.DrawSkeleton(Lower);
end;


{---------------------------------------------------------}
{---  Loads animation for the player. (animation.cfg)  ---}
{---------------------------------------------------------}
procedure Q3Player.LoadAnim(filename: String);
var F : Text;
    S : String;
    I, P, skip : Integer;
begin
  if FileExists(filename) = FALSE then
    exit;

  AssignFile(F, filename);
  Reset(F);

  I :=0;
  while EOF(F) = false do
  begin
    Readln(F, S);
    if Pos('sex', S) > 0 then
    else if Pos('headoffset', S) > 0 then
    else if Pos('footsteps', S) > 0 then
    else if (S <> '') AND (Pos('//', S) > 5) then
    begin
      // Extract the values of FirstFrame, numFrames, LoopingFrames, FPS from the String
      P :=Pos(#9, S);
      Anim[i].FirstFrame :=StrToInt(Copy(S, 1, P-1));
      S :=Copy(S, P+1, Length(S));

      P :=Pos(#9, S);
      Anim[i].numFrames :=StrToInt(Copy(S, 1, P-1));
      S :=Copy(S, P+1, Length(S));

      P :=Pos(#9, S);
      Anim[i].loopingFrames :=StrToInt(Copy(S, 1, P-1));
      S :=Copy(S, P+1, Length(S));

      P :=Pos(#9, S);
      if P < 0 then P :=Length(S)+1;
      Anim[i].FPS :=StrToInt(Copy(S, 1, P-1));

      Inc(I);
    end;
  end;
  CloseFile(F);

  skip := anim[LEGS_WALKCR].firstFrame - anim[TORSO_GESTURE].firstFrame;
  for I :=LEGS_WALKCR to MAX_ANIMATIONS do
    Anim[I].firstFrame := Anim[I].firstFrame - skip;

  for I :=0 to MAX_ANIMATIONS do
    if Anim[I].numFrames > 0 then
      Anim[I].numFrames :=Anim[I].numFrames - 1;

end;


{---------------------------------------------------------}
{---  Sets the new animation sequence for the player   ---}
{---------------------------------------------------------}
procedure Q3Player.SetAnim(ani : Integer);
begin
  if ani in [0..5] then
  begin
    Lower.FPS :=anim[ani].FPS;
    Upper.FPS :=anim[ani].FPS;

    Lower.StartFrame :=anim[ani].FirstFrame;
    Upper.StartFrame :=anim[ani].FirstFrame;

    Lower.EndFrame :=anim[ani].FirstFrame + anim[ani].numFrames;
    Upper.EndFrame :=anim[ani].FirstFrame + anim[ani].numFrames;

    animLower :=ani;
    animUpper :=ani;
  end
  else if ani in [6..12] then
  begin
    Upper.FPS :=anim[ani].FPS;
    Upper.NextFrame :=anim[ani].FirstFrame;
    Upper.StartFrame :=anim[ani].FirstFrame;
    Upper.EndFrame :=anim[ani].FirstFrame + anim[ani].numFrames;

    animUpper :=ani;
  end
  else if ani in [13..24] then
  begin
    Lower.FPS :=anim[ani].FPS;
    Lower.NextFrame :=anim[ani].FirstFrame;
    Lower.StartFrame :=anim[ani].FirstFrame;
    Lower.EndFrame :=anim[ani].FirstFrame + anim[ani].numFrames;

    animLower :=ani;
  end
end;


{---------------------------------------------------------}
{---  Loads a player model, skin and snimations        ---}
{---------------------------------------------------------}
procedure Q3Player.LoadPlayer(path, skin: String);
begin
  // Pre-calculate the normals
  if aNorms[0,0,2] <> 1 then
    InitNormals;

  Lower.LoadModel(path + 'lower.md3');
  Upper.LoadModel(path + 'upper.md3');
  Head.LoadModel(path + 'head.md3');

  Lower.LoadSkin(path, 'lower_' + skin + '.skin');
  Upper.LoadSkin(path, 'upper_' + skin + '.skin');
  Head.LoadSkin(path, 'head_' + skin + '.skin');

  LoadAnim(path + 'animation.cfg');

  Lower.startframe :=0;    Lower.EndFrame :=0;
  Upper.startframe :=0;    Upper.EndFrame :=0;
  Head.startframe  :=0;    Head.EndFrame  :=0;

  SetAnim(TORSO_STAND);
  SetAnim(LEGS_WALK);

  Lower.LinkModel('tag_torso', Upper);
  Upper.LinkModel('tag_head', Head);
end;


end.


⌨️ 快捷键说明

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