📄 r_alias_c.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): r_alias_c.c }
{ }
{ Initial conversion by : Diogo Teixeira - fozi_b@yahoo.com }
{ Initial conversion on : 20-Jan-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: }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{ proofread: missing. }
{ }
{----------------------------------------------------------------------------}
(*
- Initial translation by Diogo Teixeira (20/01/2002)
NOTES:
.some pointer types are named ptype_t, others type_p and some
^type_t, this is because they were different in the files i
used from the delphi source and some weren't present at all.
(this should have been discussed earlier)
.i added a "// TRANSLATOR'S NOTE:" in every critical point in
the translation, any "missing ->" points to a variable that
is declared in some other file and should be linked here.
.ALL_SET switch makes this compile using all the code
that is hidden because of "missing ->".
.ASM_CODE switch enables assembly code, i did not translate
this part since it is not needed and we didn't discussed
this previously, so the "pure c" version was translated instead.
- Finished Initial translation in 24/01/2002
- For any discussion about this delphi translation mail: fozi_b@yahoo.com
*)
unit r_alias_c;
interface
uses
windows,
qfiles,
q_shared,
r_local,
r_bsp_c,
r_model;
type // TRANSLATOR'S NOTE: added to simplify translation
tmatrix3x4 = array[0..2, 0..3] of single;
procedure R_AliasSetUpLerpData(pmdl : dmdl_p; backlerp : single);
procedure R_AliasSetUpTransform;
procedure R_AliasTransformVector(in_ : vec3_t; var out_ : vec3_t; xf : matrix34);
//procedure R_AliasTransformVector(in_, out_ : vec3_t; xf : tmatrix3x4);
procedure R_AliasProjectAndClipTestFinalVert(fv: finalvert_p);
procedure R_AliasTransformFinalVerts(numpoints: integer; fv: finalvert_p; oldv: dtrivertx_p; newv: dtrivertx_p);
function R_AliasCheckFrameBBox(frame : daliasframe_p; worldxf : matrix34) : cardinal;
function R_AliasCheckBBox : qboolean;
procedure R_AliasPreparePoints;
procedure R_AliasSetupLighting;
procedure R_AliasSetupFrames(pmdl: dmdl_p);
procedure R_AliasDrawModel;
// TRANSLATOR'S NOTE: defined but not used???
//procedure R_AliasLerpFrames(paliashdr : dmdl_p; backlerp : single);
const
BBOX_TRIVIAL_ACCEPT = 0;
BBOX_MUST_CLIP_XY = 1;
BBOX_MUST_CLIP_Z = 2;
BBOX_TRIVIAL_REJECT = 8;
var
r_affinetridesc: affinetridesc_t;
r_aliasblendcolor: integer;
r_amodels_drawn: integer;
implementation
uses
ref,
r_light,
r_main,
r_rast,
r_aclip,
r_polyse,
SysUtils;
const
LIGHT_MIN = 5; // lowest light value we'll allow, to avoid the
// need for inner-loop light clamping
NUMVERTEXNORMALS = 162;
type
paedge_t = ^aedge_t;
aedge_t = array[0..1] of integer;
(*
** use a real variable to control lerping
*)
var
r_plightvec : vec3_t;
// CodeFusion...The line below MUST be commented out as it is not used.
// r_lerped : array [0..1023] of vec3_t;
r_lerp_frontv : vec3_t;
r_lerp_backv : vec3_t;
r_lerp_move : vec3_t;
r_ambientlight : integer;
r_shadelight : single;
r_thisframe : daliasframe_p;
r_lastframe : daliasframe_p;
s_pmdl : dmdl_p;
aliastransform : matrix34;
aliasworldtransform : matrix34;
aliasoldworldtransform : matrix34;
r_avertexnormals : array [0..NUMVERTEXNORMALS- 1] of vec3_t = ({$I anorms.inc});
s_ziscale : Single;
s_alias_forward : vec3_t;
s_alias_right : vec3_t;
s_alias_up : vec3_t;
aedges : array [0..11] of aedge_t = (
(0, 1), (1, 2), (2, 3), (3, 0),
(4, 5), (5, 6), (6, 7), (7, 4),
(0, 5), (1, 4), (2, 7), (3, 6)
);
(*
================
R_ConcatTransforms
================
*)
// TRANSLATOR'S NOTE: also defined in q_shared.h
(*
procedure R_ConcatTransforms(in1: tmatrix3x4; in2: tmatrix3x4; var out_: tmatrix3x4);
begin
out_[0][0] := in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
in1[0][2] * in2[2][0];
out_[0][1] := in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
in1[0][2] * in2[2][1];
out_[0][2] := in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
in1[0][2] * in2[2][2];
out_[0][3] := in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] +
in1[0][2] * in2[2][3] + in1[0][3];
out_[1][0] := in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
in1[1][2] * in2[2][0];
out_[1][1] := in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
in1[1][2] * in2[2][1];
out_[1][2] := in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
in1[1][2] * in2[2][2];
out_[1][3] := in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] +
in1[1][2] * in2[2][3] + in1[1][3];
out_[2][0] := in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
in1[2][2] * in2[2][0];
out_[2][1] := in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
in1[2][2] * in2[2][1];
out_[2][2] := in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
in1[2][2] * in2[2][2];
out_[2][3] := in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
in1[2][2] * in2[2][3] + in1[2][3];
end;
*)
(*
================
R_AliasCheckBBox
================
*)
(*
** R_AliasCheckFrameBBox
**
** Checks a specific alias frame bounding box
*)
function R_AliasCheckFrameBBox(frame : daliasframe_p; worldxf : matrix34) : cardinal;
var
aggregate_and_clipcode: cardinal;
aggregate_or_clipcode: cardinal;
zclipped: qboolean;
zfullyclipped: qboolean;
// minz : single;
i: integer;
mins, maxs: vec3_t;
transformed_min: vec3_t;
transformed_max: vec3_t;
j: integer;
tmp, transformed: vec3_t;
clipcode: cardinal;
dp: single;
begin
aggregate_and_clipcode := Cardinal(not Cardinal(0));
aggregate_or_clipcode := 0;
zclipped := false;
zfullyclipped := true;
// minz:= 9999.0;
clipcode := 0;
(*
** get the exact frame bounding box
*)
for i := 0 to 2 do
begin
mins[i] := frame^.translate[i];
maxs[i] := mins[i] + frame^.scale[i] * 255;
end;
(*
** transform the min and max values into view space
*)
R_AliasTransformVector(mins, transformed_min, aliastransform);
R_AliasTransformVector(maxs, transformed_max, aliastransform);
if (transformed_min[2] >= ALIAS_Z_CLIP_PLANE) then
zfullyclipped := false;
if (transformed_max[2] >= ALIAS_Z_CLIP_PLANE) then
zfullyclipped := false;
if (zfullyclipped) then
begin
Result := BBOX_TRIVIAL_REJECT;
Exit;
end;
if (zclipped) then
begin
Result := (BBOX_MUST_CLIP_XY or BBOX_MUST_CLIP_Z);
Exit;
end;
(*
** build a transformed bounding box from the given min and max
*)
for i:= 0 to 7 do
begin
clipcode := 0;
if ((i and 1) <> 0) then
tmp[0] := mins[0]
else
tmp[0] := maxs[0];
if ((i and 2) <> 0) then
tmp[1] := mins[1]
else
tmp[1] := maxs[1];
if ((i and 4) <> 0) then
tmp[2] := mins[2]
else
tmp[2] := maxs[2];
R_AliasTransformVector(tmp, transformed, worldxf);
for j := 0 to 3 do
begin
dp := DotProduct(transformed, view_clipplanes[j].normal);
if ((dp - view_clipplanes[j].dist) < 0.0) then
clipcode := clipcode or (1 shl j);
end;
aggregate_and_clipcode := aggregate_and_clipcode and clipcode;
aggregate_or_clipcode := aggregate_or_clipcode or clipcode;
end;
if (aggregate_and_clipcode <> 0) then
begin
Result := BBOX_TRIVIAL_REJECT;
Exit;
end;
if (aggregate_or_clipcode = 0) then
begin
Result := BBOX_TRIVIAL_ACCEPT;
Exit;
end;
Result := BBOX_MUST_CLIP_XY;
end;
function R_AliasCheckBBox : qboolean;
var
ccodes: array[0..1] of cardinal;
begin
(*
** non-lerping model
*)
ccodes[0] := R_AliasCheckFrameBBox(r_thisframe, aliasworldtransform);
ccodes[1] := 0;
if (currententity^.backlerp = 0.0) then
begin
if (ccodes[0] = BBOX_TRIVIAL_ACCEPT) then
begin
Result := qboolean(BBOX_TRIVIAL_ACCEPT);
Exit;
end
else
if ((ccodes[0] and BBOX_TRIVIAL_REJECT) <> 0) then
begin
Result := qboolean(BBOX_TRIVIAL_REJECT);
Exit;
end
else
begin
Result := qboolean(ccodes[0] and (not cardinal(BBOX_TRIVIAL_REJECT)));
Exit;
end;
end;
ccodes[1] := R_AliasCheckFrameBBox(r_lastframe, aliasoldworldtransform);
if ((ccodes[0] or ccodes[1]) = BBOX_TRIVIAL_ACCEPT) then
begin
Result := qboolean(BBOX_TRIVIAL_ACCEPT);
Exit;
end
else
if (((ccodes[0] and ccodes[1]) and BBOX_TRIVIAL_REJECT) <> 0) then
begin
Result := qboolean(BBOX_TRIVIAL_REJECT);
Exit;
end
else
begin
Result:= qboolean((ccodes[0] or ccodes[1]) and (not Cardinal(BBOX_TRIVIAL_REJECT)));
Exit;
end;
end;
(*
================
R_AliasTransformVector
================
*)
procedure R_AliasTransformVector(in_ : vec3_t; var out_ : vec3_t; xf : matrix34);
begin
out_[0] := DotProduct(in_, vec3_p(@xf[0][0])^) + xf[0][3];
out_[1] := DotProduct(in_, vec3_p(@xf[1][0])^) + xf[1][3];
out_[2] := DotProduct(in_, vec3_p(@xf[2][0])^) + xf[2][3];
end;
(*
================
R_AliasPreparePoints
General clipped case
================
*)
type
aliasbatchedtransformdata_t = record
num_points: integer;
last_verts: dtrivertx_p; // verts from the last frame
this_verts: dtrivertx_p; // verts from this frame
dest_verts: finalvert_p; // destination for transformed verts
end;
var
aliasbatchedtransformdata: aliasbatchedtransformdata_t;
procedure R_AliasPreparePoints;
(*type
tfinalvert_t_array = array [word] of finalvert_t; // TRANSLATOR'S NOTE: added to solve pointer->array problems
pfinalvert_t_array = ^tfinalvert_t_array;
tdstvert_t_array = array [word] of dstvert_t; // TRANSLATOR'S NOTE: added to solve pointer->array problems
pdstvert_t_array = ^tdstvert_t_array; *)
var
i : integer;
pstverts : dstvert_a;//pdstvert_t_array;
ptri : dtriangle_p;
pfv : array [0..2] of finalvert_p;
finalverts : array [0..integer(MAXALIASVERTS+((CACHE_SIZE- 1) div sizeof(finalvert_t)))+ 3- 1] of finalvert_t;
pfinalverts : finalvert_arrp;
begin
//PGM
iractive := 0;
if ((r_newrefdef.rdflags and RDF_IRGOGGLES) <> 0) and ((currententity^.flags and RF_IR_VISIBLE) <> 0) then
iractive := 1;
// iractive:= 0;
// if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity.flags & RF_IR_VISIBLE)
// iractive:= 1;
//PGM
// put work vertexes on stack, cache aligned
pfinalverts := finalvert_arrp(((Integer(@finalverts[0]) + CACHE_SIZE - 1) and (not Cardinal(CACHE_SIZE - 1))));
aliasbatchedtransformdata.num_points := s_pmdl^.num_xyz;
aliasbatchedtransformdata.last_verts := @r_lastframe^.verts;
aliasbatchedtransformdata.this_verts := @r_thisframe^.verts;
aliasbatchedtransformdata.dest_verts := Pointer(pfinalverts);
R_AliasTransformFinalVerts( aliasbatchedtransformdata.num_points,
aliasbatchedtransformdata.dest_verts,
aliasbatchedtransformdata.last_verts,
aliasbatchedtransformdata.this_verts );
// clip and draw all triangles
//
pstverts := Pointer(Cardinal(s_pmdl) + s_pmdl^.ofs_st);
ptri := Pointer(Cardinal(s_pmdl) + s_pmdl^.ofs_tris);
if ((currententity^.flags and RF_WEAPONMODEL) <> 0) and (r_lefthand^.value = 1.0) then
begin
for i := 0 to s_pmdl^.num_tris-1 do
begin
pfv[0] := @pfinalverts^[ptri^.index_xyz[0]];
pfv[1] := @pfinalverts^[ptri^.index_xyz[1]];
pfv[2] := @pfinalverts^[ptri^.index_xyz[2]];
if ((pfv[0]^.flags and pfv[1]^.flags and pfv[2].flags) <> 0) then
begin
Inc(Integer(ptri), SizeOf(dtriangle_t));
continue; // completely clipped
end;
// insert s/t coordinates
pfv[0]^.s := _SAL(pstverts^[ptri^.index_st[0]].s, 16);
pfv[0]^.t := _SAL(pstverts^[ptri^.index_st[0]].t, 16);
pfv[1]^.s := _SAL(pstverts^[ptri^.index_st[1]].s, 16);
pfv[1]^.t := _SAL(pstverts^[ptri^.index_st[1]].t, 16);
pfv[2]^.s := _SAL(pstverts^[ptri^.index_st[2]].s, 16);
pfv[2]^.t := _SAL(pstverts^[ptri^.index_st[2]].t, 16);
if ((pfv[0]^.flags or pfv[1]^.flags or pfv[2]^.flags) = 0) then
begin
// totally unclipped
aliastriangleparms.a := pfv[2];
aliastriangleparms.b := pfv[1];
aliastriangleparms.c := pfv[0];
R_DrawTriangle;
end
else
begin
R_AliasClipTriangle(pfv[2], pfv[1], pfv[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -