?? model.pas
字號:
//------------------------------------------------------------------------
//
// 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 + -