Moved modified HL SDK to trunk

This commit is contained in:
Scott Ehlert
2006-08-27 02:22:59 +00:00
parent 28c4ea4fec
commit 30235e05e5
900 changed files with 344676 additions and 0 deletions

687
hlsdk/utils/visx2/flow.c Normal file
View File

@ -0,0 +1,687 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "vis.h"
int c_fullskip;
int c_chains;
int c_portalskip, c_leafskip;
int c_vistest, c_mighttest;
int active;
void CheckStack (leaf_t *leaf, threaddata_t *thread)
{
pstack_t *p;
for (p=thread->pstack_head.next ; p ; p=p->next)
{
// printf ("=");
if (p->leaf == leaf)
Error ("CheckStack: leaf recursion");
}
// printf ("\n");
}
winding_t *AllocStackWinding (pstack_t *stack)
{
int i;
for (i=0 ; i<3 ; i++)
{
if (stack->freewindings[i])
{
stack->freewindings[i] = 0;
return &stack->windings[i];
}
}
Error ("AllocStackWinding: failed");
return NULL;
}
void FreeStackWinding (winding_t *w, pstack_t *stack)
{
int i;
i = w - stack->windings;
if (i<0 || i>2)
return; // not from local
if (stack->freewindings[i])
Error ("FreeStackWinding: allready free");
stack->freewindings[i] = 1;
}
/*
==============
ChopWinding
==============
*/
winding_t *ChopWinding (winding_t *in, pstack_t *stack, plane_t *split)
{
vec_t dists[128];
int sides[128];
int counts[3];
vec_t dot;
int i, j;
vec_t *p1, *p2;
vec3_t mid;
winding_t *neww;
int maxpts;
counts[0] = counts[1] = counts[2] = 0;
if ( in->numpoints > (sizeof(sides)/sizeof(*sides)) )
Error("Winding with too many sides!");
// determine sides for each point
for (i=0 ; i<in->numpoints ; i++)
{
dot = DotProduct (in->points[i], split->normal);
dot -= split->dist;
dists[i] = dot;
if (dot > ON_EPSILON)
sides[i] = SIDE_FRONT;
else if (dot < -ON_EPSILON)
sides[i] = SIDE_BACK;
else
{
sides[i] = SIDE_ON;
}
counts[sides[i]]++;
}
if (!counts[1])
return in; // completely on front side
if (!counts[0])
{
FreeStackWinding (in, stack);
return NULL;
}
sides[i] = sides[0];
dists[i] = dists[0];
neww = AllocStackWinding (stack);
neww->numpoints = 0;
for (i=0 ; i<in->numpoints ; i++)
{
p1 = in->points[i];
if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
{
FreeStackWinding (neww, stack);
return in; // can't chop -- fall back to original
}
if (sides[i] == SIDE_ON)
{
VectorCopy (p1, neww->points[neww->numpoints]);
neww->numpoints++;
continue;
}
if (sides[i] == SIDE_FRONT)
{
VectorCopy (p1, neww->points[neww->numpoints]);
neww->numpoints++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
{
FreeStackWinding (neww, stack);
return in; // can't chop -- fall back to original
}
// generate a split point
p2 = in->points[(i+1)%in->numpoints];
dot = dists[i] / (dists[i]-dists[i+1]);
for (j=0 ; j<3 ; j++)
{ // avoid round off error when possible
if (split->normal[j] == 1)
mid[j] = split->dist;
else if (split->normal[j] == -1)
mid[j] = -split->dist;
else
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
}
VectorCopy (mid, neww->points[neww->numpoints]);
neww->numpoints++;
}
// free the original winding
FreeStackWinding (in, stack);
return neww;
}
/*
==============
InTheBallpark
Build a bounding box using the start and end windings
then verify that the clip winding bounding box touches
the start/end bounding box.
==============
*/
int
InTheBallpark( winding_t *start, winding_t *clip, winding_t *end )
{
int d,p;
vec3_t bmin = {9999,9999,9999}, bmax = {-9999,-9999,-9999};
vec3_t cmin = {9999,9999,9999}, cmax = {-9999,-9999,-9999};
vec3_t bcenter, bsize;
vec3_t ccenter, csize;
for(d=0; d<3; d++)
{
// Establish a bounding box based on start winding
for (p=0; p<start->numpoints; p++)
{
if (start->points[p][d] < bmin[d])
bmin[d] = start->points[p][d];
if (start->points[p][d] > bmax[d])
bmax[d] = start->points[p][d];
}
// Extend this bounding box based on end winding
for (p=0; p<end->numpoints; p++)
{
if (end->points[p][d] < bmin[d])
bmin[d] = end->points[p][d];
if (end->points[p][d] > bmax[d])
bmax[d] = end->points[p][d];
}
// Establish a second box based on clip winding
for (p=0; p<clip->numpoints; p++)
{
if (clip->points[p][d] < cmin[d])
cmin[d] = clip->points[p][d];
if (clip->points[p][d] > cmax[d])
cmax[d] = clip->points[p][d];
}
// Calculate the center of each bounding box
bcenter[d] = (bmax[d]+bmin[d]); // Optimized out /2;
ccenter[d] = (cmax[d]+cmin[d]); // Optimized out /2;
// Calculate the distances from center to the edges
bsize[d] = (bmax[d] - bmin[d]); // Optimized out /2;
csize[d] = (cmax[d] - cmin[d]); // Optimized out /2;
// Are the centers further apart than the distance to the edges
if ( fabs(bcenter[d]-ccenter[d]) > bsize[d]+csize[d]+ON_EPSILON )
return 0;
}
return 1;
}
/*
==============
ClipToSeperators
Source, pass, and target are an ordering of portals.
Generates seperating planes canidates by taking two points from source and one
point from pass, and clips target by them.
If target is totally clipped away, that portal can not be seen through.
Normal clip keeps target on the same side as pass, which is correct if the
order goes source, pass, target. If the order goes pass, source, target then
flipclip should be set.
==============
*/
winding_t *ClipToSeperators (winding_t *source, winding_t *pass, winding_t *target, qboolean flipclip, pstack_t *stack)
{
int i, j, k, l;
plane_t plane;
vec3_t v1, v2;
float d;
vec_t length;
int counts[3];
qboolean fliptest;
// check all combinations
for (i=0 ; i<source->numpoints ; i++)
{
l = (i+1)%source->numpoints;
VectorSubtract (source->points[l] , source->points[i], v1);
// fing a vertex of pass that makes a plane that puts all of the
// vertexes of pass on the front side and all of the vertexes of
// source on the back side
for (j=0 ; j<pass->numpoints ; j++)
{
VectorSubtract (pass->points[j], source->points[i], v2);
plane.normal[0] = v1[1]*v2[2] - v1[2]*v2[1];
plane.normal[1] = v1[2]*v2[0] - v1[0]*v2[2];
plane.normal[2] = v1[0]*v2[1] - v1[1]*v2[0];
// if points don't make a valid plane, skip it
length = plane.normal[0] * plane.normal[0]
+ plane.normal[1] * plane.normal[1]
+ plane.normal[2] * plane.normal[2];
if (length < ON_EPSILON)
continue;
length = 1/sqrt(length);
plane.normal[0] *= length;
plane.normal[1] *= length;
plane.normal[2] *= length;
plane.dist = DotProduct (pass->points[j], plane.normal);
//
// find out which side of the generated seperating plane has the
// source portal
//
#if 1
fliptest = false;
for (k=0 ; k<source->numpoints ; k++)
{
if (k == i || k == l)
continue;
d = DotProduct (source->points[k], plane.normal) - plane.dist;
if (d < -ON_EPSILON)
{ // source is on the negative side, so we want all
// pass and target on the positive side
fliptest = false;
break;
}
else if (d > ON_EPSILON)
{ // source is on the positive side, so we want all
// pass and target on the negative side
fliptest = true;
break;
}
}
if (k == source->numpoints)
continue; // planar with source portal
#else
fliptest = flipclip;
#endif
//
// flip the normal if the source portal is backwards
//
if (fliptest)
{
VectorSubtract (vec3_origin, plane.normal, plane.normal);
plane.dist = -plane.dist;
}
#if 1
//
// if all of the pass portal points are now on the positive side,
// this is the seperating plane
//
counts[0] = counts[1] = counts[2] = 0;
for (k=0 ; k<pass->numpoints ; k++)
{
if (k==j)
continue;
d = DotProduct (pass->points[k], plane.normal) - plane.dist;
if (d < -ON_EPSILON)
break;
else if (d > ON_EPSILON)
counts[0]++;
else
counts[2]++;
}
if (k != pass->numpoints)
continue; // points on negative side, not a seperating plane
if (!counts[0])
continue; // planar with seperating plane
#else
k = (j+1)%pass->numpoints;
d = DotProduct (pass->points[k], plane.normal) - plane.dist;
if (d < -ON_EPSILON)
continue;
k = (j+pass->numpoints-1)%pass->numpoints;
d = DotProduct (pass->points[k], plane.normal) - plane.dist;
if (d < -ON_EPSILON)
continue;
#endif
//
// flip the normal if we want the back side
//
if (flipclip)
{
VectorSubtract (vec3_origin, plane.normal, plane.normal);
plane.dist = -plane.dist;
}
//
// clip target by the seperating plane
//
target = ChopWinding (target, stack, &plane);
if (!target)
return NULL; // target is not visible
}
}
return target;
}
/*
==================
RecursiveLeafFlow
Flood fill through the leafs
If src_portal is NULL, this is the originating leaf
==================
*/
void RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
{
pstack_t stack;
portal_t *p;
plane_t backplane;
leaf_t *leaf;
int i, j;
long *test, *might, *vis, more;
int pnum;
c_chains++;
leaf = &leafs[leafnum];
// CheckStack (leaf, thread);
// mark the leaf as visible
if (! (thread->leafvis[leafnum>>3] & (1<<(leafnum&7)) ) )
{
thread->leafvis[leafnum>>3] |= 1<<(leafnum&7);
thread->base->numcansee++;
}
prevstack->next = &stack;
stack.next = NULL;
stack.leaf = leaf;
stack.portal = NULL;
might = (long *)stack.mightsee;
vis = (long *)thread->leafvis;
// check all portals for flowing into other leafs
for (i=0 ; i<leaf->numportals ; i++)
{
p = leaf->portals[i];
if ( ! (prevstack->mightsee[p->leaf>>3] & (1<<(p->leaf&7)) ) )
{
c_leafskip++;
continue; // can't possibly see it
}
#if 0
pnum = p - portals;
if ( (thread->fullportal[pnum>>3] & (1<<(pnum&7)) ) )
{
c_fullskip++;
continue; // allready have full vis info
}
#endif
// if the portal can't see anything we haven't allready seen, skip it
if (p->status == stat_done)
{
c_vistest++;
test = (long *)p->visbits;
}
else
{
c_mighttest++;
test = (long *)p->mightsee;
}
more = 0;
for (j=0 ; j<bitlongs ; j++)
{
might[j] = ((long *)prevstack->mightsee)[j] & test[j];
more |= (might[j] & ~vis[j]);
}
if (!more)
{ // can't see anything new
c_portalskip++;
continue;
}
// get plane of portal, point normal into the neighbor leaf
stack.portalplane = p->plane;
VectorSubtract (vec3_origin, p->plane.normal, backplane.normal);
backplane.dist = -p->plane.dist;
if (VectorCompare (prevstack->portalplane.normal, backplane.normal) )
continue; // can't go out a coplanar face
c_portalcheck++;
stack.portal = p;
stack.next = NULL;
stack.freewindings[0] = 1;
stack.freewindings[1] = 1;
stack.freewindings[2] = 1;
stack.pass = ChopWinding (p->winding, &stack, &thread->pstack_head.portalplane);
if (!stack.pass)
continue;
stack.source = ChopWinding (prevstack->source, &stack, &backplane);
if (!stack.source)
continue;
if (!prevstack->pass)
{ // the second leaf can only be blocked if coplanar
RecursiveLeafFlow (p->leaf, thread, &stack);
continue;
}
stack.pass = ChopWinding (stack.pass, &stack, &prevstack->portalplane);
if (!stack.pass)
continue;
c_portaltest++;
#ifdef NOT_BROKEN
if (!InTheBallpark(stack.source, prevstack->pass, stack.pass))
{
FreeStackWinding (stack.pass, &stack);
stack.pass = NULL;
continue;
}
#endif
stack.pass = ClipToSeperators (stack.source, prevstack->pass, stack.pass, false, &stack);
if (!stack.pass)
continue;
stack.pass = ClipToSeperators (prevstack->pass, stack.source, stack.pass, true, &stack);
if (!stack.pass)
continue;
c_portalpass++;
#if 0
if (stack.pass == p->winding)
{
thread->fullportal[pnum>>3] |= (1<<(pnum&7));
FreeStackWinding (stack.source, &stack);
stack.source = ChopWinding (thread->base->winding, &stack, &backplane);
for (j=0 ; j<bitlongs ; j++)
might[j] = ((long *)thread->pstack_head.mightsee)[j] & test[j];
}
#endif
// flow through it for real
RecursiveLeafFlow (p->leaf, thread, &stack);
}
}
/*
===============
PortalFlow
===============
*/
void PortalFlow (portal_t *p)
{
threaddata_t data;
int i;
if (p->status != stat_working)
Error ("PortalFlow: reflowed");
p->status = stat_working;
p->visbits = malloc (bitbytes);
memset (p->visbits, 0, bitbytes);
memset (&data, 0, sizeof(data));
data.leafvis = p->visbits;
data.base = p;
data.pstack_head.portal = p;
data.pstack_head.source = p->winding;
data.pstack_head.portalplane = p->plane;
for (i=0 ; i<bitlongs ; i++)
((long *)data.pstack_head.mightsee)[i] = ((long *)p->mightsee)[i];
RecursiveLeafFlow (p->leaf, &data, &data.pstack_head);
p->status = stat_done;
}
/*
===============================================================================
This is a rough first-order aproximation that is used to trivially reject some
of the final calculations.
===============================================================================
*/
void SimpleFlood (portal_t *srcportal, int leafnum, byte *portalsee, int *c_leafsee)
{
int i;
leaf_t *leaf;
portal_t *p;
if (srcportal->mightsee[leafnum>>3] & (1<<(leafnum&7)) )
return;
srcportal->mightsee[leafnum>>3] |= (1<<(leafnum&7));
(*c_leafsee)++;
leaf = &leafs[leafnum];
for (i=0 ; i<leaf->numportals ; i++)
{
p = leaf->portals[i];
if ( !portalsee[ p - portals ] )
continue;
SimpleFlood (srcportal, p->leaf, portalsee, c_leafsee);
}
}
/*
==============
BasePortalVis
==============
*/
void BasePortalVis (int threadnum)
{
int i, j, k;
portal_t *tp, *p;
float d;
winding_t *w;
byte portalsee[MAX_PORTALS];
int c_leafsee;
while (1)
{
i = GetThreadWork ();
if (i == -1)
break;
p = portals+i;
p->mightsee = malloc (bitbytes);
memset (p->mightsee, 0, bitbytes);
memset (portalsee, 0, numportals*2);
for (j=0, tp = portals ; j<numportals*2 ; j++, tp++)
{
if (j == i)
continue;
w = tp->winding;
for (k=0 ; k<w->numpoints ; k++)
{
d = DotProduct (w->points[k], p->plane.normal)
- p->plane.dist;
if (d > ON_EPSILON)
break;
}
if (k == w->numpoints)
continue; // no points on front
w = p->winding;
for (k=0 ; k<w->numpoints ; k++)
{
d = DotProduct (w->points[k], tp->plane.normal)
- tp->plane.dist;
if (d < -ON_EPSILON)
break;
}
if (k == w->numpoints)
continue; // no points on front
portalsee[j] = 1;
}
c_leafsee = 0;
SimpleFlood (p, p->leaf, portalsee, &c_leafsee);
p->nummightsee = c_leafsee;
// printf ("portal:%4i c_leafsee:%4i \n", i, c_leafsee);
}
}

View File

@ -0,0 +1,153 @@
# Microsoft Developer Studio Project File - Name="vis" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=vis - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "vis.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "vis.mak" CFG="vis - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "vis - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "vis - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/visx2", KVGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "vis - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /GX /O2 /I "..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "vis - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /Gm /GX /ZI /Od /I "..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Fr /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "vis - Win32 Release"
# Name "vis - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\flow.c
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\soundpvs.c
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.c
# End Source File
# Begin Source File
SOURCE=..\vis.c
# End Source File
# Begin Source File
SOURCE=..\vis.h
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\bspfile.h
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "vis"=.\vis.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/visx2", KVGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/visx2", KVGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,328 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="vis"
ProjectGUID="{DFA19018-A7DA-4655-AD9C-9B8D7C2451FD}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/visx2&quot;, KVGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/vis.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/vis.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/vis.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/vis.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/vis.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
BrowseInformationFile=".\Debug/"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/vis.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/vis.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/vis.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\flow.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\soundpvs.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\vis.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\vis.h">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\bspfile.h">
</File>
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\..\common\mathlib.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
<File
RelativePath="..\..\common\threads.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,439 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="vis"
ProjectGUID="{DFA19018-A7DA-4655-AD9C-9B8D7C2451FD}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/vis.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/vis.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/vis.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/vis.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/vis.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/vis.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
BrowseInformationFile=".\Debug/"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/vis.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/vis.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\flow.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\soundpvs.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\vis.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\vis.h"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\bspfile.h"
>
</File>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\..\common\mathlib.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
<File
RelativePath="..\..\common\threads.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,156 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "vis.h"
/*
Some textures (sky, water, slime, lava) are considered ambien sound emiters.
Find an aproximate distance to the nearest emiter of each class for each leaf.
*/
/*
====================
SurfaceBBox
====================
*/
void SurfaceBBox (dface_t *s, vec3_t mins, vec3_t maxs)
{
int i, j;
int e;
int vi;
float *v;
mins[0] = mins[1] = mins[2] = 999999;
maxs[0] = maxs[1] = maxs[2] = -99999;
for (i=0 ; i<s->numedges ; i++)
{
e = dsurfedges[s->firstedge+i];
if (e >= 0)
vi = dedges[e].v[0];
else
vi = dedges[-e].v[1];
v = dvertexes[vi].point;
for (j=0 ; j<3 ; j++)
{
if (v[j] < mins[j])
mins[j] = v[j];
if (v[j] > maxs[j])
maxs[j] = v[j];
}
}
}
/*
====================
CalcAmbientSounds
====================
*/
void CalcAmbientSounds (void)
{
int i, j, k, l;
dleaf_t *leaf, *hit;
byte *vis;
dface_t *surf;
vec3_t mins, maxs;
float d, maxd;
int ambient_type;
texinfo_t *info;
miptex_t *miptex;
int ofs;
float dists[NUM_AMBIENTS];
float vol;
for (i=0 ; i< portalleafs ; i++)
{
leaf = &dleafs[i+1];
//
// clear ambients
//
for (j=0 ; j<NUM_AMBIENTS ; j++)
dists[j] = 1020;
vis = &uncompressed[i*bitbytes];
for (j=0 ; j< portalleafs ; j++)
{
if ( !(vis[j>>3] & (1<<(j&7))) )
continue;
//
// check this leaf for sound textures
//
hit = &dleafs[j+1];
for (k=0 ; k< hit->nummarksurfaces ; k++)
{
surf = &dfaces[dmarksurfaces[hit->firstmarksurface + k]];
info = &texinfo[surf->texinfo];
ofs = ((dmiptexlump_t *)dtexdata)->dataofs[info->miptex];
miptex = (miptex_t *)(&dtexdata[ofs]);
if ( !Q_strncasecmp (miptex->name, "!water", 6) )
ambient_type = AMBIENT_WATER;
else if ( !Q_strncasecmp (miptex->name, "sky", 3) )
ambient_type = AMBIENT_SKY;
else if ( !Q_strncasecmp (miptex->name, "!slime", 6) )
ambient_type = AMBIENT_WATER; // AMBIENT_SLIME;
else if ( !Q_strncasecmp (miptex->name, "!lava", 6) )
ambient_type = AMBIENT_LAVA;
else if ( !Q_strncasecmp (miptex->name, "!04water", 8) )
ambient_type = AMBIENT_WATER;
else
continue;
// find distance from source leaf to polygon
SurfaceBBox (surf, mins, maxs);
maxd = 0;
for (l=0 ; l<3 ; l++)
{
if (mins[l] > leaf->maxs[l])
d = mins[l] - leaf->maxs[l];
else if (maxs[l] < leaf->mins[l])
d = leaf->mins[l] - mins[l];
else
d = 0;
if (d > maxd)
maxd = d;
}
maxd = 0.25;
if (maxd < dists[ambient_type])
dists[ambient_type] = maxd;
}
}
for (j=0 ; j<NUM_AMBIENTS ; j++)
{
if (dists[j] < 100)
vol = 1.0;
else
{
vol = 1.0 - dists[2]*0.002;
if (vol < 0)
vol = 0;
}
leaf->ambient_level[j] = vol*255;
}
}
}

527
hlsdk/utils/visx2/vis.c Normal file
View File

@ -0,0 +1,527 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// vis.c
#include "vis.h"
#include "threads.h"
#define MAX_THREADS 4
int numportals;
int portalleafs;
portal_t *portals;
leaf_t *leafs;
int c_portaltest, c_portalpass, c_portalcheck;
qboolean showgetleaf = true;
int leafon; // the next leaf to be given to a thread to process
byte *vismap, *vismap_p, *vismap_end; // past visfile
int originalvismapsize;
byte *uncompressed; // [bitbytes*portalleafs]
int bitbytes; // (portalleafs+63)>>3
int bitlongs;
qboolean fastvis;
qboolean verbose;
//=============================================================================
void PlaneFromWinding (winding_t *w, plane_t *plane)
{
vec3_t v1, v2;
// calc plane
VectorSubtract (w->points[2], w->points[1], v1);
VectorSubtract (w->points[0], w->points[1], v2);
CrossProduct (v2, v1, plane->normal);
VectorNormalize (plane->normal);
plane->dist = DotProduct (w->points[0], plane->normal);
}
/*
==================
NewWinding
==================
*/
winding_t *NewWinding (int points)
{
winding_t *w;
int size;
if (points > MAX_POINTS_ON_WINDING)
Error ("NewWinding: %i points", points);
size = (int)((winding_t *)0)->points[points];
w = malloc (size);
memset (w, 0, size);
return w;
}
void pw(winding_t *w)
{
int i;
for (i=0 ; i<w->numpoints ; i++)
printf ("(%5.1f, %5.1f, %5.1f)\n",w->points[i][0], w->points[i][1],w->points[i][2]);
}
void prl(leaf_t *l)
{
int i;
portal_t *p;
plane_t pl;
for (i=0 ; i<l->numportals ; i++)
{
p = l->portals[i];
pl = p->plane;
printf ("portal %4i to leaf %4i : %7.1f : (%4.1f, %4.1f, %4.1f)\n",(int)(p-portals),p->leaf,pl.dist, pl.normal[0], pl.normal[1], pl.normal[2]);
}
}
//=============================================================================
/*
=============
GetNextPortal
Returns the next portal for a thread to work on
Returns the portals from the least complex, so the later ones can reuse
the earlier information.
=============
*/
portal_t *GetNextPortal (void)
{
int j;
portal_t *p, *tp;
int min;
int i;
i = GetThreadWork (); // bump the pacifier
if (i == -1)
return NULL;
ThreadLock();
min = 99999;
p = NULL;
for (j=0, tp = portals ; j<numportals*2 ; j++, tp++)
{
if (tp->nummightsee < min && tp->status == stat_none)
{
min = tp->nummightsee;
p = tp;
}
}
if (p)
p->status = stat_working;
ThreadUnlock();
return p;
}
/*
==============
LeafThread
==============
*/
void LeafThread (int thread)
{
portal_t *p;
do
{
p = GetNextPortal ();
if (!p)
break;
PortalFlow (p);
qprintf ("portal:%4i mightsee:%4i cansee:%4i\n", (int)(p - portals), p->nummightsee, p->numcansee);
} while (1);
}
/*
===============
CompressRow
===============
*/
int CompressRow (byte *vis, byte *dest)
{
int j;
int rep;
int visrow;
byte *dest_p;
dest_p = dest;
visrow = (portalleafs + 7)>>3;
for (j=0 ; j<visrow ; j++)
{
*dest_p++ = vis[j];
if (vis[j])
continue;
rep = 1;
for ( j++; j<visrow ; j++)
if (vis[j] || rep == 255)
break;
else
rep++;
*dest_p++ = rep;
j--;
}
return dest_p - dest;
}
/*
===============
LeafFlow
Builds the entire visibility list for a leaf
===============
*/
int totalvis;
void LeafFlow (int leafnum)
{
leaf_t *leaf;
byte *outbuffer;
byte compressed[MAX_MAP_LEAFS/8];
int i, j;
int numvis;
byte *dest;
portal_t *p;
//
// flow through all portals, collecting visible bits
//
outbuffer = uncompressed + leafnum*bitbytes;
leaf = &leafs[leafnum];
for (i=0 ; i<leaf->numportals ; i++)
{
p = leaf->portals[i];
if (p->status != stat_done)
Error ("portal not done");
for (j=0 ; j<bitbytes ; j++)
outbuffer[j] |= p->visbits[j];
}
if (outbuffer[leafnum>>3] & (1<<(leafnum&7)))
printf ("WARNING: Leaf portals saw into leaf");
outbuffer[leafnum>>3] |= (1<<(leafnum&7));
numvis = 0;
for (i=0 ; i<portalleafs ; i++)
if (outbuffer[i>>3] & (1<<(i&3)))
numvis++;
//
// compress the bit string
//
qprintf ("leaf %4i : %4i visible\n", leafnum, numvis);
totalvis += numvis;
#if 0
i = (portalleafs+7)>>3;
memcpy (compressed, outbuffer, i);
#else
i = CompressRow (outbuffer, compressed);
#endif
dest = vismap_p;
vismap_p += i;
if (vismap_p > vismap_end)
Error ("Vismap expansion overflow");
dleafs[leafnum+1].visofs = dest-vismap; // leaf 0 is a common solid
memcpy (dest, compressed, i);
}
/*
==================
CalcPortalVis
==================
*/
void CalcPortalVis (void)
{
int i;
// fastvis just uses mightsee for a very loose bound
if (fastvis)
{
for (i=0 ; i<numportals*2 ; i++)
{
portals[i].visbits = portals[i].mightsee;
portals[i].status = stat_done;
}
return;
}
leafon = 0;
RunThreadsOn (numportals*2, true, LeafThread);
qprintf ("portalcheck: %i portaltest: %i portalpass: %i\n",c_portalcheck, c_portaltest, c_portalpass);
qprintf ("c_vistest: %i c_mighttest: %i\n",c_vistest, c_mighttest);
}
/*
==================
CalcVis
==================
*/
void CalcVis (void)
{
int i;
RunThreadsOn (numportals*2, true, BasePortalVis);
CalcPortalVis ();
//
// assemble the leaf vis lists by oring and compressing the portal lists
//
for (i=0 ; i<portalleafs ; i++)
LeafFlow (i);
printf ("average leafs visible: %i\n", totalvis / portalleafs);
}
/*
============
LoadPortals
============
*/
void LoadPortals (char *name)
{
int i, j;
portal_t *p;
leaf_t *l;
char magic[80];
FILE *f;
int numpoints;
winding_t *w;
int leafnums[2];
plane_t plane;
if (!strcmp(name,"-"))
f = stdin;
else
{
f = fopen(name, "r");
if (!f)
{
printf ("LoadPortals: couldn't read %s\n",name);
printf ("No vising performed.\n");
exit (1);
}
}
if (fscanf (f,"%79s\n%i\n%i\n",magic, &portalleafs, &numportals) != 3)
Error ("LoadPortals: failed to read header");
if (strcmp(magic,PORTALFILE))
Error ("LoadPortals: not a portal file");
printf ("%4i portalleafs\n", portalleafs);
printf ("%4i numportals\n", numportals);
bitbytes = ((portalleafs+63)&~63)>>3;
bitlongs = bitbytes/sizeof(long);
// each file portal is split into two memory portals
portals = malloc(2*numportals*sizeof(portal_t));
memset (portals, 0, 2*numportals*sizeof(portal_t));
leafs = malloc(portalleafs*sizeof(leaf_t));
memset (leafs, 0, portalleafs*sizeof(leaf_t));
originalvismapsize = portalleafs*((portalleafs+7)/8);
vismap = vismap_p = dvisdata;
vismap_end = vismap + MAX_MAP_VISIBILITY;
for (i=0, p=portals ; i<numportals ; i++)
{
if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1])
!= 3)
Error ("LoadPortals: reading portal %i", i);
if (numpoints > MAX_POINTS_ON_WINDING)
Error ("LoadPortals: portal %i has too many points", i);
if ( (unsigned)leafnums[0] > portalleafs
|| (unsigned)leafnums[1] > portalleafs)
Error ("LoadPortals: reading portal %i", i);
w = p->winding = NewWinding (numpoints);
w->original = true;
w->numpoints = numpoints;
for (j=0 ; j<numpoints ; j++)
{
double v[3];
int k;
// scanf into double, then assign to vec_t
if (fscanf (f, "(%lf %lf %lf ) "
, &v[0], &v[1], &v[2]) != 3)
Error ("LoadPortals: reading portal %i", i);
for (k=0 ; k<3 ; k++)
w->points[j][k] = v[k];
}
fscanf (f, "\n");
// calc plane
PlaneFromWinding (w, &plane);
// create forward portal
l = &leafs[leafnums[0]];
if (l->numportals == MAX_PORTALS_ON_LEAF)
Error ("Leaf with too many portals");
l->portals[l->numportals] = p;
l->numportals++;
p->winding = w;
VectorSubtract (vec3_origin, plane.normal, p->plane.normal);
p->plane.dist = -plane.dist;
p->leaf = leafnums[1];
p++;
// create backwards portal
l = &leafs[leafnums[1]];
if (l->numportals == MAX_PORTALS_ON_LEAF)
Error ("Leaf with too many portals");
l->portals[l->numportals] = p;
l->numportals++;
p->winding = NewWinding(w->numpoints);
p->winding->numpoints = w->numpoints;
for (j=0 ; j<w->numpoints ; j++)
{
VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]);
}
p->plane = plane;
p->leaf = leafnums[0];
p++;
}
fclose (f);
}
/*
===========
main
===========
*/
int main (int argc, char **argv)
{
char portalfile[1024];
char source[1024];
int i;
double start, end;
printf ("vis.exe v1.3 (%s)\n", __DATE__);
printf ("---- vis ----\n");
verbose = false;
for (i=1 ; i<argc ; i++)
{
if (!strcmp(argv[i],"-threads"))
{
numthreads = atoi (argv[i+1]);
i++;
}
else if (!strcmp(argv[i], "-fast"))
{
printf ("fastvis = true\n");
fastvis = true;
}
else if (!strcmp(argv[i], "-v"))
{
printf ("verbose = true\n");
verbose = true;
}
else if (argv[i][0] == '-')
Error ("Unknown option \"%s\"", argv[i]);
else
break;
}
if (i != argc - 1)
Error ("usage: vis [-threads #] [-level 0-4] [-fast] [-v] bspfile");
start = I_FloatTime ();
ThreadSetDefault ();
printf ("%i thread(s)\n", numthreads);
strcpy (source, argv[i]);
StripExtension (source);
DefaultExtension (source, ".bsp");
LoadBSPFile (source);
strcpy (portalfile, argv[i]);
StripExtension (portalfile);
strcat (portalfile, ".prt");
LoadPortals (portalfile);
uncompressed = malloc(bitbytes*portalleafs);
memset (uncompressed, 0, bitbytes*portalleafs);
CalcVis ();
qprintf ("c_chains: %i\n",c_chains);
visdatasize = vismap_p - dvisdata;
printf ("visdatasize:%i compressed from %i\n", visdatasize, originalvismapsize);
CalcAmbientSounds ();
WriteBSPFile (source);
// unlink (portalfile);
end = I_FloatTime ();
printf ("%5.1f seconds elapsed\n", end-start);
free(uncompressed);
return 0;
}

141
hlsdk/utils/visx2/vis.h Normal file
View File

@ -0,0 +1,141 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// vis.h
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#define MAX_PORTALS 32768
#define PORTALFILE "PRT1"
//#define ON_EPSILON 0.1
typedef struct
{
vec3_t normal;
float dist;
} plane_t;
#define MAX_POINTS_ON_WINDING 64
#define MAX_POINTS_ON_FIXED_WINDING 12
typedef struct
{
qboolean original; // don't free, it's part of the portal
int numpoints;
vec3_t points[MAX_POINTS_ON_FIXED_WINDING]; // variable sized
} winding_t;
winding_t *NewWinding (int points);
void FreeWinding (winding_t *w);
winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon);
winding_t *CopyWinding (winding_t *w);
typedef enum {stat_none, stat_working, stat_done} vstatus_t;
typedef struct
{
plane_t plane; // normal pointing into neighbor
int leaf; // neighbor
winding_t *winding;
vstatus_t status;
byte *visbits;
byte *mightsee;
int nummightsee;
int numcansee;
} portal_t;
typedef struct seperating_plane_s
{
struct seperating_plane_s *next;
plane_t plane; // from portal is on positive side
} sep_t;
typedef struct passage_s
{
struct passage_s *next;
int from, to; // leaf numbers
sep_t *planes;
} passage_t;
#define MAX_PORTALS_ON_LEAF 256
typedef struct leaf_s
{
int numportals;
passage_t *passages;
portal_t *portals[MAX_PORTALS_ON_LEAF];
} leaf_t;
typedef struct pstack_s
{
byte mightsee[MAX_MAP_LEAFS/8]; // bit string
struct pstack_s *next;
leaf_t *leaf;
portal_t *portal; // portal exiting
winding_t *source;
winding_t *pass;
winding_t windings[3]; // source, pass, temp in any order
int freewindings[3];
plane_t portalplane;
} pstack_t;
typedef struct
{
byte *leafvis; // bit string
// byte fullportal[MAX_PORTALS/8]; // bit string
portal_t *base;
pstack_t pstack_head;
} threaddata_t;
#ifdef __alpha
#include <pthread.h>
extern pthread_mutex_t *my_mutex;
#define LOCK pthread_mutex_lock (my_mutex)
#define UNLOCK pthread_mutex_unlock (my_mutex)
#else
#define LOCK
#define UNLOCK
#endif
extern int numportals;
extern int portalleafs;
extern portal_t *portals;
extern leaf_t *leafs;
extern int c_portaltest, c_portalpass, c_portalcheck;
extern int c_portalskip, c_leafskip;
extern int c_vistest, c_mighttest;
extern int c_chains;
extern byte *vismap, *vismap_p, *vismap_end; // past visfile
extern qboolean showgetleaf;
extern byte *uncompressed;
extern int bitbytes;
extern int bitlongs;
void LeafFlow (int leafnum);
void BasePortalVis (int threadnum);
void PortalFlow (portal_t *p);
void CalcAmbientSounds (void);