📄 r_model.pas
字号:
for i := 0 to mod_numknown - 1 do
begin
if _mod^.name[0] = #0 then
begin
inc(Integer(_mod), SizeOf(model_t));
continue;
end;
ri.Con_Printf(PRINT_ALL, '%d : %s', _mod.extradatasize, _mod.name);
total := total + _mod^.extradatasize;
inc(Integer(_mod), SizeOf(model_t));
end; {next i};
ri.Con_Printf(PRINT_ALL, 'Total resident: %d', total);
end {procedure};
(*
===============
Mod_Init
===============
*)
procedure Mod_Init;
begin
FillChar(mod_novis, sizeof(mod_novis), $FF);
end;
// CAK
function PCharToInt(s: PChar): Integer;
var
s2: string;
begin
s2 := s;
try
Result := StrToInt(s2);
except
Result := -1;
end {try};
end;
(*
==================
Mod_ForName
Loads in a model for the given name
==================
*)
function Mod_ForName(name: PChar; crash: qboolean): model_p;
var
_mod: model_p;
buf: Pointer;
i: Integer;
begin
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
i := PCharToInt(PChar(@name[1]));
if (i < 1) or (r_worldmodel = nil) or (i >= r_worldmodel^.numsubmodels) then
ri.Sys_Error(ERR_DROP, 'bad inline model number');
Result := @mod_inline[i];
Exit;
end;
//
// search the currently loaded models
//
_mod := @mod_known[0];
for i := 0 to mod_numknown - 1 do
begin
if strcomp(PChar(@_mod^.name), name) = 0 then
begin
Result := _mod;
Exit;
end;
_mod := @mod_known[i];
end;
//
// find a free model slot spot
//
_mod := nil;
for i := 0 to mod_numknown - 1 do
begin
if mod_known[i].name[0] = #0 then
begin
_mod := @mod_known[i];
break; // free spot
end;
end;
if (_mod = nil) then
begin // no free spot found
if mod_numknown = MAX_MOD_KNOWN then
ri.Sys_Error(ERR_DROP, 'mod_numknown == MAX_MOD_KNOWN');
inc(mod_numknown);
_mod := @mod_known[mod_numknown - 1];
end;
strcopy(PChar(@_mod^.name[0]), name);
//
// load the file
//
modfilelen := ri.FS_LoadFile(PChar(@_mod^.name), @buf);
if buf = nil then
begin
if crash then
ri.Sys_Error(ERR_DROP, PChar('Mod_NumForName: ' + string(_mod.name) + ' not found'));
FillChar(_mod^.name[0], sizeof(_mod^.name), 0);
Result := nil;
Exit;
end;
loadmodel := _mod;
//
// fill it in
//
// call the apropriate loader
case LittleLong(PInteger(buf)^) of
IDALIASHEADER:
begin
loadmodel^.extradata := Hunk_Begin($200000);
Mod_LoadAliasModel(_mod, buf);
end;
IDSPRITEHEADER:
begin
loadmodel^.extradata := Hunk_Begin($10000);
Mod_LoadSpriteModel(_mod, buf);
end;
IDBSPHEADER:
begin
loadmodel^.extradata := Hunk_Begin($1000000);
Mod_LoadBrushModel(_mod, buf);
end;
else
begin
ri.Sys_Error(ERR_DROP, PChar('Mod_NumForName: unknown fileid for ' + string(_mod^.name)));
end;
end;
loadmodel^.extradatasize := Hunk_End;
ri.FS_FreeFile(buf);
Result := _mod;
end;
(*
===============
Mod_PointInLeaf
===============
*)
function Mod_PointInLeaf(const p: vec3_t; model: model_p): mleaf_p;
var
node: mnode_p;
d: Single;
plane: mplane_p;
begin
if (model = nil) or (model^.nodes = nil) then
ri.Sys_Error(ERR_DROP, 'Mod_PointInLeaf: bad model');
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.0 then
node := node^.children[0]
else
node := node^.children[1];
end;
Result := nil; // never reached
end;
(*
===================
Mod_DecompressVis
===================
*)
var
decompressed: array[0..(MAX_MAP_LEAFS div 8) - 1] of Byte;
function Mod_DecompressVis(_in: PByte; model: model_p): PByte;
var
c: Integer;
_out: PByte;
row: Integer;
begin
row := (model^.vis^.numclusters + 7) shr 3;
_out := @decompressed[0];
(*
move(in^,out^,row);
*)
if _in = nil then
begin // no vis info, so make all visible
while row <> 0 do
begin
_out^ := $FF;
inc(Integer(_out), 1);
dec(row, 1);
end;
Result := @decompressed[0];
exit;
end;
repeat
if (_in^ <> 0) then
begin
_out^ := _in^;
inc(Integer(_out), 1);
inc(Integer(_in), 1);
end
else
begin
c := PByteArray(_in)^[1];
inc(Integer(_in), 2);
while (c > 0) do
begin
_out^ := 0;
inc(Integer(_out), 1);
dec(c);
end;
end;
until (Integer(_out) - Integer(@decompressed[0])) >= row;
Result := @decompressed[0];
end;
(*
==============
Mod_ClusterPVS
==============
*)
function Mod_ClusterPVS(cluster: integer; model: model_p): PByte;
begin
if (cluster = -1) or (model^.vis = nil) then
begin
Result := @mod_novis[0];
exit;
end {if};
Result := Mod_DecompressVis(PByte(Integer(model^.vis) + model^.vis^.bitofs[cluster][DVIS_PVS]), model);
end {function};
(*
===============================================================================
BRUSHMODEL LOADING
===============================================================================
*)
var
mod_base: PByte;
(*
=================
Mod_LoadLighting
Converts the 24 bit lighting down to 8 bit
by taking the brightest component
=================
*)
procedure Mod_LoadLighting(l: lump_p);
var
i, size: Integer;
_in: PByte;
_out: PByte;
begin
if l^.filelen = 0 then
begin
loadmodel^.lightdata := nil;
exit;
end;
size := Trunc(l^.filelen / 3);
loadmodel^.lightdata := Hunk_Alloc(size);
_in := Pointer(Integer(mod_base) + l^.fileofs);
_out := loadmodel^.lightdata;
for i := 0 to size - 1 do
begin
if (PByteArray(_in)^[0] > PByteArray(_in)^[1]) and (PByteArray(_in)^[0] > PByteArray(_in)^[2]) then
_out^ := PByteArray(_in)^[0]
else
begin
if (PByteArray(_in)^[1] > PByteArray(_in)^[0]) and (PByteArray(_in)^[1] > PByteArray(_in)^[2]) then
_out^ := PByteArray(_in)^[1]
else
_out^ := PByteArray(_in)^[2];
end;
inc(Integer(_in), 3);
inc(Integer(_out));
end;
end;
var
r_leaftovis: array[0..MAX_MAP_LEAFS - 1] of Integer;
r_vistoleaf: array[0..MAX_MAP_LEAFS - 1] of Integer;
r_numvisleafs: Integer;
procedure R_NumberLeafs(node: mnode_p);
var
leaf: mleaf_p;
leafnum: Integer;
begin
if node^.contents <> -1 then
begin
leaf := mleaf_p(node);
leafnum := (Integer(leaf) - Integer(loadmodel^.leafs)) div SizeOf(mleaf_t);
if (leaf^.contents and CONTENTS_SOLID) <> 0 then
Exit;
r_leaftovis[leafnum] := r_numvisleafs;
r_vistoleaf[r_numvisleafs] := leafnum;
inc(r_numvisleafs);
exit;
end;
R_NumberLeafs(node^.children[0]);
R_NumberLeafs(node^.children[1]);
end;
(*
=================
Mod_LoadVisibility
=================
*)
procedure Mod_LoadVisibility(l: lump_p);
var
i: Integer;
begin
if (l^.filelen = 0) then
begin
loadmodel^.vis := nil;
Exit;
end;
loadmodel^.vis := Hunk_Alloc(l^.filelen);
move(Pointer(Integer(mod_base) + l^.fileofs)^, loadmodel^.vis^, 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
_in := Pointer(Integer(mod_base) + l^.fileofs);
if (l^.filelen mod SizeOf(_in^)) <> 0 then
ri.Sys_Error(ERR_DROP, PChar('MOD_LoadBmodel: funny lump size in ' + string(loadmodel^.name)));
count := Trunc(l^.filelen / SizeOf(_in^));
_out := Hunk_Alloc((count + 8) * sizeof(_out^)); // extra for skybox
loadmodel^.vertexes := _out;
loadmodel^.numvertexes := count;
for i := 0 to count - 1 do
begin
_out^.position[0] := LittleFloat(_in^.point[0]);
_out^.position[1] := LittleFloat(_in^.point[1]);
_out^.position[2] := LittleFloat(_in^.point[2]);
inc(Integer(_in), SizeOf(_in^));
inc(Integer(_out), SizeOf(_out^));
end;
end;
(*
=================
Mod_LoadSubmodels
=================
*)
procedure Mod_LoadSubmodels(l: lump_p);
var
_in, _out: dmodel_p;
i, j, count: Integer;
begin
_in := Pointer(Integer(mod_base) + l^.fileofs);
if (l^.filelen mod SizeOf(_in^)) <> 0 then
ri.Sys_Error(ERR_DROP, PChar('MOD_LoadBmodel: funny lump size in ' + string(loadmodel^.name)));
count := Trunc(l^.filelen / SizeOf(_in^));
_out := Hunk_Alloc(count * sizeof(_out^));
loadmodel^.submodels := _out;
loadmodel^.numsubmodels := count;
for i := 0 to count - 1 do
begin
for j := 0 to 2 do
begin // spread the mins / maxs by a pixel
_out^.mins[j] := LittleFloat(_in^.mins[j]) - 1;
_out^.maxs[j] := LittleFloat(_in^.maxs[j]) + 1;
_out^.origin[j] := LittleFloat(_in^.origin[j]);
end;
_out^.headnode := LittleLong(_in^.headnode);
_out^.firstface := LittleLong(_in^.firstface);
_out^.numfaces := LittleLong(_in^.numfaces);
inc(Integer(_in), SizeOf(_in^));
inc(Integer(_out), SizeOf(_out^));
end;
end;
(*
=================
Mod_LoadEdges
=================
*)
procedure Mod_LoadEdges(l: lump_p);
var
_in: dedge_p;
_out: medge_p;
i: Integer;
count: Integer;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -