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

📄 model.pas

📁 3D火焰效果好程序好的很
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------
//
// Author      : Jan Horn
// Email       : jhorn@global.co.za
// Website     : http://home.global.co.za/~jhorn
// Date        : 7 October 2001
// Version     : 1.0
// Description : Quake 3 Model Loader (MD3 Loader) 
//
//------------------------------------------------------------------------
unit model;

interface

uses
  Windows, SysUtils, OpenGL, Textures;

type
  TMD3Header = Record
    ID : Array[1..4] of Char;               // id = IDP3
    Version       : Integer;                // Version = 15
    Filename      : Array[1..68] of Char;
    numBoneFrames : Integer;
    numTags       : Integer;
    numMeshes     : Integer;
    numMaxSkins   : Integer;
    headerLength  : Integer;
    TagStart      : Integer;
    TagEnd        : Integer;
    FileSize      : Integer;
  end;

  TBoneFrame = Record
    mins : Array[0..2] of glFloat;
    maxs : Array[0..2] of glFloat;
    Position : Array[0..2] of glFloat;
    Scale    : glFloat;
    Creator  : Array[1..16] of Char;
  end;

  TAnim = Record
    FirstFrame     : Integer;
    numFrames      : Integer;
    LoopingFrames  : Integer;
    FPS            : Integer;
  end;

  TRotationMatrix = Array[0..2, 0..2] of glFloat;
  TVector = Array[0..2] of glFloat;
  TTag = Record
    Name     : Array[1..64] of Char;
    Position : TVector;
    Rotation : TRotationMatrix;
  end;

  TTriangle = Record
    Vertex : Array[0..2] of Integer;
  end;

  TTexCoord = Record
    Coord : Array[0..1] of glFloat;
  end;

  TVertex = Record
    Vertex : Array[0..2] of Smallint;
    Normal : Array[0..1] of Byte;
  end;

  TMeshHeader = Record
    ID   : Array[1..4] of Char;
    Name : Array[1..68] of Char;
    numMeshFrames : Integer;
    numSkins     : Integer;
    numVertexes  : Integer;
    numTriangles : Integer;
    triStart     : Integer;
    headerSize   : Integer;
    TexVectorStart : Integer;
    VertexStart  : Integer;
    MeshSize     : Integer;
  end;

  TMesh = Record
    MeshHeader : TMeshHeader;
    Skins      : Array of Array[1..68] of Char;
    Triangle   : Array of TTriangle;
    TexCoord   : Array of TTexCoord;
    Vertex     : Array of TVertex;
    Texture    : glUint;
    SetTexture : Boolean;
  end;

  PMD3Model = ^TMD3Model;
  TMD3Model = object
    frame      : Integer;      // Current frame to draw
    startFrame : Integer;
    endFrame   : Integer;
    nextFrame  : Integer;      // Next frame to draw
    FPS        : Integer;
    Poll       : glFloat;      // Interpolation Time;
    LastUpdate : glFloat;      // last draw
    TexNr      : Integer;      // using for LoadSkin (*.skin)
    TexInf     : Array[0..99] of Integer;   // using for LoadSkin (*.skin)
    md3name    : String;
    Header     : TMD3header;
    BoneFrames : Array of TBoneFrame;
    Tags       : Array of TTag;
    Meshes     : Array of TMesh;
    Links      : Array of PMD3Model;
    procedure LoadModel(filename : String);
    procedure DrawModelInt(const currentFrame, nexFrame : Integer; const pol: Real);
    procedure DrawModel;
    procedure DrawSkeleton(var Mdl : TMD3Model);
    procedure UpdateFrame(time : glFLoat);
    procedure LinkModel(tagname : String; var MD3Model : TMD3Model);
    procedure LoadSkin(Imagepath, filename : String);
  end;

  Q3Player = Object
    Lower, Upper, Head : TMD3Model;
    anim : Array[0..25] of TAnim;
    animLower, animUpper : Integer;
    procedure LoadAnim(filename : String);
    procedure LoadPlayer(path, skin : String);
    procedure SetAnim(ani : Integer);
    procedure Draw(time : glFLoat);
  end;

const BOTH_DEATH1 = 0;
      BOTH_DEAD1  = 1;
      BOTH_DEATH2 = 2;
      BOTH_DEAD2  = 3;
      BOTH_DEATH3 = 4;
      BOTH_DEAD3  = 5;

      TORSO_GESTURE = 6;
      TORSO_ATTACK  = 7;
      TORSO_ATTACK2 = 8;
      TORSO_DROP    = 9;
      TORSO_RAISE   = 10;
      TORSO_STAND   = 11;
      TORSO_STAND2  = 12;

      LEGS_WALKCR   = 13;
      LEGS_WALK     = 14;
      LEGS_RUN      = 15;
      LEGS_BACK     = 16;
      LEGS_SWIM     = 17;
      LEGS_JUMP     = 18;
      LEGS_LAND     = 19;
      LEGS_JUMPB    = 20;
      LEGS_LANDB    = 21;
      LEGS_IDLE     = 22;
      LEGS_IDLECR   = 23;
      LEGS_TURN     = 24;

      MAX_ANIMATIONS = 25;


var anorms : Array[0..255, 0..255, 0..2] of Real;

function CharArrToStr(const C : Array of Char) : String;

implementation

procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;


function ArcTan2(Y, X: Extended): Extended;
asm
  FLD     Y
  FLD     X
  FPATAN
  FWAIT
end;

function ArcCos(X: Extended): Extended;
begin
  Result := ArcTan2(Sqrt(1 - X*X), X);
end;


{---------------------------------------------------------}
{--- Converts an array of characters to a string       ---}
{---------------------------------------------------------}
function CharArrToStr(const C : Array of Char) : String;
var I : Integer;
begin
  // convert the array of characters to a String
  I :=0;
  result :='';
  while C[i] <> #0 do
  begin
    result := result + C[I];
    Inc(I);
  end;
end;


{---------------------------------------------------------}
{--- Create a lookup table of normals. Faster this way ---}
{---------------------------------------------------------}
procedure InitNormals;
var I, J : Integer;
    alpha, beta : Real;
begin
  for I :=0 to 255 do
  begin
    for J :=0 to 255 do
    begin
      alpha :=2*I*pi/255;
      beta :=2*j*pi/255;
      anorms[i][j][0] := cos(beta) * sin(alpha);
      anorms[i][j][1] := sin(beta) * sin(alpha);
      anorms[i][j][2] := cos(alpha);
    end;
  end;
end;


{  TMD3Model  }

{---------------------------------------------------------}
{---  Draws a model                                    ---}
{---------------------------------------------------------}
procedure TMD3Model.DrawModel;
begin
  DrawModelInt(frame, nextframe, poll);
end;


{---------------------------------------------------------}
{---  Draw the model using interpolation               ---}
{---------------------------------------------------------}
procedure TMD3Model.DrawModelInt(const currentFrame, nexFrame : Integer; const pol: Real);
var i, j, k : Integer;
    triangleNum, currentMesh, currentOffsetVertex,
    currentVertex, nextCurrentOffsetVertex : Integer;
    normU, normV : Integer;
    s, t : glFloat;
    v, n : Array[0..2] of glFloat;
    nextV, nextN : Array[0..2] of glFloat;
begin
  For k :=0 to header.numMeshes-1 do
  begin
    currentMesh :=k;
    currentOffsetVertex :=currentFrame * meshes[currentMesh].MeshHeader.numVertexes;
    // interpolation
    nextCurrentOffsetVertex := nexFrame * meshes[currentMesh].MeshHeader.numVertexes;

    TriangleNum := Meshes[currentMesh].MeshHeader.numTriangles;

    if meshes[k].settexture then
      glBindTexture(GL_TEXTURE_2D, meshes[k].texture);
    for I :=0 to TriangleNum-1 do
    begin
      glBegin(GL_TRIANGLES);
      for J :=0 to 2 do
      begin
        currentVertex := Meshes[currentMesh].Triangle[i].vertex[j];

        v[0] :=meshes[currentMesh].vertex[currentOffsetVertex + currentVertex].Vertex[0] / 64;
        v[1] :=meshes[currentMesh].vertex[currentOffsetVertex + currentVertex].Vertex[1] / 64;
        v[2] :=meshes[currentMesh].vertex[currentOffsetVertex + currentVertex].Vertex[2] / 64;

        nextv[0] :=meshes[currentMesh].vertex[nextCurrentOffsetVertex + currentVertex].Vertex[0] / 64;
        nextv[1] :=meshes[currentMesh].vertex[nextCurrentOffsetVertex + currentVertex].Vertex[1] / 64;
        nextv[2] :=meshes[currentMesh].vertex[nextCurrentOffsetVertex + currentVertex].Vertex[2] / 64;

	normU := meshes[currentMesh].vertex[currentOffsetVertex + currentVertex].Normal[0];
	normV := meshes[currentMesh].vertex[currentOffsetVertex + currentVertex].Normal[1];

	n[0] :=aNorms[normU, normV, 0];
	n[1] :=aNorms[normU, normV, 1];
	n[2] :=aNorms[normU, normV, 2];

        // interpolated U, V and N
        normU := meshes[currentMesh].vertex[nextCurrentOffsetVertex + currentVertex].Normal[0];
        normV := meshes[currentMesh].vertex[nextCurrentOffsetVertex + currentVertex].Normal[1];

        nextN[0] := anorms[normU, normV, 0];
        nextN[1] := anorms[normU, normV, 1];
        nextN[2] := anorms[normU, normV, 2];

	s :=meshes[currentMesh].TexCoord[currentVertex].Coord[0];
	t :=meshes[currentMesh].TexCoord[currentVertex].Coord[1];

	glTexCoord2f(s, 1-t);

        // interpolation
        glNormal3f(n[0] + pol * (nextN[0] - n[0]), n[1] + pol * (nextN[1] - n[1]), n[2] + pol * (nextN[2] - n[2]));
        glVertex3f(v[0] + pol * (nextV[0] - v[0]), v[1] + pol * (nextV[1] - v[1]), v[2] + pol * (nextV[2] - v[2]));
      end;
      glEnd;
    end;
  end;
end;


{---------------------------------------------------------}
{--- Links a model to a tag. (head is linked to torso) ---}
{---------------------------------------------------------}
procedure TMD3Model.LinkModel(tagname: String; var MD3Model: TMD3Model);
var I : Integer;
begin
  for I :=0 to Header.numTags-1 do
  begin
    if CharArrToStr(tags[i].Name) = tagname then
    begin
      Links[i] :=@MD3Model;
      exit;
    end;
  end;
end;


{---------------------------------------------------------}
{---  Loads a model from a .MDL files                  ---}
{---  Result 1 = OK, -1 = no file, -2 = Bad header     ---}
{---------------------------------------------------------}
procedure TMD3Model.LoadModel(filename: String);
var F : File;
    I : Integer;
    MeshOffset : Integer;
begin
  if FileExists(filename) = FALSE then
    exit;

⌨️ 快捷键说明

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