📄 gl_model.pas
字号:
// PLEASE, don't modify this file
// 70% complete
{----------------------------------------------------------------------------}
{ }
{ File(s): gl_model.c - model loading and caching }
{ }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru }
{ Initial conversion on : 03-Apr-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ Copyright (C) 1997-2001 Id Software, Inc. }
{ }
{ This program is free software; you can redistribute it and/or }
{ modify it under the terms of the GNU General Public License }
{ as published by the Free Software Foundation; either version 2 }
{ of the License, or (at your option) any later version. }
{ }
{ This program is distributed in the hope that it will be useful, }
{ but WITHOUT ANY WARRANTY; without even the implied warranty of }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. }
{ }
{ See the GNU General Public License for more details. }
{ }
{----------------------------------------------------------------------------}
{ Updated on : }
{ Updated by : }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ 1) xxx }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) Do more tests }
{ }
{----------------------------------------------------------------------------}
// models.c -- model loading and caching
unit gl_model;
interface
uses q_shared, gl_local, gl_model_h, ref;
//...
function Mod_PointInLeaf (p : vec3_t; model : model_p) : mleaf_p; //for gl_rmain
function Mod_ClusterPVS (cluster : integer; model : model_p) : PByte; //for gl_rsurf
procedure Mod_Modellist_f; //for gl_rmain
procedure Mod_Init; //for gl_rmain
procedure R_BeginRegistration (model : PChar); cdecl; //for gl_rmain
function R_RegisterModel (name : PChar) : model_p; cdecl; //for gl_rmain
procedure R_EndRegistration; cdecl; //gl_rmain
procedure Mod_FreeAll; //for gl_rmain
implementation
uses qfiles, gl_image, gl_warp, gl_rsurf;
procedure Mod_Free (_mod : model_p); forward;
var
loadmodel : model_p;
modfilelen : integer;
(*
void Mod_LoadSpriteModel (model_t *mod, void *buffer);
void Mod_LoadBrushModel (model_t *mod, void *buffer);
void Mod_LoadAliasModel (model_t *mod, void *buffer);
model_t *Mod_LoadModel (model_t *mod, qboolean crash);*)
procedure Mod_LoadBrushModel (_mod : model_p; buffer : pointer); forward;
procedure Mod_LoadAliasModel (_mod : model_p; buffer : pointer); forward;
procedure Mod_LoadSpriteModel (_mod : model_p; buffer : pointer); forward;
var
mod_novis : array [0..MAX_MAP_LEAFS div 8 -1] of byte;
const
MAX_MOD_KNOWN = 512;
var
mod_known : array [0..MAX_MOD_KNOWN-1] of model_t;
mod_numknown : integer;
var
// the inline * models from the current map are kept seperate
mod_inline : array [0..MAX_MOD_KNOWN-1] of model_t;
(*int registration_sequence;*)
{*
===============
Mod_PointInLeaf
===============
*}
function Mod_PointInLeaf (p : vec3_t; model : model_p) : mleaf_p; //for gl_rmain
var
node : mnode_p;
d : float;
plane : cplane_p;
begin
//Y if (!model || !model->nodes) then
ri.Sys_Error (ERR_DROP, 'Mod_PointInLeaf: bad model', []);
//Y node := model.nodes;
while (True) do
begin
if (node.contents <> -1) then
begin
Result := mleaf_p(node);
Exit;
end;
plane := node.plane;
d := DotProduct (p, plane.normal) - plane.dist;
if (d > 0)
then node := node.children[0]
else node := node.children[1];
end;
Result := Nil; // never reached
end;
{*
===================
Mod_DecompressVis
===================
*}
function Mod_DecompressVis (_in : PByte; model : model_p) : PByte;
(*var
static byte decompressed[MAX_MAP_LEAFS/8];
int c;
byte *out;
int row;*)
begin
(* row = (model->vis->numclusters+7)>>3;
out = decompressed;
if (!in) then
begin
// no vis info, so make all visible
while (row)
{
*out++ = 0xff;
row--;
}
return decompressed;
end;
do
{
if (*in) then
begin
*out++ = *in++;
continue;
end;
c = in[1];
in += 2;
while (c)
{
*out++ = 0;
c--;
}
} while (out - decompressed < row);
Result := decompressed;*)
end;
{*
==============
Mod_ClusterPVS
==============
*}
function Mod_ClusterPVS (cluster : integer; model : model_p) : PByte;
begin
if (cluster = -1) {OR (!model->vis)} then
begin
Result := @mod_novis;
Exit;
end;
//Y Result := Mod_DecompressVis ( (byte * )model->vis + model->vis->bitofs[cluster][DVIS_PVS], model);
end;
{*
================
Mod_Modellist_f
================
*}
procedure Mod_Modellist_f; //for gl_rmain
var
i, total : integer;
_mod : model_p;
begin
total := 0;
ri.Con_Printf (PRINT_ALL, 'Loaded models:\n', []);
//Y for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
begin
(*Y if (!mod->name[0]) then
Continue;*)
ri.Con_Printf (PRINT_ALL, '%8i : %s\n', [_mod.extradatasize, _mod.name]);
Inc (total, _mod.extradatasize);
end;
ri.Con_Printf (PRINT_ALL, 'Total resident: %i\n', [total]);
end;
{*
===============
Mod_Init
===============
*}
procedure Mod_Init; //for gl_rmain
begin
// memset (mod_novis, 0xff, sizeof(mod_novis));
end;
{*
==================
Mod_ForName
Loads in a model for the given name
==================
*}
function Mod_ForName (name : PChar; crash : qboolean) : model_p;
var
_mod : model_p;
// unsigned *buf;
buf : pointer;
i : integer;
begin
//Y if (!name[0]) then
ri.Sys_Error (ERR_DROP, 'Mod_ForName: NULL name', []);
//
// inline models are grabbed only from worldmodel
//
if (name[0] = '*') then
begin
(*Y i := atoi(name+1);
if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels) then*)
ri.Sys_Error (ERR_DROP, 'bad inline model number', []);
Result := @mod_inline[i];
end;
(*Y //
// search the currently loaded models
//
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
{
if (!mod->name[0])
continue;
if (!strcmp (mod->name, name) )
return mod;
}
//
// find a free model slot spot
//
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
{
if (!mod->name[0])
break; // free spot
}
if (i == mod_numknown)
{
if (mod_numknown == MAX_MOD_KNOWN)
ri.Sys_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
mod_numknown++;
}
strcpy (mod->name, name);
//
// load the file
//
modfilelen := ri.FS_LoadFile (_mod.name, &buf);
if (!buf)
{
if (crash)
ri.Sys_Error (ERR_DROP, "Mod_NumForName: %s not found", mod->name);
memset (mod->name, 0, sizeof(mod->name));
return NULL;
}*)
loadmodel := _mod;
//
// fill it in
//
// call the apropriate loader
// switch (LittleLong(*(unsigned * )buf))
Case integer(buf) of
IDALIASHEADER: begin
//Y loadmodel.extradata := Hunk_Begin (0x200000);
Mod_LoadAliasModel (_mod, buf);
end;
IDSPRITEHEADER: begin
//Y loadmodel.extradata := Hunk_Begin (0x10000);
Mod_LoadSpriteModel (_mod, buf);
end;
IDBSPHEADER: begin
//Y loadmodel->extradata = Hunk_Begin (0x1000000);
Mod_LoadBrushModel (_mod, buf);
end;
else
ri.Sys_Error (ERR_DROP, 'Mod_NumForName: unknown fileid for %s', [_mod.name]);
end;//case
//Y loadmodel.extradatasize := Hunk_End ();
ri.FS_FreeFile (buf);
Result := _mod;
end;
{*
===============================================================================
BRUSHMODEL LOADING
===============================================================================
*}
var
mod_base : PByte;
{*
=================
Mod_LoadLighting
=================
*}
procedure Mod_LoadLighting (l : lump_p);
begin
if (l.filelen=0) then
begin
loadmodel.lightdata := Nil;
Exit;
end;
(*Y loadmodel.lightdata := Hunk_Alloc ( l->filelen);
memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);*)
end;
{*
=================
Mod_LoadVisibility
=================
*}
procedure Mod_LoadVisibility (l : lump_p);
var
i : integer;
begin
if (l.filelen=0) then
begin
loadmodel.vis := {Nil}0;
Exit;
end;
(*Y loadmodel.vis = Hunk_Alloc ( l->filelen);
memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
loadmodel.vis.numclusters = LittleLong (loadmodel->vis->numclusters);
for i:=0 to loadmodel.vis.numclusters-1 do
begin
loadmodel.vis.bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);
loadmodel.vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);
end;*)
end;
{*
=================
Mod_LoadVertexes
=================
*}
procedure Mod_LoadVertexes (l : lump_p);
var
_in : dvertex_p;
_out : mvertex_p;
i,
count : integer;
begin
//Y _in := (void * )(mod_base + l->fileofs);
// if (l->filelen % sizeof(*in))
if (l.filelen MOD sizeof(_in^)) <> 0 then
ri.Sys_Error (ERR_DROP, 'MOD_LoadBmodel: funny lump size in %s', [loadmodel.name]);
count := l.filelen DIV sizeof(_in^);
(*Y _out := Hunk_Alloc ( count*sizeof( *out));
loadmodel.vertexes := _out;*)
loadmodel.numvertexes := count;
//Y for ( i=0 ; i<count ; i++, in++, out++)
begin
_out.position[0] := LittleFloat (_in.point[0]);
_out.position[1] := LittleFloat (_in.point[1]);
_out.position[2] := LittleFloat (_in.point[2]);
end;
end;
{*
=================
RadiusFromBounds
=================
*}
function RadiusFromBounds (mins, maxs : vec3_t) : float;
var
i : integer;
corner : vec3_t;
begin
for i:=0 to 2 do
// corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
if fabs(mins[i]) > fabs(maxs[i])
then corner[i] := fabs(mins[i])
else corner[i] := fabs(maxs[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -