📄 r_bsp_c.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): r_bsp_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 : 18-july-2002 }
{ Updated by : CodeFusion (michael@skovslund.dk) }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ None. }
{----------------------------------------------------------------------------}
{ * TODO: }
{ Debug an see if the code works :0) }
{----------------------------------------------------------------------------}
(*
- Initial translation by Diogo Teixeira (20/01/2002)
NOTES:
.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 ->".
- Finished Initial translation in 24/01/2002
- For any discussion about this delphi translation mail: fozi_b@yahoo.com
*)
unit r_bsp_c;
interface
uses
qfiles,
q_shared,
r_local,
ref,
r_model;
type
solidstate_t = (touchessolid, drawnode, nodrawnode);
const
M_PI = 3.14159265358979323846;
MAX_BMODEL_VERTS = 500; // 6K
MAX_BMODEL_EDGES = 1000; // 12K
//
// current entity info
//
procedure R_RotateBmodel;
procedure R_DrawSolidClippedSubmodelPolygons(pmodel: model_p; topnode: mnode_p);
procedure R_DrawSubmodelPolygons(pmodel: model_p; clipflags: Integer; topnode: mnode_p);
procedure R_RenderWorld;
var
insubmodel: qboolean;
currententity: entity_p;
modelorg: vec3_t; // modelorg is the viewpoint reletive to
// the currently rendering entity
r_currentbkey: Integer;
r_entorigin: vec3_t; // the currently rendering entity in world
// coordinates
//===========================================================================
implementation
uses
r_misc,
r_rast,
r_edge,
DelphiTypes,
r_main,
SysUtils;
var
entity_rotation: matrix33;
pbverts: mvertex_p;
pbedges: bedge_p;
numbverts: Integer;
numbedges: Integer;
pfrontenter: mvertex_p;
pfrontexit: mvertex_p;
makeclippededge: qboolean;
c_drawnode: Integer;
(*
================
R_EntityRotate
================
*)
procedure R_EntityRotate(var vec: vec3_t);
var
tvec: vec3_t;
begin
VectorCopy(vec, tvec);
vec[0] := DotProduct(vec3_p(@entity_rotation[0])^, tvec);
vec[1] := DotProduct(vec3_p(@entity_rotation[1])^, tvec);
vec[2] := DotProduct(vec3_p(@entity_rotation[2])^, tvec);
end;
(*
================
R_RotateBmodel
================
*)
procedure R_RotateBmodel;
var
angle: Single;
s, c: Single;
temp1: matrix33;
temp2: matrix33;
temp3: matrix33;
begin
// TODO: should use a look-up table
// TODO: should really be stored with the entity instead of being reconstructed
// TODO: could cache lazily, stored in the entity
// TODO: share work with R_SetUpAliasTransform
// yaw
angle := currententity^.angles[YAW];
angle := angle * M_PI * 2 / 360;
s := sin(angle);
c := cos(angle);
temp1[0, 0] := c;
temp1[0, 1] := s;
temp1[0, 2] := 0.0;
temp1[1, 0] := -s;
temp1[1, 1] := c;
temp1[1, 2] := 0.0;
temp1[2, 0] := 0.0;
temp1[2, 1] := 0.0;
temp1[2, 2] := 1;
// pitch
angle := currententity^.angles[PITCH];
angle := angle * M_PI * 2 / 360;
s := sin(angle);
c := cos(angle);
temp2[0, 0] := c;
temp2[0, 1] := 0.0;
temp2[0, 2] := -s;
temp2[1, 0] := 0.0;
temp2[1, 1] := 1;
temp2[1, 2] := 0.0;
temp2[2, 0] := s;
temp2[2, 1] := 0.0;
temp2[2, 2] := c;
R_ConcatRotations(temp2, temp1, temp3);
// roll
angle := currententity^.angles[ROLL];
angle := angle * M_PI * 2 / 360;
s := sin(angle);
c := cos(angle);
temp1[0, 0] := 1;
temp1[0, 1] := 0.0;
temp1[0, 2] := 0.0;
temp1[1, 0] := 0.0;
temp1[1, 1] := c;
temp1[1, 2] := s;
temp1[2, 0] := 0.0;
temp1[2, 1] := -s;
temp1[2, 2] := c;
R_ConcatRotations(temp1, temp3, entity_rotation);
//
// rotate modelorg and the transformation matrix
//
R_EntityRotate(modelorg);
R_EntityRotate(vpn);
R_EntityRotate(vright);
R_EntityRotate(vup);
R_TransformFrustum;
end;
(*
================
R_RecursiveClipBPoly
Clip a bmodel poly down the world bsp tree
================
*)
procedure R_RecursiveClipBPoly(pedges: bedge_p; pnode: mnode_p; psurf: msurface_p);
var
psideedges: array[0..1] of bedge_p;
pnextedge: bedge_p;
ptedge: bedge_p;
i, side: Integer;
lastside: Integer;
dist, frac: Single;
lastdist: Single;
splitplane: mplane_p;
tplane: mplane_t;
pvert: mvertex_p;
plastvert: mvertex_p;
ptvert: mvertex_p;
pn: mnode_p;
area: Integer;
begin
psideedges[0] := nil;
psideedges[1] := nil;
makeclippededge := false;
// transform the BSP plane into model space
// FIXME: cache these?
splitplane := pnode^.plane;
tplane.dist := splitplane^.dist - DotProduct(r_entorigin, splitplane^.normal);
tplane.normal[0] := DotProduct(vec3_p(@entity_rotation[0, 0])^, splitplane^.normal);
tplane.normal[1] := DotProduct(vec3_p(@entity_rotation[1, 0])^, splitplane^.normal);
tplane.normal[2] := DotProduct(vec3_p(@entity_rotation[2, 0])^, splitplane^.normal);
// clip edges to BSP plane
// for ( ; pedges ; pedges = pnextedge)
while (pedges <> nil) do
begin
pnextedge := pedges^.pnext;
// set the status for the last point as the previous point
// FIXME: cache this stuff somehow?
plastvert := pedges^.v[0];
lastdist := DotProduct(plastvert^.position, tplane.normal) - tplane.dist;
if (lastdist > 0) then
lastside := 0
else
lastside := 1;
pvert := pedges^.v[1];
dist := DotProduct(pvert^.position, tplane.normal) - tplane.dist;
if (dist > 0) then
side := 0
else
side := 1;
if (side <> lastside) then
begin
// clipped
if (numbverts >= MAX_BMODEL_VERTS) then
Exit;
// generate the clipped vertex
frac := lastdist / (lastdist - dist);
// ptvert = &pbverts[numbverts++];
ptvert := mvertex_p(Integer(pbverts) + (numbverts * SizeOf(mvertex_t)));
Inc(numbverts, 1);
ptvert^.position[0] := plastvert^.position[0] +
frac * (pvert^.position[0] -
plastvert^.position[0]);
ptvert^.position[1] := plastvert^.position[1] +
frac * (pvert^.position[1] -
plastvert^.position[1]);
ptvert^.position[2] := plastvert^.position[2] +
frac * (pvert^.position[2] -
plastvert^.position[2]);
// split into two edges, one on each side, and remember entering
// and exiting points
// FIXME: share the clip edge by having a winding direction flag?
if (numbedges >= (MAX_BMODEL_EDGES - 1)) then
begin
ri.Con_Printf(PRINT_ALL,'Out of edges for bmodel');
Exit;
end;
ptedge := bedge_p(Integer(pbedges)+(numbedges*SizeOf(bedge_t)));
ptedge^.pnext := psideedges[lastside];
psideedges[lastside] := ptedge;
ptedge^.v[0] := plastvert;
ptedge^.v[1] := ptvert;
Inc(numbedges);
ptedge := bedge_p(Integer(pbedges)+(numbedges*SizeOf(bedge_t)));
ptedge^.pnext := psideedges[side];
psideedges[side] := ptedge;
ptedge^.v[0] := ptvert;
ptedge^.v[1] := pvert;
Inc(numbedges);
if (side = 0) then
begin
// entering for front, exiting for back
pfrontenter := ptvert;
makeclippededge := true;
end
else
begin
pfrontexit := ptvert;
makeclippededge := true;
end
end
else
begin
// add the edge to the appropriate side
pedges^.pnext := psideedges[side];
psideedges[side] := pedges;
end;
pedges := pnextedge;
end;
// if anything was clipped, reconstitute and add the edges along the clip
// plane to both sides (but in opposite directions)
if (makeclippededge) then
begin
if (numbedges >= (MAX_BMODEL_EDGES - 2)) then
begin
ri.Con_Printf(PRINT_ALL, 'Out of edges for bmodel' + #13#10);
Exit;
end;
ptedge := bedge_p(Integer(pbedges) + (numbedges * SizeOf(bedge_t)));
ptedge^.pnext := psideedges[0];
psideedges[0] := ptedge;
ptedge^.v[0] := pfrontexit;
ptedge^.v[1] := pfrontenter;
Inc(numbedges);
ptedge := bedge_p(Integer(pbedges) + (numbedges * SizeOf(bedge_t)));
ptedge^.pnext := psideedges[1];
psideedges[1] := ptedge;
ptedge^.v[0] := pfrontenter;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -