mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
rewrite q3map2 math in c++
This commit is contained in:
@@ -540,7 +540,6 @@ $(INSTALLDIR)/q3map2.$(EXE): \
|
||||
tools/quake3/common/miniz.o \
|
||||
tools/quake3/q3map2/autopk3.o \
|
||||
tools/quake3/q3map2/brush.o \
|
||||
tools/quake3/q3map2/brush_primit.o \
|
||||
tools/quake3/q3map2/bspfile_abstract.o \
|
||||
tools/quake3/q3map2/bspfile_ibsp.o \
|
||||
tools/quake3/q3map2/bspfile_rbsp.o \
|
||||
|
||||
+2
-1
@@ -26,7 +26,8 @@
|
||||
|
||||
template<typename Element> class BasicVector3;
|
||||
typedef BasicVector3<float> Vector3;
|
||||
class Plane3;
|
||||
template<typename T> class Plane3___;
|
||||
typedef Plane3___<double> Plane3;
|
||||
class Matrix4;
|
||||
class AABB;
|
||||
class Segment;
|
||||
|
||||
@@ -281,7 +281,8 @@ inline SelectionTestable* Instance_getSelectionTestable( scene::Instance& instan
|
||||
}
|
||||
|
||||
|
||||
class Plane3;
|
||||
template<typename T> class Plane3___;
|
||||
typedef Plane3___<double> Plane3;
|
||||
typedef Callback1<const Plane3&> PlaneCallback;
|
||||
|
||||
class SelectedPlanes
|
||||
|
||||
@@ -103,6 +103,11 @@ Element* data(){
|
||||
const Element* data() const {
|
||||
return m_elements;
|
||||
}
|
||||
|
||||
BasicVector3& set( const Element value ){
|
||||
x() = y() = z() = value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A 4-element vector.
|
||||
@@ -171,8 +176,25 @@ Element* data(){
|
||||
const Element* data() const {
|
||||
return m_elements;
|
||||
}
|
||||
|
||||
BasicVector3<Element>& vec3(){
|
||||
return reinterpret_cast<BasicVector3<Element>&>( x() );
|
||||
}
|
||||
const BasicVector3<Element>& vec3() const {
|
||||
return reinterpret_cast<const BasicVector3<Element>&>( x() );
|
||||
}
|
||||
|
||||
BasicVector4& set( const Element value ){
|
||||
x() = y() = z() = w() = value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Element>
|
||||
inline BasicVector2<Element> vector2_from_array( const Element* array ){
|
||||
return BasicVector2<Element>( array[0], array[1] );
|
||||
}
|
||||
|
||||
template<typename Element>
|
||||
inline BasicVector3<Element> vector3_from_array( const Element* array ){
|
||||
return BasicVector3<Element>( array[0], array[1], array[2] );
|
||||
|
||||
+25
-19
@@ -27,36 +27,41 @@
|
||||
|
||||
#include "math/matrix.h"
|
||||
|
||||
/// \brief A plane equation stored in double-precision floating-point.
|
||||
class Plane3
|
||||
template<typename T>
|
||||
class Plane3___
|
||||
{
|
||||
public:
|
||||
double a, b, c, d;
|
||||
T a, b, c, d;
|
||||
|
||||
Plane3(){
|
||||
Plane3___(){
|
||||
}
|
||||
Plane3( double _a, double _b, double _c, double _d )
|
||||
Plane3___( double _a, double _b, double _c, double _d )
|
||||
: a( _a ), b( _b ), c( _c ), d( _d ){
|
||||
}
|
||||
template<typename Element>
|
||||
Plane3( const BasicVector3<Element>& normal, double dist )
|
||||
Plane3___( const BasicVector3<Element>& normal, double dist )
|
||||
: a( normal.x() ), b( normal.y() ), c( normal.z() ), d( dist ){
|
||||
}
|
||||
|
||||
BasicVector3<double>& normal(){
|
||||
return reinterpret_cast<BasicVector3<double>&>( *this );
|
||||
BasicVector3<T>& normal(){
|
||||
return reinterpret_cast<BasicVector3<T>&>( *this );
|
||||
}
|
||||
const BasicVector3<double>& normal() const {
|
||||
return reinterpret_cast<const BasicVector3<double>&>( *this );
|
||||
const BasicVector3<T>& normal() const {
|
||||
return reinterpret_cast<const BasicVector3<T>&>( *this );
|
||||
}
|
||||
double& dist(){
|
||||
T& dist(){
|
||||
return d;
|
||||
}
|
||||
const double& dist() const {
|
||||
const T& dist() const {
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A plane equation stored in double-precision floating-point.
|
||||
using Plane3 = Plane3___<double>;
|
||||
/// \brief A plane equation stored in single-precision floating-point.
|
||||
using Plane3f = Plane3___<float>;
|
||||
|
||||
inline Plane3 plane3_normalised( const Plane3& plane ){
|
||||
double rmagnitude = 1.0 / sqrt( plane.a * plane.a + plane.b * plane.b + plane.c * plane.c );
|
||||
return Plane3(
|
||||
@@ -105,8 +110,9 @@ inline Plane3 plane3_transformed_affine_full( const Plane3& plane, const Matrix4
|
||||
return Plane3( normal, vector3_dot( normal, anchor ) );
|
||||
}
|
||||
|
||||
inline Plane3 plane3_flipped( const Plane3& plane ){
|
||||
return Plane3( vector3_negated( plane.normal() ), -plane.dist() );
|
||||
template<typename T>
|
||||
inline Plane3___<T> plane3_flipped( const Plane3___<T>& plane ){
|
||||
return Plane3___<T>( vector3_negated( plane.normal() ), -plane.dist() );
|
||||
}
|
||||
|
||||
const double c_PLANE_NORMAL_EPSILON = 0.0001f;
|
||||
@@ -148,8 +154,8 @@ inline Plane3 plane3_for_points( const BasicVector3<Element> planepts[3] ){
|
||||
return plane3_for_points( planepts[0], planepts[1], planepts[2] );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline double plane3_distance_to_point( const Plane3& plane, const BasicVector3<T>& point ){
|
||||
template<typename P, typename V>
|
||||
inline double plane3_distance_to_point( const Plane3___<P>& plane, const BasicVector3<V>& point ){
|
||||
return vector3_dot( point, plane.normal() ) - plane.dist();
|
||||
}
|
||||
|
||||
@@ -160,9 +166,9 @@ inline BasicVector3<T> plane3_project_point( const Plane3& plane, const BasicVec
|
||||
return point + direction * d;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline BasicVector3<T> plane3_project_point( const Plane3& plane, const BasicVector3<T>& point ){
|
||||
return ( point - plane.normal() * vector3_dot( point, plane.normal() ) + plane.normal() * plane.dist() );
|
||||
template<typename P, typename V>
|
||||
inline BasicVector3<V> plane3_project_point( const Plane3___<P>& plane, const BasicVector3<V>& point ){
|
||||
return point - plane.normal() * plane3_distance_to_point( plane, point );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+10
-17
@@ -289,19 +289,18 @@ inline void vector2_normalise( BasicVector2<Element>& self ){
|
||||
self = vector2_normalised( self );
|
||||
}
|
||||
|
||||
template<typename Element>
|
||||
inline BasicVector2<Element> vector2_mid( const BasicVector2<Element>& begin, const BasicVector2<Element>& end ){
|
||||
return vector2_scaled( vector2_added( begin, end ), 0.5 );
|
||||
}
|
||||
|
||||
const Vector3 g_vector3_identity( 0, 0, 0 );
|
||||
const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
const Vector3 g_vector3_axis_x( 1, 0, 0 );
|
||||
const Vector3 g_vector3_axis_y( 0, 1, 0 );
|
||||
const Vector3 g_vector3_axis_z( 0, 0, 1 );
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define VARIABLE_IS_NOT_USED __attribute__ ((unused))
|
||||
#else
|
||||
#define VARIABLE_IS_NOT_USED
|
||||
#endif
|
||||
|
||||
const Vector3 VARIABLE_IS_NOT_USED g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
|
||||
const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
|
||||
|
||||
template<typename Element, typename OtherElement>
|
||||
inline void vector3_swap( BasicVector3<Element>& self, BasicVector3<OtherElement>& other ){
|
||||
@@ -560,20 +559,14 @@ inline Vector3 vector3_for_spherical( double theta, double phi ){
|
||||
|
||||
template<typename Element>
|
||||
inline std::size_t vector3_max_abs_component_index( const BasicVector3<Element>& self ){
|
||||
std::size_t maxi = 0;
|
||||
for( std::size_t i = 1; i < 3; ++i )
|
||||
if( fabs( self[i] ) > fabs( self[maxi] ) )
|
||||
maxi = i;
|
||||
return maxi;
|
||||
const std::size_t maxi = ( fabs( self[1] ) > fabs( self[0] ) )? 1 : 0;
|
||||
return ( fabs( self[2] ) > fabs( self[maxi] ) )? 2 : maxi;;
|
||||
}
|
||||
|
||||
template<typename Element>
|
||||
inline std::size_t vector3_min_abs_component_index( const BasicVector3<Element>& self ){
|
||||
std::size_t mini = 0;
|
||||
for( std::size_t i = 1; i < 3; ++i )
|
||||
if( fabs( self[i] ) < fabs( self[mini] ) )
|
||||
mini = i;
|
||||
return mini;
|
||||
const std::size_t mini = ( fabs( self[1] ) < fabs( self[0] ) )? 1 : 0;
|
||||
return ( fabs( self[2] ) < fabs( self[mini] ) )? 2 : mini;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +90,8 @@ float Texdef_getDefaultTextureScale();
|
||||
class texdef_t;
|
||||
struct Winding;
|
||||
class Matrix4;
|
||||
class Plane3;
|
||||
template<typename T> class Plane3___;
|
||||
typedef Plane3___<double> Plane3;
|
||||
|
||||
void Normal_GetTransform( const Vector3& normal, Matrix4& transform );
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
// replaced qprintf with Sys_Printf
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "inout.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "inout.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "generic/vector.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
@@ -56,7 +57,7 @@ xmlDocPtr doc;
|
||||
xmlNodePtr tree;
|
||||
|
||||
// some useful stuff
|
||||
xmlNodePtr xml_NodeForVec( vec3_t v ){
|
||||
xmlNodePtr xml_NodeForVec( const Vector3& v ){
|
||||
xmlNodePtr ret;
|
||||
char buf[1024];
|
||||
|
||||
@@ -166,7 +167,7 @@ void xml_Select( const char *msg, int entitynum, int brushnum, bool bError ){
|
||||
}
|
||||
}
|
||||
|
||||
void xml_Point( const char *msg, vec3_t pt ){
|
||||
void xml_Point( const char *msg, const Vector3& pt ){
|
||||
xmlNodePtr node, point;
|
||||
char buf[1024];
|
||||
char level[2];
|
||||
@@ -188,7 +189,7 @@ void xml_Point( const char *msg, vec3_t pt ){
|
||||
}
|
||||
|
||||
#define WINDING_BUFSIZE 2048
|
||||
void xml_Winding( const char *msg, vec3_t p[], int numpoints, bool die ){
|
||||
void xml_Winding( const char *msg, const Vector3 p[], int numpoints, bool die ){
|
||||
xmlNodePtr node, winding;
|
||||
char buf[WINDING_BUFSIZE];
|
||||
char smlbuf[128];
|
||||
|
||||
@@ -24,18 +24,20 @@
|
||||
|
||||
// inout is the only stuff relying on xml, include the headers there
|
||||
#include "libxml/tree.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
template<typename Element> class BasicVector3;
|
||||
typedef BasicVector3<float> Vector3;
|
||||
|
||||
// some useful xml routines
|
||||
xmlNodePtr xml_NodeForVec( vec3_t v );
|
||||
xmlNodePtr xml_NodeForVec( const Vector3& v );
|
||||
void xml_SendNode( xmlNodePtr node );
|
||||
// print a message in q3map output and send the corresponding select information down the xml stream
|
||||
// bError: do we end with an error on this one or do we go ahead?
|
||||
void xml_Select( const char *msg, int entitynum, int brushnum, bool bError );
|
||||
// end q3map with an error message and send a point information in the xml stream
|
||||
// note: we might want to add a boolean to use this as a warning or an error thing..
|
||||
void xml_Winding( const char *msg, vec3_t p[], int numpoints, bool die );
|
||||
void xml_Point( const char *msg, vec3_t pt );
|
||||
void xml_Winding( const char *msg, const Vector3 p[], int numpoints, bool die );
|
||||
void xml_Point( const char *msg, const Vector3& pt );
|
||||
|
||||
void Broadcast_Setup( const char *dest );
|
||||
void Broadcast_Shutdown();
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define MIN_WORLD_COORD ( -65536 )
|
||||
#define MAX_WORLD_COORD ( 65536 )
|
||||
#define WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD )
|
||||
+183
-251
@@ -23,11 +23,9 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "inout.h"
|
||||
#include "polylib.h"
|
||||
#include "qfiles.h"
|
||||
|
||||
#include "maxworld.h"
|
||||
|
||||
#define BOGUS_RANGE WORLD_SIZE
|
||||
|
||||
@@ -105,21 +103,16 @@ void FreeWindingAccu( winding_accu_t *w ){
|
||||
*/
|
||||
void RemoveColinearPoints( winding_t *w ){
|
||||
int i, j, k;
|
||||
vec3_t v1, v2;
|
||||
int nump;
|
||||
vec3_t p[MAX_POINTS_ON_WINDING];
|
||||
Vector3 p[MAX_POINTS_ON_WINDING];
|
||||
|
||||
nump = 0;
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
j = ( i + 1 ) % w->numpoints;
|
||||
k = ( i + w->numpoints - 1 ) % w->numpoints;
|
||||
VectorSubtract( w->p[j], w->p[i], v1 );
|
||||
VectorSubtract( w->p[i], w->p[k], v2 );
|
||||
VectorNormalize( v1,v1 );
|
||||
VectorNormalize( v2,v2 );
|
||||
if ( DotProduct( v1, v2 ) < 0.999 ) {
|
||||
VectorCopy( w->p[i], p[nump] );
|
||||
if ( vector3_dot( VectorNormalized( w->p[j] - w->p[i] ), VectorNormalized( w->p[j] - w->p[k] ) ) < 0.999 ) {
|
||||
p[nump] = w->p[i];
|
||||
nump++;
|
||||
}
|
||||
}
|
||||
@@ -137,15 +130,10 @@ void RemoveColinearPoints( winding_t *w ){
|
||||
WindingPlane
|
||||
============
|
||||
*/
|
||||
void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ){
|
||||
vec3_t v1, v2;
|
||||
|
||||
VectorSubtract( w->p[1], w->p[0], v1 );
|
||||
VectorSubtract( w->p[2], w->p[0], v2 );
|
||||
CrossProduct( v2, v1, normal );
|
||||
VectorNormalize( normal, normal );
|
||||
*dist = DotProduct( w->p[0], normal );
|
||||
|
||||
Plane3f WindingPlane( const winding_t *w ){
|
||||
Plane3f plane;
|
||||
PlaneFromPoints( plane, w->p[0], w->p[1], w->p[2] );
|
||||
return plane;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -153,42 +141,23 @@ void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ){
|
||||
WindingArea
|
||||
=============
|
||||
*/
|
||||
vec_t WindingArea( winding_t *w ){
|
||||
int i;
|
||||
vec3_t d1, d2, cross;
|
||||
vec_t total;
|
||||
float WindingArea( const winding_t *w ){
|
||||
float total = 0;
|
||||
|
||||
total = 0;
|
||||
for ( i = 2 ; i < w->numpoints ; i++ )
|
||||
for ( int i = 2 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
VectorSubtract( w->p[i - 1], w->p[0], d1 );
|
||||
VectorSubtract( w->p[i], w->p[0], d2 );
|
||||
CrossProduct( d1, d2, cross );
|
||||
total += 0.5 * VectorLength( cross );
|
||||
total += 0.5 * vector3_length( vector3_cross( w->p[i - 1] - w->p[0], w->p[i] - w->p[0] ) );
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ){
|
||||
vec_t v;
|
||||
int i,j;
|
||||
|
||||
mins[0] = mins[1] = mins[2] = 99999;
|
||||
maxs[0] = maxs[1] = maxs[2] = -99999;
|
||||
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
MinMax WindingBounds( const winding_t *w ){
|
||||
MinMax minmax;
|
||||
for ( int i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
{
|
||||
v = w->p[i][j];
|
||||
if ( v < mins[j] ) {
|
||||
mins[j] = v;
|
||||
}
|
||||
if ( v > maxs[j] ) {
|
||||
maxs[j] = v;
|
||||
}
|
||||
}
|
||||
minmax.extend( w->p[i] );
|
||||
}
|
||||
return minmax;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -196,16 +165,13 @@ void WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ){
|
||||
WindingCenter
|
||||
=============
|
||||
*/
|
||||
void WindingCenter( winding_t *w, vec3_t center ){
|
||||
int i;
|
||||
float scale;
|
||||
Vector3 WindingCenter( const winding_t *w ){
|
||||
Vector3 center( 0, 0, 0 );
|
||||
|
||||
VectorCopy( vec3_origin, center );
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
VectorAdd( w->p[i], center, center );
|
||||
|
||||
scale = 1.0 / w->numpoints;
|
||||
VectorScale( center, scale, center );
|
||||
for ( int i = 0 ; i < w->numpoints ; i++ )
|
||||
center += w->p[i];
|
||||
|
||||
return center / w->numpoints;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -213,7 +179,7 @@ void WindingCenter( winding_t *w, vec3_t center ){
|
||||
BaseWindingForPlaneAccu
|
||||
=================
|
||||
*/
|
||||
winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& inplane ){
|
||||
// The goal in this function is to replicate the behavior of the original BaseWindingForPlane()
|
||||
// function (see below) but at the same time increasing accuracy substantially.
|
||||
|
||||
@@ -228,8 +194,9 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
// of 2) than the winding polygon in the original function.
|
||||
|
||||
int x, i;
|
||||
vec_t max, v;
|
||||
vec3_accu_t vright, vup, org, normalAccu;
|
||||
float max, v;
|
||||
DoubleVector3 vright, vup, org;
|
||||
const Plane3 plane( inplane.normal(), inplane.dist() );
|
||||
winding_accu_t *w;
|
||||
|
||||
// One of the components of normal must have a magnitiude greater than this value,
|
||||
@@ -239,7 +206,7 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
|
||||
x = -1;
|
||||
for ( i = 0; i < 3; i++ ) {
|
||||
v = (vec_t) fabs( normal[i] );
|
||||
v = fabs( plane.normal()[i] );
|
||||
if ( v > max ) {
|
||||
x = i;
|
||||
max = v;
|
||||
@@ -252,14 +219,14 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
switch ( x ) {
|
||||
case 0: // Fall through to next case.
|
||||
case 1:
|
||||
vright[0] = (vec_accu_t) -normal[1];
|
||||
vright[1] = (vec_accu_t) normal[0];
|
||||
vright[0] = -plane.normal()[1];
|
||||
vright[1] = plane.normal()[0];
|
||||
vright[2] = 0;
|
||||
break;
|
||||
case 2:
|
||||
vright[0] = 0;
|
||||
vright[1] = (vec_accu_t) -normal[2];
|
||||
vright[2] = (vec_accu_t) normal[1];
|
||||
vright[1] = -plane.normal()[2];
|
||||
vright[2] = plane.normal()[1];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -276,19 +243,18 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
// We're relying on the fact that MAX_WORLD_COORD is a power of 2 to keep
|
||||
// our calculation precise and relatively free of floating point error.
|
||||
// [However, the code will still work fine if that's not the case.]
|
||||
VectorScaleAccu( vright, ( (vec_accu_t) MAX_WORLD_COORD ) * 4.0, vright );
|
||||
vright *= ( (double) MAX_WORLD_COORD ) * 4.0;
|
||||
|
||||
// At time time of this writing, MAX_WORLD_COORD was 65536 (2^16). Therefore
|
||||
// the length of vright at this point is at least 185364. In comparison, a
|
||||
// corner of the world at location (65536, 65536, 65536) is distance 113512
|
||||
// away from the origin.
|
||||
|
||||
VectorCopyRegularToAccu( normal, normalAccu );
|
||||
CrossProductAccu( normalAccu, vright, vup );
|
||||
vup = vector3_cross( plane.normal(), vright );
|
||||
|
||||
// vup now has length equal to that of vright.
|
||||
|
||||
VectorScaleAccu( normalAccu, (vec_accu_t) dist, org );
|
||||
org = plane.normal() * plane.dist();
|
||||
|
||||
// org is now a point on the plane defined by normal and dist. Furthermore,
|
||||
// org, vright, and vup are pairwise perpendicular. Now, the 4 vectors
|
||||
@@ -304,17 +270,10 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
|
||||
w = AllocWindingAccu( 4 );
|
||||
|
||||
VectorSubtractAccu( org, vright, w->p[0] );
|
||||
VectorAddAccu( w->p[0], vup, w->p[0] );
|
||||
|
||||
VectorAddAccu( org, vright, w->p[1] );
|
||||
VectorAddAccu( w->p[1], vup, w->p[1] );
|
||||
|
||||
VectorAddAccu( org, vright, w->p[2] );
|
||||
VectorSubtractAccu( w->p[2], vup, w->p[2] );
|
||||
|
||||
VectorSubtractAccu( org, vright, w->p[3] );
|
||||
VectorSubtractAccu( w->p[3], vup, w->p[3] );
|
||||
w->p[0] = org - vright + vup;
|
||||
w->p[1] = org + vright + vup;
|
||||
w->p[2] = org + vright - vup;
|
||||
w->p[3] = org - vright - vup;
|
||||
|
||||
w->numpoints = 4;
|
||||
|
||||
@@ -336,10 +295,10 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){
|
||||
error, and can lead to all sorts of disappearing triangle problems.
|
||||
=================
|
||||
*/
|
||||
winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){
|
||||
winding_t *BaseWindingForPlane( const Plane3f& plane ){
|
||||
int i, x;
|
||||
vec_t max, v;
|
||||
vec3_t org, vright, vup;
|
||||
float max, v;
|
||||
Vector3 org, vright, vup;
|
||||
winding_t *w;
|
||||
|
||||
// find the major axis
|
||||
@@ -348,7 +307,7 @@ winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){
|
||||
x = -1;
|
||||
for ( i = 0 ; i < 3; i++ )
|
||||
{
|
||||
v = fabs( normal[i] );
|
||||
v = fabs( plane.normal()[i] );
|
||||
if ( v > max ) {
|
||||
x = i;
|
||||
max = v;
|
||||
@@ -358,7 +317,7 @@ winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){
|
||||
Error( "BaseWindingForPlane: no axis found" );
|
||||
}
|
||||
|
||||
VectorCopy( vec3_origin, vup );
|
||||
vup.set( 0 );
|
||||
switch ( x )
|
||||
{
|
||||
case 0:
|
||||
@@ -370,34 +329,26 @@ winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){
|
||||
break;
|
||||
}
|
||||
|
||||
v = DotProduct( vup, normal );
|
||||
VectorMA( vup, -v, normal, vup );
|
||||
VectorNormalize( vup, vup );
|
||||
vup -= plane.normal() * vector3_dot( vup, plane.normal() );
|
||||
VectorNormalize( vup );
|
||||
|
||||
VectorScale( normal, dist, org );
|
||||
org = plane.normal() * plane.dist();
|
||||
|
||||
CrossProduct( vup, normal, vright );
|
||||
vright = vector3_cross( vup, plane.normal() );
|
||||
|
||||
// LordHavoc: this has to use *2 because otherwise some created points may
|
||||
// be inside the world (think of a diagonal case), and any brush with such
|
||||
// points should be removed, failure to detect such cases is disasterous
|
||||
VectorScale( vup, MAX_WORLD_COORD * 2, vup );
|
||||
VectorScale( vright, MAX_WORLD_COORD * 2, vright );
|
||||
vup *= MAX_WORLD_COORD * 2;
|
||||
vright *= MAX_WORLD_COORD * 2;
|
||||
|
||||
// project a really big axis aligned box onto the plane
|
||||
w = AllocWinding( 4 );
|
||||
|
||||
VectorSubtract( org, vright, w->p[0] );
|
||||
VectorAdd( w->p[0], vup, w->p[0] );
|
||||
|
||||
VectorAdd( org, vright, w->p[1] );
|
||||
VectorAdd( w->p[1], vup, w->p[1] );
|
||||
|
||||
VectorAdd( org, vright, w->p[2] );
|
||||
VectorSubtract( w->p[2], vup, w->p[2] );
|
||||
|
||||
VectorSubtract( org, vright, w->p[3] );
|
||||
VectorSubtract( w->p[3], vup, w->p[3] );
|
||||
w->p[0] = org - vright + vup;
|
||||
w->p[1] = org + vright + vup;
|
||||
w->p[2] = org + vright - vup;
|
||||
w->p[3] = org - vright - vup;
|
||||
|
||||
w->numpoints = 4;
|
||||
|
||||
@@ -448,7 +399,7 @@ winding_t *CopyWindingAccuToRegular( const winding_accu_t *w ){
|
||||
c->numpoints = w->numpoints;
|
||||
for ( i = 0; i < c->numpoints; i++ )
|
||||
{
|
||||
VectorCopyAccuToRegular( w->p[i], c->p[i] );
|
||||
c->p[i] = w->p[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@@ -458,14 +409,14 @@ winding_t *CopyWindingAccuToRegular( const winding_accu_t *w ){
|
||||
ReverseWinding
|
||||
==================
|
||||
*/
|
||||
winding_t *ReverseWinding( winding_t *w ){
|
||||
winding_t *ReverseWinding( const winding_t *w ){
|
||||
int i;
|
||||
winding_t *c;
|
||||
|
||||
c = AllocWinding( w->numpoints );
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
VectorCopy( w->p[w->numpoints - 1 - i], c->p[i] );
|
||||
c->p[i] = w->p[w->numpoints - 1 - i];
|
||||
}
|
||||
c->numpoints = w->numpoints;
|
||||
return c;
|
||||
@@ -477,15 +428,12 @@ winding_t *ReverseWinding( winding_t *w ){
|
||||
ClipWindingEpsilon
|
||||
=============
|
||||
*/
|
||||
void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back ){
|
||||
vec_t dists[MAX_POINTS_ON_WINDING + 4];
|
||||
int sides[MAX_POINTS_ON_WINDING + 4];
|
||||
void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane,
|
||||
float epsilon, winding_t **front, winding_t **back ){
|
||||
float dists[MAX_POINTS_ON_WINDING + 4];
|
||||
EPlaneSide sides[MAX_POINTS_ON_WINDING + 4];
|
||||
int counts[3];
|
||||
static vec_t dot; // VC 4.2 optimizer bug if not static
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec3_t mid;
|
||||
winding_t *f, *b;
|
||||
int maxpts;
|
||||
|
||||
@@ -495,18 +443,16 @@ void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist,
|
||||
for ( i = 0 ; i < in->numpoints ; i++ )
|
||||
{
|
||||
|
||||
dot = DotProduct( in->p[i], normal );
|
||||
dot -= dist;
|
||||
dists[i] = dot;
|
||||
if ( dot > epsilon ) {
|
||||
sides[i] = SIDE_FRONT;
|
||||
dists[i] = plane3_distance_to_point( plane, in->p[i] );
|
||||
if ( dists[i] > epsilon ) {
|
||||
sides[i] = eSideFront;
|
||||
}
|
||||
else if ( dot < -epsilon ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
else if ( dists[i] < -epsilon ) {
|
||||
sides[i] = eSideBack;
|
||||
}
|
||||
else
|
||||
{
|
||||
sides[i] = SIDE_ON;
|
||||
sides[i] = eSideOn;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
@@ -535,49 +481,49 @@ void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist,
|
||||
|
||||
for ( i = 0 ; i < in->numpoints ; i++ )
|
||||
{
|
||||
p1 = in->p[i];
|
||||
const Vector3& p1 = in->p[i];
|
||||
|
||||
if ( sides[i] == SIDE_ON ) {
|
||||
VectorCopy( p1, f->p[f->numpoints] );
|
||||
if ( sides[i] == eSideOn ) {
|
||||
f->p[f->numpoints] = p1;
|
||||
f->numpoints++;
|
||||
VectorCopy( p1, b->p[b->numpoints] );
|
||||
b->p[b->numpoints] = p1;
|
||||
b->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_FRONT ) {
|
||||
VectorCopy( p1, f->p[f->numpoints] );
|
||||
if ( sides[i] == eSideFront ) {
|
||||
f->p[f->numpoints] = p1;
|
||||
f->numpoints++;
|
||||
}
|
||||
if ( sides[i] == SIDE_BACK ) {
|
||||
VectorCopy( p1, b->p[b->numpoints] );
|
||||
if ( sides[i] == eSideBack ) {
|
||||
b->p[b->numpoints] = p1;
|
||||
b->numpoints++;
|
||||
}
|
||||
|
||||
if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
|
||||
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// generate a split point
|
||||
p2 = in->p[( i + 1 ) % in->numpoints];
|
||||
|
||||
dot = dists[i] / ( dists[i] - dists[i + 1] );
|
||||
const Vector3& p2 = in->p[( i + 1 ) % in->numpoints];
|
||||
const double dot = dists[i] / ( dists[i] - dists[i + 1] );
|
||||
Vector3 mid;
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
{ // avoid round off error when possible
|
||||
if ( normal[j] == 1 ) {
|
||||
mid[j] = dist;
|
||||
if ( plane.normal()[j] == 1 ) {
|
||||
mid[j] = plane.dist();
|
||||
}
|
||||
else if ( normal[j] == -1 ) {
|
||||
mid[j] = -dist;
|
||||
else if ( plane.normal()[j] == -1 ) {
|
||||
mid[j] = -plane.dist();
|
||||
}
|
||||
else{
|
||||
mid[j] = p1[j] + dot * ( p2[j] - p1[j] );
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy( mid, f->p[f->numpoints] );
|
||||
f->p[f->numpoints] = mid;
|
||||
f->numpoints++;
|
||||
VectorCopy( mid, b->p[b->numpoints] );
|
||||
b->p[b->numpoints] = mid;
|
||||
b->numpoints++;
|
||||
}
|
||||
|
||||
@@ -589,9 +535,9 @@ void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist,
|
||||
}
|
||||
}
|
||||
|
||||
void ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back ){
|
||||
ClipWindingEpsilonStrict( in, normal, dist, epsilon, front, back );
|
||||
void ClipWindingEpsilon( winding_t *in, const Plane3f& plane,
|
||||
float epsilon, winding_t **front, winding_t **back ){
|
||||
ClipWindingEpsilonStrict( in, plane, epsilon, front, back );
|
||||
/* apparently most code expects that in the winding-on-plane case, the back winding is the original winding */
|
||||
if ( !*front && !*back ) {
|
||||
*back = CopyWinding( in );
|
||||
@@ -599,22 +545,26 @@ void ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
|
||||
}
|
||||
|
||||
|
||||
// Smallest positive value for vec_t such that 1.0 + VEC_SMALLEST_EPSILON_AROUND_ONE != 1.0.
|
||||
// In the case of 32 bit floats (which is almost certainly the case), it's 0.00000011921.
|
||||
// Don't forget that your epsilons should depend on the possible range of values,
|
||||
// because for example adding VEC_SMALLEST_EPSILON_AROUND_ONE to 1024.0 will have no effect.
|
||||
#define VEC_SMALLEST_EPSILON_AROUND_ONE FLT_EPSILON
|
||||
|
||||
/*
|
||||
=============
|
||||
ChopWindingInPlaceAccu
|
||||
=============
|
||||
*/
|
||||
void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, vec_t crudeEpsilon ){
|
||||
void ChopWindingInPlaceAccu( winding_accu_t **inout, const Plane3f& plane, float crudeEpsilon ){
|
||||
winding_accu_t *in;
|
||||
int counts[3];
|
||||
int i, j;
|
||||
vec_accu_t dists[MAX_POINTS_ON_WINDING + 1];
|
||||
int sides[MAX_POINTS_ON_WINDING + 1];
|
||||
double dists[MAX_POINTS_ON_WINDING + 1];
|
||||
EPlaneSide sides[MAX_POINTS_ON_WINDING + 1];
|
||||
int maxpts;
|
||||
winding_accu_t *f;
|
||||
vec_accu_t *p1, *p2;
|
||||
vec_accu_t w;
|
||||
vec3_accu_t mid, normalAccu;
|
||||
double w;
|
||||
|
||||
// We require at least a very small epsilon. It's a good idea for several reasons.
|
||||
// First, we will be dividing by a potentially very small distance below. We don't
|
||||
@@ -634,12 +584,12 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist,
|
||||
// So this minimum epsilon is quite similar to casting the higher resolution numbers to
|
||||
// the lower resolution and comparing them in the lower resolution mode. We explicitly
|
||||
// choose the minimum epsilon as something around the vec_t epsilon of one because we
|
||||
// want the resolution of vec_accu_t to have a large resolution around the epsilon.
|
||||
// want the resolution of double to have a large resolution around the epsilon.
|
||||
// Some of that leftover resolution even goes away after we scale to points far away.
|
||||
|
||||
// Here is a further discussion regarding the choice of smallestEpsilonAllowed.
|
||||
// In the 32 float world (we can assume vec_t is that), the "epsilon around 1.0" is
|
||||
// 0.00000011921. In the 64 bit float world (we can assume vec_accu_t is that), the
|
||||
// 0.00000011921. In the 64 bit float world (we can assume double is that), the
|
||||
// "epsilon around 1.0" is 0.00000000000000022204. (By the way these two epsilons
|
||||
// are defined as VEC_SMALLEST_EPSILON_AROUND_ONE VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE
|
||||
// respectively.) If you divide the first by the second, you get approximately
|
||||
@@ -648,23 +598,24 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist,
|
||||
// VEC_SMALLEST_EPSILON_AROUND_ONE, you would be guaranteed at least 2000 "ticks" in
|
||||
// 64-bit land inside of the epsilon for all numbers we're dealing with.
|
||||
|
||||
static const vec_accu_t smallestEpsilonAllowed = ( (vec_accu_t) VEC_SMALLEST_EPSILON_AROUND_ONE ) * 0.5;
|
||||
const vec_accu_t fineEpsilon = ( crudeEpsilon < smallestEpsilonAllowed )? smallestEpsilonAllowed : (vec_accu_t) crudeEpsilon;
|
||||
static const double smallestEpsilonAllowed = ( (double) VEC_SMALLEST_EPSILON_AROUND_ONE ) * 0.5;
|
||||
const double fineEpsilon = ( crudeEpsilon < smallestEpsilonAllowed )? smallestEpsilonAllowed : (double) crudeEpsilon;
|
||||
|
||||
in = *inout;
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
VectorCopyRegularToAccu( normal, normalAccu );
|
||||
|
||||
for ( i = 0; i < in->numpoints; i++ )
|
||||
{
|
||||
dists[i] = DotProductAccu( in->p[i], normalAccu ) - dist;
|
||||
dists[i] = plane3_distance_to_point( plane, in->p[i] );
|
||||
if ( dists[i] > fineEpsilon ) {
|
||||
sides[i] = SIDE_FRONT;
|
||||
sides[i] = eSideFront;
|
||||
}
|
||||
else if ( dists[i] < -fineEpsilon ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
sides[i] = eSideBack;
|
||||
}
|
||||
else{
|
||||
sides[i] = eSideOn;
|
||||
}
|
||||
else{sides[i] = SIDE_ON; }
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
sides[i] = sides[0];
|
||||
@@ -673,26 +624,26 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist,
|
||||
// I'm wondering if whatever code that handles duplicate planes is robust enough
|
||||
// that we never get a case where two nearly equal planes result in 2 NULL windings
|
||||
// due to the 'if' statement below. TODO: Investigate this.
|
||||
if ( !counts[SIDE_FRONT] ) {
|
||||
if ( !counts[eSideFront] ) {
|
||||
FreeWindingAccu( in );
|
||||
*inout = NULL;
|
||||
return;
|
||||
}
|
||||
if ( !counts[SIDE_BACK] ) {
|
||||
if ( !counts[eSideBack] ) {
|
||||
return; // Winding is unmodified.
|
||||
}
|
||||
|
||||
// NOTE: The least number of points that a winding can have at this point is 2.
|
||||
// In that case, one point is SIDE_FRONT and the other is SIDE_BACK.
|
||||
|
||||
maxpts = counts[SIDE_FRONT] + 2; // We dynamically expand if this is too small.
|
||||
maxpts = counts[eSideFront] + 2; // We dynamically expand if this is too small.
|
||||
f = AllocWindingAccu( maxpts );
|
||||
|
||||
for ( i = 0; i < in->numpoints; i++ )
|
||||
{
|
||||
p1 = in->p[i];
|
||||
const DoubleVector3& p1 = in->p[i];
|
||||
|
||||
if ( sides[i] == SIDE_ON || sides[i] == SIDE_FRONT ) {
|
||||
if ( sides[i] == eSideOn || sides[i] == eSideFront ) {
|
||||
if ( f->numpoints >= MAX_POINTS_ON_WINDING ) {
|
||||
Error( "ChopWindingInPlaceAccu: MAX_POINTS_ON_WINDING" );
|
||||
}
|
||||
@@ -701,31 +652,31 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist,
|
||||
f = CopyWindingAccuIncreaseSizeAndFreeOld( f );
|
||||
maxpts++;
|
||||
}
|
||||
VectorCopyAccu( p1, f->p[f->numpoints] );
|
||||
f->p[f->numpoints] = p1;
|
||||
f->numpoints++;
|
||||
if ( sides[i] == SIDE_ON ) {
|
||||
if ( sides[i] == eSideOn ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
|
||||
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate a split point.
|
||||
p2 = in->p[( ( i + 1 ) == in->numpoints ) ? 0 : ( i + 1 )];
|
||||
const DoubleVector3& p2 = in->p[( ( i + 1 ) == in->numpoints ) ? 0 : ( i + 1 )];
|
||||
|
||||
// The divisor's absolute value is greater than the dividend's absolute value.
|
||||
// w is in the range (0,1).
|
||||
w = dists[i] / ( dists[i] - dists[i + 1] );
|
||||
|
||||
DoubleVector3 mid;
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
// Avoid round-off error when possible. Check axis-aligned normal.
|
||||
if ( normal[j] == 1 ) {
|
||||
mid[j] = dist;
|
||||
if ( plane.normal()[j] == 1 ) {
|
||||
mid[j] = plane.dist();
|
||||
}
|
||||
else if ( normal[j] == -1 ) {
|
||||
mid[j] = -dist;
|
||||
else if ( plane.normal()[j] == -1 ) {
|
||||
mid[j] = -plane.dist();
|
||||
}
|
||||
else{mid[j] = p1[j] + ( w * ( p2[j] - p1[j] ) ); }
|
||||
}
|
||||
@@ -737,7 +688,7 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist,
|
||||
f = CopyWindingAccuIncreaseSizeAndFreeOld( f );
|
||||
maxpts++;
|
||||
}
|
||||
VectorCopyAccu( mid, f->p[f->numpoints] );
|
||||
f->p[f->numpoints] = mid;
|
||||
f->numpoints++;
|
||||
}
|
||||
|
||||
@@ -750,15 +701,12 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist,
|
||||
ChopWindingInPlace
|
||||
=============
|
||||
*/
|
||||
void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon ){
|
||||
void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon ){
|
||||
winding_t *in;
|
||||
vec_t dists[MAX_POINTS_ON_WINDING + 4];
|
||||
int sides[MAX_POINTS_ON_WINDING + 4];
|
||||
float dists[MAX_POINTS_ON_WINDING + 4];
|
||||
EPlaneSide sides[MAX_POINTS_ON_WINDING + 4];
|
||||
int counts[3];
|
||||
static vec_t dot; // VC 4.2 optimizer bug if not static
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec3_t mid;
|
||||
winding_t *f;
|
||||
int maxpts;
|
||||
|
||||
@@ -768,18 +716,16 @@ void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t eps
|
||||
// determine sides for each point
|
||||
for ( i = 0 ; i < in->numpoints ; i++ )
|
||||
{
|
||||
dot = DotProduct( in->p[i], normal );
|
||||
dot -= dist;
|
||||
dists[i] = dot;
|
||||
if ( dot > epsilon ) {
|
||||
sides[i] = SIDE_FRONT;
|
||||
dists[i] = plane3_distance_to_point( plane, in->p[i] );
|
||||
if ( dists[i] > epsilon ) {
|
||||
sides[i] = eSideFront;
|
||||
}
|
||||
else if ( dot < -epsilon ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
else if ( dists[i] < -epsilon ) {
|
||||
sides[i] = eSideBack;
|
||||
}
|
||||
else
|
||||
{
|
||||
sides[i] = SIDE_ON;
|
||||
sides[i] = eSideOn;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
@@ -802,41 +748,42 @@ void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t eps
|
||||
|
||||
for ( i = 0 ; i < in->numpoints ; i++ )
|
||||
{
|
||||
p1 = in->p[i];
|
||||
const Vector3& p1 = in->p[i];
|
||||
|
||||
if ( sides[i] == SIDE_ON ) {
|
||||
VectorCopy( p1, f->p[f->numpoints] );
|
||||
if ( sides[i] == eSideOn ) {
|
||||
f->p[f->numpoints] = p1;
|
||||
f->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_FRONT ) {
|
||||
VectorCopy( p1, f->p[f->numpoints] );
|
||||
if ( sides[i] == eSideFront ) {
|
||||
f->p[f->numpoints] = p1;
|
||||
f->numpoints++;
|
||||
}
|
||||
|
||||
if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
|
||||
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// generate a split point
|
||||
p2 = in->p[( i + 1 ) % in->numpoints];
|
||||
const Vector3& p2 = in->p[( i + 1 ) % in->numpoints];
|
||||
|
||||
dot = dists[i] / ( dists[i] - dists[i + 1] );
|
||||
const double dot = dists[i] / ( dists[i] - dists[i + 1] );
|
||||
Vector3 mid;
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
{ // avoid round off error when possible
|
||||
if ( normal[j] == 1 ) {
|
||||
mid[j] = dist;
|
||||
if ( plane.normal()[j] == 1 ) {
|
||||
mid[j] = plane.dist();
|
||||
}
|
||||
else if ( normal[j] == -1 ) {
|
||||
mid[j] = -dist;
|
||||
else if ( plane.normal()[j] == -1 ) {
|
||||
mid[j] = -plane.dist();
|
||||
}
|
||||
else{
|
||||
mid[j] = p1[j] + dot * ( p2[j] - p1[j] );
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy( mid, f->p[f->numpoints] );
|
||||
f->p[f->numpoints] = mid;
|
||||
f->numpoints++;
|
||||
}
|
||||
|
||||
@@ -860,10 +807,10 @@ void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t eps
|
||||
of the cliping plane. The original is freed.
|
||||
=================
|
||||
*/
|
||||
winding_t *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ){
|
||||
winding_t *ChopWinding( winding_t *in, const Plane3f& plane ){
|
||||
winding_t *f, *b;
|
||||
|
||||
ClipWindingEpsilon( in, normal, dist, ON_EPSILON, &f, &b );
|
||||
ClipWindingEpsilon( in, plane, ON_EPSILON, &f, &b );
|
||||
FreeWinding( in );
|
||||
if ( b ) {
|
||||
FreeWinding( b );
|
||||
@@ -880,11 +827,9 @@ winding_t *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ){
|
||||
*/
|
||||
void CheckWinding( winding_t *w ){
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec_t d, edgedist;
|
||||
vec3_t dir, edgenormal, facenormal;
|
||||
vec_t area;
|
||||
vec_t facedist;
|
||||
float d, edgedist;
|
||||
Vector3 dir, edgenormal;
|
||||
float area;
|
||||
|
||||
if ( w->numpoints < 3 ) {
|
||||
Error( "CheckWinding: %i points",w->numpoints );
|
||||
@@ -895,11 +840,11 @@ void CheckWinding( winding_t *w ){
|
||||
Error( "CheckWinding: %f area", area );
|
||||
}
|
||||
|
||||
WindingPlane( w, facenormal, &facedist );
|
||||
const Plane3f faceplane = WindingPlane( w );
|
||||
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
p1 = w->p[i];
|
||||
const Vector3& p1 = w->p[i];
|
||||
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
if ( p1[j] > MAX_WORLD_COORD || p1[j] < MIN_WORLD_COORD ) {
|
||||
@@ -909,23 +854,21 @@ void CheckWinding( winding_t *w ){
|
||||
j = i + 1 == w->numpoints ? 0 : i + 1;
|
||||
|
||||
// check the point is on the face plane
|
||||
d = DotProduct( p1, facenormal ) - facedist;
|
||||
d = plane3_distance_to_point( faceplane, p1 );
|
||||
if ( d < -ON_EPSILON || d > ON_EPSILON ) {
|
||||
Error( "CheckWinding: point off plane" );
|
||||
}
|
||||
|
||||
// check the edge isnt degenerate
|
||||
p2 = w->p[j];
|
||||
VectorSubtract( p2, p1, dir );
|
||||
const Vector3& p2 = w->p[j];
|
||||
dir = p2 - p1;
|
||||
|
||||
if ( VectorLength( dir ) < ON_EPSILON ) {
|
||||
if ( vector3_length( dir ) < ON_EPSILON ) {
|
||||
Error( "CheckWinding: degenerate edge" );
|
||||
}
|
||||
|
||||
CrossProduct( facenormal, dir, edgenormal );
|
||||
VectorNormalize( edgenormal, edgenormal );
|
||||
edgedist = DotProduct( p1, edgenormal );
|
||||
edgedist += ON_EPSILON;
|
||||
edgenormal = VectorNormalized( vector3_cross( faceplane.normal(), dir ) );
|
||||
edgedist = vector3_dot( p1, edgenormal ) + ON_EPSILON;
|
||||
|
||||
// all other points must be on front side
|
||||
for ( j = 0 ; j < w->numpoints ; j++ )
|
||||
@@ -933,7 +876,7 @@ void CheckWinding( winding_t *w ){
|
||||
if ( j == i ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( w->p[j], edgenormal );
|
||||
d = vector3_dot( w->p[j], edgenormal );
|
||||
if ( d > edgedist ) {
|
||||
Error( "CheckWinding: non-convex" );
|
||||
}
|
||||
@@ -947,26 +890,22 @@ void CheckWinding( winding_t *w ){
|
||||
WindingOnPlaneSide
|
||||
============
|
||||
*/
|
||||
int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){
|
||||
bool front, back;
|
||||
int i;
|
||||
vec_t d;
|
||||
|
||||
front = false;
|
||||
back = false;
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane ){
|
||||
bool front = false;
|
||||
bool back = false;
|
||||
for ( int i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
d = DotProduct( w->p[i], normal ) - dist;
|
||||
const double d = plane3_distance_to_point( plane, w->p[i] );
|
||||
if ( d < -ON_EPSILON ) {
|
||||
if ( front ) {
|
||||
return SIDE_CROSS;
|
||||
return eSideCross;
|
||||
}
|
||||
back = true;
|
||||
continue;
|
||||
}
|
||||
if ( d > ON_EPSILON ) {
|
||||
if ( back ) {
|
||||
return SIDE_CROSS;
|
||||
return eSideCross;
|
||||
}
|
||||
front = true;
|
||||
continue;
|
||||
@@ -974,12 +913,12 @@ int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){
|
||||
}
|
||||
|
||||
if ( back ) {
|
||||
return SIDE_BACK;
|
||||
return eSideBack;
|
||||
}
|
||||
if ( front ) {
|
||||
return SIDE_FRONT;
|
||||
return eSideFront;
|
||||
}
|
||||
return SIDE_ON;
|
||||
return eSideOn;
|
||||
}
|
||||
|
||||
|
||||
@@ -991,42 +930,36 @@ int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){
|
||||
=================
|
||||
*/
|
||||
#define MAX_HULL_POINTS 128
|
||||
void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal ) {
|
||||
void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& normal ) {
|
||||
int i, j, k;
|
||||
float *p, *copy;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
int numHullPoints, numNew;
|
||||
vec3_t hullPoints[MAX_HULL_POINTS];
|
||||
vec3_t newHullPoints[MAX_HULL_POINTS];
|
||||
vec3_t hullDirs[MAX_HULL_POINTS];
|
||||
Vector3 hullPoints[MAX_HULL_POINTS];
|
||||
Vector3 newHullPoints[MAX_HULL_POINTS];
|
||||
Vector3 hullDirs[MAX_HULL_POINTS];
|
||||
bool hullSide[MAX_HULL_POINTS];
|
||||
bool outside;
|
||||
|
||||
if ( !*hull ) {
|
||||
if ( *hull == nullptr ) {
|
||||
*hull = CopyWinding( w );
|
||||
return;
|
||||
}
|
||||
|
||||
numHullPoints = ( *hull )->numpoints;
|
||||
memcpy( hullPoints, ( *hull )->p, numHullPoints * sizeof( vec3_t ) );
|
||||
memcpy( hullPoints, ( *hull )->p, numHullPoints * sizeof( Vector3 ) );
|
||||
|
||||
for ( i = 0 ; i < w->numpoints ; i++ ) {
|
||||
p = w->p[i];
|
||||
const Vector3 &p = w->p[i];
|
||||
|
||||
// calculate hull side vectors
|
||||
for ( j = 0 ; j < numHullPoints ; j++ ) {
|
||||
k = ( j + 1 ) % numHullPoints;
|
||||
|
||||
VectorSubtract( hullPoints[k], hullPoints[j], dir );
|
||||
VectorNormalize( dir, dir );
|
||||
CrossProduct( normal, dir, hullDirs[j] );
|
||||
hullDirs[j] = vector3_cross( normal, VectorNormalized( hullPoints[k] - hullPoints[j] ) );
|
||||
}
|
||||
|
||||
outside = false;
|
||||
for ( j = 0 ; j < numHullPoints ; j++ ) {
|
||||
VectorSubtract( p, hullPoints[j], dir );
|
||||
d = DotProduct( dir, hullDirs[j] );
|
||||
const double d = vector3_dot( p - hullPoints[j], hullDirs[j] );
|
||||
if ( d >= ON_EPSILON ) {
|
||||
outside = true;
|
||||
}
|
||||
@@ -1049,7 +982,7 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal )
|
||||
}
|
||||
|
||||
// insert the point here
|
||||
VectorCopy( p, newHullPoints[0] );
|
||||
newHullPoints[0] = p;
|
||||
numNew = 1;
|
||||
|
||||
// copy over all points that aren't double fronts
|
||||
@@ -1058,18 +991,17 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal )
|
||||
if ( hullSide[ ( j + k ) % numHullPoints ] && hullSide[ ( j + k + 1 ) % numHullPoints ] ) {
|
||||
continue;
|
||||
}
|
||||
copy = hullPoints[ ( j + k + 1 ) % numHullPoints ];
|
||||
VectorCopy( copy, newHullPoints[numNew] );
|
||||
newHullPoints[numNew] = hullPoints[ ( j + k + 1 ) % numHullPoints ];
|
||||
numNew++;
|
||||
}
|
||||
|
||||
numHullPoints = numNew;
|
||||
memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( vec3_t ) );
|
||||
memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( Vector3 ) );
|
||||
}
|
||||
|
||||
FreeWinding( *hull );
|
||||
w = AllocWinding( numHullPoints );
|
||||
w->numpoints = numHullPoints;
|
||||
*hull = w;
|
||||
memcpy( w->p, hullPoints, numHullPoints * sizeof( vec3_t ) );
|
||||
memcpy( w->p, hullPoints, numHullPoints * sizeof( Vector3 ) );
|
||||
}
|
||||
|
||||
@@ -19,11 +19,14 @@
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qmath.h"
|
||||
|
||||
struct winding_t
|
||||
{
|
||||
int numpoints;
|
||||
vec3_t p[];
|
||||
Vector3 p[];
|
||||
};
|
||||
|
||||
#define MAX_POINTS_ON_WINDING 512
|
||||
@@ -33,27 +36,35 @@ struct winding_t
|
||||
#define ON_EPSILON 0.1
|
||||
#endif
|
||||
|
||||
enum EPlaneSide
|
||||
{
|
||||
eSideFront = 0, //! in front of plane ---->| *
|
||||
eSideBack = 1, //! behind the plane -*-->|
|
||||
eSideOn = 2,
|
||||
eSideCross = 3,
|
||||
};
|
||||
|
||||
winding_t *AllocWinding( int points );
|
||||
vec_t WindingArea( winding_t *w );
|
||||
void WindingCenter( winding_t *w, vec3_t center );
|
||||
void ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back );
|
||||
void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back );
|
||||
winding_t *ChopWinding( winding_t *in, vec3_t normal, vec_t dist );
|
||||
float WindingArea( const winding_t *w );
|
||||
Vector3 WindingCenter( const winding_t *w );
|
||||
void ClipWindingEpsilon( winding_t *in, const Plane3f& plane,
|
||||
float epsilon, winding_t **front, winding_t **back );
|
||||
void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane,
|
||||
float epsilon, winding_t **front, winding_t **back );
|
||||
winding_t *ChopWinding( winding_t *in, const Plane3f& plane );
|
||||
winding_t *CopyWinding( const winding_t *w );
|
||||
winding_t *ReverseWinding( winding_t *w );
|
||||
winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist );
|
||||
winding_t *ReverseWinding( const winding_t *w );
|
||||
winding_t *BaseWindingForPlane( const Plane3f& plane );
|
||||
void CheckWinding( winding_t *w );
|
||||
void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist );
|
||||
Plane3f WindingPlane( const winding_t *w );
|
||||
void RemoveColinearPoints( winding_t *w );
|
||||
int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist );
|
||||
EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane );
|
||||
void FreeWinding( winding_t *w );
|
||||
void WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs );
|
||||
MinMax WindingBounds( const winding_t *w );
|
||||
|
||||
void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal );
|
||||
void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& normal );
|
||||
|
||||
void ChopWindingInPlace( winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon );
|
||||
void ChopWindingInPlace( winding_t **w, const Plane3f& plane, float epsilon );
|
||||
// frees the original if clipped
|
||||
|
||||
void pw( winding_t *w );
|
||||
@@ -67,10 +78,10 @@ void pw( winding_t *w );
|
||||
struct winding_accu_t
|
||||
{
|
||||
int numpoints;
|
||||
vec3_accu_t p[];
|
||||
DoubleVector3 p[];
|
||||
};
|
||||
|
||||
winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist );
|
||||
void ChopWindingInPlaceAccu( winding_accu_t **w, vec3_t normal, vec_t dist, vec_t epsilon );
|
||||
winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& plane );
|
||||
void ChopWindingInPlaceAccu( winding_accu_t **w, const Plane3f& plane, float epsilon );
|
||||
winding_t *CopyWindingAccuToRegular( const winding_accu_t *w );
|
||||
void FreeWindingAccu( winding_accu_t *w );
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
#pragma once
|
||||
|
||||
#include "bytebool.h"
|
||||
#include "math/vector.h"
|
||||
#include "math/plane.h"
|
||||
|
||||
|
||||
#define VectorSet( v, a, b, c ) ( ( v )[0] = ( a ),( v )[1] = ( b ),( v )[2] = ( c ) )
|
||||
#define VectorCopy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2] )
|
||||
|
||||
#define RGBTOGRAY( x ) ( (float)( ( x )[0] ) * 0.2989f + (float)( ( x )[1] ) * 0.5870f + (float)( ( x )[2] ) * 0.1140f )
|
||||
|
||||
#define VectorFastNormalize VectorNormalize
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct MinMax___
|
||||
{
|
||||
BasicVector3<T> mins;
|
||||
BasicVector3<T> maxs;
|
||||
MinMax___(){
|
||||
clear();
|
||||
}
|
||||
template<typename U>
|
||||
MinMax___( const BasicVector3<U>& min, const BasicVector3<U>& max ) : mins( min ), maxs( max ){
|
||||
}
|
||||
void clear(){
|
||||
mins.x() = mins.y() = mins.z() = std::numeric_limits<T>::max();
|
||||
maxs.x() = maxs.y() = maxs.z() = std::numeric_limits<T>::lowest();
|
||||
}
|
||||
template<typename U>
|
||||
void extend( const BasicVector3<U>& point ){
|
||||
for ( size_t i = 0; i < 3; ++i ){
|
||||
const auto val = point[i];
|
||||
if ( val < mins[i] ) {
|
||||
mins[i] = val;
|
||||
}
|
||||
if ( val > maxs[i] ) {
|
||||
maxs[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename U>
|
||||
void extend( const MinMax___<U>& other ){
|
||||
extend( other.mins );
|
||||
extend( other.maxs );
|
||||
}
|
||||
template<typename U>
|
||||
bool test( const BasicVector3<U>& point ) const {
|
||||
return point.x() >= mins.x() && point.y() >= mins.y() && point.z() >= mins.z()
|
||||
&& point.x() <= maxs.x() && point.y() <= maxs.y() && point.z() <= maxs.z();
|
||||
}
|
||||
// true, if there is an intersection
|
||||
template<typename U>
|
||||
bool test( const MinMax___<U>& other ) const {
|
||||
return other.maxs.x() >= mins.x() && other.maxs.y() >= mins.y() && other.maxs.z() >= mins.z()
|
||||
&& other.mins.x() <= maxs.x() && other.mins.y() <= maxs.y() && other.mins.z() <= maxs.z();
|
||||
}
|
||||
BasicVector3<T> origin() const {
|
||||
return ( mins + maxs ) * 0.5;
|
||||
}
|
||||
};
|
||||
|
||||
using MinMax = MinMax___<float>;
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct Color4___ : public BasicVector4<T>
|
||||
{
|
||||
using BasicVector4<T>::BasicVector4;
|
||||
|
||||
Color4___( const BasicVector4<T>& vector ) : BasicVector4<T>( vector ){
|
||||
}
|
||||
BasicVector3<T>& rgb(){
|
||||
return this->vec3();
|
||||
}
|
||||
const BasicVector3<T>& rgb() const {
|
||||
return this->vec3();
|
||||
}
|
||||
T& alpha(){
|
||||
return this->w();
|
||||
}
|
||||
const T& alpha() const {
|
||||
return this->w();
|
||||
}
|
||||
};
|
||||
|
||||
using Color4f = Color4___<float>;
|
||||
using Color4b = Color4___<byte>;
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
T VectorNormalize( BasicVector3<T>& vector ) {
|
||||
const double length = vector3_length( DoubleVector3( vector ) );
|
||||
|
||||
if ( length == 0 ) {
|
||||
vector.set( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
vector /= length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
BasicVector3<T> VectorNormalized( const BasicVector3<T>& vector ) {
|
||||
BasicVector3<T> vec( vector );
|
||||
VectorNormalize( vec );
|
||||
return vec;
|
||||
}
|
||||
|
||||
const float EQUAL_EPSILON = 0.001;
|
||||
|
||||
inline bool VectorCompare( const Vector3& v1, const Vector3& v2 ){
|
||||
return vector3_equal_epsilon( v1, v2, EQUAL_EPSILON );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T VectorMax( const BasicVector3<T>& v ){
|
||||
return ( v[0] > v[1] ) ? ( ( v[0] > v[2] ) ? v[0] : v[2] ) : ( ( v[1] > v[2] ) ? v[1] : v[2] );
|
||||
}
|
||||
|
||||
inline bool VectorIsOnAxis( const Vector3& v ){
|
||||
int zeroComponentCount = 0;
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
if ( v[i] == 0.0 ) {
|
||||
zeroComponentCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return zeroComponentCount > 1; // The zero vector will be on axis.
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
PlaneFromPoints
|
||||
|
||||
Returns false if the triangle is degenrate.
|
||||
The normal will point out of the clock for clockwise ordered points
|
||||
=====================
|
||||
*/
|
||||
template<typename P, typename V>
|
||||
bool PlaneFromPoints( Plane3___<P>& plane, const BasicVector3<V>& p0, const BasicVector3<V>& p1, const BasicVector3<V>& p2 ) {
|
||||
plane.normal() = vector3_cross( p2 - p0, p1 - p0 );
|
||||
if ( VectorNormalize( plane.normal() ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
plane.dist() = vector3_dot( p0, plane.normal() );
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename P, typename V>
|
||||
bool PlaneFromPoints( Plane3___<P>& plane, const BasicVector3<V> planepts[3] ) {
|
||||
return PlaneFromPoints( plane, planepts[0], planepts[1], planepts[2] );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ComputeAxisBase()
|
||||
computes the base texture axis for brush primitive texturing
|
||||
note: ComputeAxisBase here and in editor code must always BE THE SAME!
|
||||
warning: special case behaviour of atan2( y, x ) <-> atan( y / x ) might not be the same everywhere when x == 0
|
||||
rotation by (0,RotY,RotZ) assigns X to normal
|
||||
*/
|
||||
|
||||
template <typename Element, typename OtherElement>
|
||||
inline void ComputeAxisBase( const BasicVector3<Element>& normal, BasicVector3<OtherElement>& texS, BasicVector3<OtherElement>& texT ){
|
||||
#if 1
|
||||
const BasicVector3<Element> up( 0, 0, 1 );
|
||||
const BasicVector3<Element> down( 0, 0, -1 );
|
||||
|
||||
if ( vector3_equal_epsilon( normal, up, Element(1e-6) ) ) {
|
||||
texS = BasicVector3<OtherElement>( 0, 1, 0 );
|
||||
texT = BasicVector3<OtherElement>( 1, 0, 0 );
|
||||
}
|
||||
else if ( vector3_equal_epsilon( normal, down, Element(1e-6) ) ) {
|
||||
texS = BasicVector3<OtherElement>( 0, 1, 0 );
|
||||
texT = BasicVector3<OtherElement>( -1, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
texS = vector3_normalised( vector3_cross( normal, up ) );
|
||||
texT = vector3_normalised( vector3_cross( normal, texS ) );
|
||||
vector3_negate( texS );
|
||||
}
|
||||
#else
|
||||
/* do some cleaning */
|
||||
if ( fabs( normal[ 0 ] ) < 1e-6 ) {
|
||||
normal[ 0 ] = 0.0f;
|
||||
}
|
||||
if ( fabs( normal[ 1 ] ) < 1e-6 ) {
|
||||
normal[ 1 ] = 0.0f;
|
||||
}
|
||||
if ( fabs( normal[ 2 ] ) < 1e-6 ) {
|
||||
normal[ 2 ] = 0.0f;
|
||||
}
|
||||
|
||||
/* compute the two rotations around y and z to rotate x to normal */
|
||||
const float RotY = -atan2( normal[ 2 ], sqrt( normal[ 1 ] * normal[ 1 ] + normal[ 0 ] * normal[ 0 ] ) );
|
||||
const float RotZ = atan2( normal[ 1 ], normal[ 0 ] );
|
||||
|
||||
/* rotate (0,1,0) and (0,0,1) to compute texS and texT */
|
||||
texS[ 0 ] = -sin( RotZ );
|
||||
texS[ 1 ] = cos( RotZ );
|
||||
texS[ 2 ] = 0;
|
||||
|
||||
/* the texT vector is along -z (t texture coorinates axis) */
|
||||
texT[ 0 ] = -sin( RotY ) * cos( RotZ );
|
||||
texT[ 1 ] = -sin( RotY ) * sin( RotZ );
|
||||
texT[ 2 ] = -cos( RotY );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
MakeNormalVectors
|
||||
|
||||
Given a normalized forward vector, create two
|
||||
other perpendicular vectors
|
||||
================
|
||||
*/
|
||||
inline void MakeNormalVectors( const Vector3& forward, Vector3& right, Vector3& up ){
|
||||
// this rotate and negate guarantees a vector
|
||||
// not colinear with the original
|
||||
right[1] = -forward[0];
|
||||
right[2] = forward[1];
|
||||
right[0] = forward[2];
|
||||
|
||||
right = VectorNormalized( right - forward * vector3_dot( right, forward ) );
|
||||
up = vector3_cross( right, forward );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** NormalToLatLong
|
||||
**
|
||||
** We use two byte encoded normals in some space critical applications.
|
||||
** Lat = 0 at (1,0,0) to 360 (-1,0,0), encoded in 8-bit sine table format
|
||||
** Lng = 0 at (0,0,1) to 180 (0,0,-1), encoded in 8-bit sine table format
|
||||
**
|
||||
*/
|
||||
inline void NormalToLatLong( const Vector3& normal, byte bytes[2] ) {
|
||||
// check for singularities
|
||||
if ( normal[0] == 0 && normal[1] == 0 ) {
|
||||
if ( normal[2] > 0 ) {
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0; // lat = 0, long = 0
|
||||
}
|
||||
else {
|
||||
bytes[0] = 128;
|
||||
bytes[1] = 0; // lat = 0, long = 128
|
||||
}
|
||||
}
|
||||
else {
|
||||
const int a = radians_to_degrees( atan2( normal[1], normal[0] ) ) * ( 255.0 / 360.0 );
|
||||
const int b = radians_to_degrees( acos( normal[2] ) ) * ( 255.0 / 360.0 );
|
||||
|
||||
bytes[0] = b & 0xff; // longitude
|
||||
bytes[1] = a & 0xff; // lattitude
|
||||
}
|
||||
}
|
||||
|
||||
// plane types are used to speed some tests
|
||||
// 0-2 are axial planes
|
||||
enum EPlaneType : int
|
||||
{
|
||||
ePlaneX = 0,
|
||||
ePlaneY = 1,
|
||||
ePlaneZ = 2,
|
||||
ePlaneNonAxial = 3
|
||||
};
|
||||
|
||||
inline EPlaneType PlaneTypeForNormal( const Vector3& normal ) {
|
||||
if ( normal[0] == 1.0 || normal[0] == -1.0 ) {
|
||||
return ePlaneX;
|
||||
}
|
||||
if ( normal[1] == 1.0 || normal[1] == -1.0 ) {
|
||||
return ePlaneY;
|
||||
}
|
||||
if ( normal[2] == 1.0 || normal[2] == -1.0 ) {
|
||||
return ePlaneZ;
|
||||
}
|
||||
|
||||
return ePlaneNonAxial;
|
||||
}
|
||||
|
||||
|
||||
inline void ColorNormalize( Vector3& color ) {
|
||||
const float max = VectorMax( color );
|
||||
|
||||
if ( max == 0 ) {
|
||||
color.set( 1 );
|
||||
}
|
||||
else{
|
||||
color *= ( 1.f / max );
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@
|
||||
// scriplib.c
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "inout.h"
|
||||
#include "scriplib.h"
|
||||
#include "vfs.h"
|
||||
@@ -365,7 +364,7 @@ void MatchToken( const char *match ) {
|
||||
}
|
||||
|
||||
|
||||
void Parse1DMatrix( int x, vec_t *m ) {
|
||||
void Parse1DMatrix( int x, float *m ) {
|
||||
int i;
|
||||
|
||||
MatchToken( "(" );
|
||||
@@ -378,7 +377,7 @@ void Parse1DMatrix( int x, vec_t *m ) {
|
||||
MatchToken( ")" );
|
||||
}
|
||||
|
||||
void Parse2DMatrix( int y, int x, vec_t *m ) {
|
||||
void Parse2DMatrix( int y, int x, float *m ) {
|
||||
int i;
|
||||
|
||||
MatchToken( "(" );
|
||||
@@ -390,7 +389,7 @@ void Parse2DMatrix( int y, int x, vec_t *m ) {
|
||||
MatchToken( ")" );
|
||||
}
|
||||
|
||||
void Parse3DMatrix( int z, int y, int x, vec_t *m ) {
|
||||
void Parse3DMatrix( int z, int y, int x, float *m ) {
|
||||
int i;
|
||||
|
||||
MatchToken( "(" );
|
||||
@@ -403,7 +402,7 @@ void Parse3DMatrix( int z, int y, int x, vec_t *m ) {
|
||||
}
|
||||
|
||||
|
||||
void Write1DMatrix( FILE *f, int x, vec_t *m ) {
|
||||
void Write1DMatrix( FILE *f, int x, float *m ) {
|
||||
int i;
|
||||
|
||||
fprintf( f, "( " );
|
||||
@@ -418,7 +417,7 @@ void Write1DMatrix( FILE *f, int x, vec_t *m ) {
|
||||
fprintf( f, ")" );
|
||||
}
|
||||
|
||||
void Write2DMatrix( FILE *f, int y, int x, vec_t *m ) {
|
||||
void Write2DMatrix( FILE *f, int y, int x, float *m ) {
|
||||
int i;
|
||||
|
||||
fprintf( f, "( " );
|
||||
@@ -430,7 +429,7 @@ void Write2DMatrix( FILE *f, int y, int x, vec_t *m ) {
|
||||
}
|
||||
|
||||
|
||||
void Write3DMatrix( FILE *f, int z, int y, int x, vec_t *m ) {
|
||||
void Write3DMatrix( FILE *f, int z, int y, int x, float *m ) {
|
||||
int i;
|
||||
|
||||
fprintf( f, "(\n" );
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
#ifndef __CMDLIB__
|
||||
#include "../common/cmdlib.h"
|
||||
#endif
|
||||
#ifndef __MATHLIB__
|
||||
#include "mathlib.h"
|
||||
#endif
|
||||
|
||||
#define MAXTOKEN 1024
|
||||
|
||||
@@ -47,10 +44,10 @@ bool TokenAvailable( void );
|
||||
|
||||
void MatchToken( const char *match );
|
||||
|
||||
void Parse1DMatrix( int x, vec_t *m );
|
||||
void Parse2DMatrix( int y, int x, vec_t *m );
|
||||
void Parse3DMatrix( int z, int y, int x, vec_t *m );
|
||||
void Parse1DMatrix( int x, float *m );
|
||||
void Parse2DMatrix( int y, int x, float *m );
|
||||
void Parse3DMatrix( int z, int y, int x, float *m );
|
||||
|
||||
void Write1DMatrix( FILE *f, int x, vec_t *m );
|
||||
void Write2DMatrix( FILE *f, int y, int x, vec_t *m );
|
||||
void Write3DMatrix( FILE *f, int z, int y, int x, vec_t *m );
|
||||
void Write1DMatrix( FILE *f, int x, float *m );
|
||||
void Write2DMatrix( FILE *f, int y, int x, float *m );
|
||||
void Write3DMatrix( FILE *f, int z, int y, int x, float *m );
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#endif
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "inout.h"
|
||||
#include "qthreads.h"
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "filematch.h"
|
||||
#include "mathlib.h"
|
||||
#include "inout.h"
|
||||
#include "vfs.h"
|
||||
#include "unzip.h"
|
||||
|
||||
@@ -179,7 +179,7 @@ bool BoundBrush( brush_t *brush ){
|
||||
winding_t *w;
|
||||
|
||||
|
||||
ClearBounds( brush->mins, brush->maxs );
|
||||
brush->minmax.clear();
|
||||
for ( i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
w = brush->sides[ i ].winding;
|
||||
@@ -187,12 +187,12 @@ bool BoundBrush( brush_t *brush ){
|
||||
continue;
|
||||
}
|
||||
for ( j = 0; j < w->numpoints; j++ )
|
||||
AddPointToBounds( w->p[ j ], brush->mins, brush->maxs );
|
||||
brush->minmax.extend( w->p[ j ] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( brush->mins[ i ] < MIN_WORLD_COORD || brush->maxs[ i ] > MAX_WORLD_COORD || brush->mins[i] >= brush->maxs[ i ] ) {
|
||||
if ( brush->minmax.mins[ i ] < MIN_WORLD_COORD || brush->minmax.maxs[ i ] > MAX_WORLD_COORD || brush->minmax.mins[i] >= brush->minmax.maxs[ i ] ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -205,28 +205,23 @@ bool BoundBrush( brush_t *brush ){
|
||||
|
||||
/*
|
||||
SnapWeldVector() - ydnar
|
||||
welds two vec3_t's into a third, taking into account nearest-to-integer
|
||||
welds two Vector3's into a third, taking into account nearest-to-integer
|
||||
instead of averaging
|
||||
*/
|
||||
|
||||
#define SNAP_EPSILON 0.01
|
||||
|
||||
void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ){
|
||||
void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out ){
|
||||
int i;
|
||||
vec_t ai, bi, outi;
|
||||
float ai, bi, outi;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( a == NULL || b == NULL || out == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* do each element */
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
/* round to integer */
|
||||
ai = Q_rint( a[ i ] );
|
||||
bi = Q_rint( b[ i ] );
|
||||
ai = std::rint( a[ i ] );
|
||||
bi = std::rint( b[ i ] );
|
||||
|
||||
/* prefer exact integer */
|
||||
if ( ai == a[ i ] ) {
|
||||
@@ -245,7 +240,7 @@ void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ){
|
||||
}
|
||||
|
||||
/* snap */
|
||||
outi = Q_rint( out[ i ] );
|
||||
outi = std::rint( out[ i ] );
|
||||
if ( fabs( outi - out[ i ] ) <= SNAP_EPSILON ) {
|
||||
out[ i ] = outi;
|
||||
}
|
||||
@@ -260,7 +255,7 @@ void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ){
|
||||
instead of averaging.
|
||||
==================
|
||||
*/
|
||||
void SnapWeldVectorAccu( vec3_accu_t a, vec3_accu_t b, vec3_accu_t out ){
|
||||
void SnapWeldVectorAccu( const DoubleVector3& a, const DoubleVector3& b, DoubleVector3& out ){
|
||||
// I'm just preserving what I think was the intended logic of the original
|
||||
// SnapWeldVector(). I'm not actually sure where this function should even
|
||||
// be used. I'd like to know which kinds of problems this function addresses.
|
||||
@@ -270,16 +265,12 @@ void SnapWeldVectorAccu( vec3_accu_t a, vec3_accu_t b, vec3_accu_t out ){
|
||||
// be snapping to the nearest 1/8 unit instead?
|
||||
|
||||
int i;
|
||||
vec_accu_t ai, bi, ad, bd;
|
||||
|
||||
if ( a == NULL || b == NULL || out == NULL ) {
|
||||
Error( "SnapWeldVectorAccu: NULL argument" );
|
||||
}
|
||||
double ai, bi, ad, bd;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
ai = Q_rintAccu( a[i] );
|
||||
bi = Q_rintAccu( b[i] );
|
||||
ai = std::rint( a[i] );
|
||||
bi = std::rint( b[i] );
|
||||
ad = fabs( ai - a[i] );
|
||||
bd = fabs( bi - b[i] );
|
||||
|
||||
@@ -310,7 +301,7 @@ void SnapWeldVectorAccu( vec3_accu_t a, vec3_accu_t b, vec3_accu_t out ){
|
||||
bool FixWinding( winding_t *w ){
|
||||
bool valid = true;
|
||||
int i, j, k;
|
||||
vec3_t vec;
|
||||
Vector3 vec;
|
||||
float dist;
|
||||
|
||||
|
||||
@@ -331,22 +322,21 @@ bool FixWinding( winding_t *w ){
|
||||
j = ( i + 1 ) % w->numpoints;
|
||||
|
||||
/* degenerate edge? */
|
||||
VectorSubtract( w->p[ i ], w->p[ j ], vec );
|
||||
dist = VectorLength( vec );
|
||||
dist = vector3_length( w->p[ i ] - w->p[ j ] );
|
||||
if ( dist < DEGENERATE_EPSILON ) {
|
||||
valid = false;
|
||||
//Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Degenerate winding edge found, fixing...\n" );
|
||||
|
||||
/* create an average point (ydnar 2002-01-26: using nearest-integer weld preference) */
|
||||
SnapWeldVector( w->p[ i ], w->p[ j ], vec );
|
||||
VectorCopy( vec, w->p[ i ] );
|
||||
w->p[ i ] = vec;
|
||||
//VectorAdd( w->p[ i ], w->p[ j ], vec );
|
||||
//VectorScale( vec, 0.5, w->p[ i ] );
|
||||
|
||||
/* move the remaining verts */
|
||||
for ( k = i + 2; k < w->numpoints; k++ )
|
||||
{
|
||||
VectorCopy( w->p[ k ], w->p[ k - 1 ] );
|
||||
w->p[ k - 1 ] = w->p[ k ];
|
||||
}
|
||||
w->numpoints--;
|
||||
}
|
||||
@@ -375,8 +365,6 @@ bool FixWinding( winding_t *w ){
|
||||
*/
|
||||
bool FixWindingAccu( winding_accu_t *w ){
|
||||
int i, j, k;
|
||||
vec3_accu_t vec;
|
||||
vec_accu_t dist;
|
||||
bool done, altered;
|
||||
|
||||
if ( w == NULL ) {
|
||||
@@ -395,19 +383,18 @@ bool FixWindingAccu( winding_accu_t *w ){
|
||||
{
|
||||
j = ( ( ( i + 1 ) == w->numpoints ) ? 0 : ( i + 1 ) );
|
||||
|
||||
VectorSubtractAccu( w->p[i], w->p[j], vec );
|
||||
dist = VectorLengthAccu( vec );
|
||||
if ( dist < DEGENERATE_EPSILON ) {
|
||||
DoubleVector3 vec = w->p[i] - w->p[j];
|
||||
if ( vector3_length( vec ) < DEGENERATE_EPSILON ) {
|
||||
// TODO: I think the "snap weld vector" was written before
|
||||
// some of the math precision fixes, and its purpose was
|
||||
// probably to address math accuracy issues. We can think
|
||||
// about changing the logic here. Maybe once plane distance
|
||||
// gets 64 bits, we can look at it then.
|
||||
SnapWeldVectorAccu( w->p[i], w->p[j], vec );
|
||||
VectorCopyAccu( vec, w->p[i] );
|
||||
w->p[i] = vec;
|
||||
for ( k = j + 1; k < w->numpoints; k++ )
|
||||
{
|
||||
VectorCopyAccu( w->p[k], w->p[k - 1] );
|
||||
w->p[k - 1] = w->p[k];
|
||||
}
|
||||
w->numpoints--;
|
||||
altered = true;
|
||||
@@ -456,9 +443,9 @@ bool CreateBrushWindings( brush_t *brush ){
|
||||
|
||||
/* make huge winding */
|
||||
#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
|
||||
w = BaseWindingForPlaneAccu( plane->normal, plane->dist );
|
||||
w = BaseWindingForPlaneAccu( plane->plane );
|
||||
#else
|
||||
w = BaseWindingForPlane( plane->normal, plane->dist );
|
||||
w = BaseWindingForPlane( plane->plane );
|
||||
#endif
|
||||
|
||||
/* walk the list of brush sides */
|
||||
@@ -475,9 +462,9 @@ bool CreateBrushWindings( brush_t *brush ){
|
||||
}
|
||||
plane = &mapplanes[ brush->sides[ j ].planenum ^ 1 ];
|
||||
#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
|
||||
ChopWindingInPlaceAccu( &w, plane->normal, plane->dist, 0 );
|
||||
ChopWindingInPlaceAccu( &w, plane->plane, 0 );
|
||||
#else
|
||||
ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); // CLIP_EPSILON );
|
||||
ChopWindingInPlace( &w, plane->plane, 0 ); // CLIP_EPSILON );
|
||||
#endif
|
||||
|
||||
/* ydnar: fix broken windings that would generate trifans */
|
||||
@@ -523,24 +510,20 @@ bool CreateBrushWindings( brush_t *brush ){
|
||||
Creates a new axial brush
|
||||
==================
|
||||
*/
|
||||
brush_t *BrushFromBounds( vec3_t mins, vec3_t maxs ){
|
||||
brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs ){
|
||||
brush_t *b;
|
||||
int i;
|
||||
vec3_t normal;
|
||||
vec_t dist;
|
||||
float dist;
|
||||
|
||||
b = AllocBrush( 6 );
|
||||
b->numsides = 6;
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
VectorClear( normal );
|
||||
normal[i] = 1;
|
||||
dist = maxs[i];
|
||||
b->sides[i].planenum = FindFloatPlane( normal, dist, 1, (vec3_t*) &maxs );
|
||||
b->sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, 1, &maxs );
|
||||
|
||||
normal[i] = -1;
|
||||
dist = -mins[i];
|
||||
b->sides[3 + i].planenum = FindFloatPlane( normal, dist, 1, (vec3_t*) &mins );
|
||||
b->sides[3 + i].planenum = FindFloatPlane( -g_vector3_axes[i], dist, 1, &mins );
|
||||
}
|
||||
|
||||
CreateBrushWindings( b );
|
||||
@@ -554,12 +537,11 @@ brush_t *BrushFromBounds( vec3_t mins, vec3_t maxs ){
|
||||
|
||||
==================
|
||||
*/
|
||||
vec_t BrushVolume( brush_t *brush ){
|
||||
float BrushVolume( brush_t *brush ){
|
||||
int i;
|
||||
winding_t *w;
|
||||
vec3_t corner;
|
||||
vec_t d, area, volume;
|
||||
plane_t *plane;
|
||||
Vector3 corner;
|
||||
float volume;
|
||||
|
||||
if ( !brush ) {
|
||||
return 0;
|
||||
@@ -578,7 +560,7 @@ vec_t BrushVolume( brush_t *brush ){
|
||||
if ( !w ) {
|
||||
return 0;
|
||||
}
|
||||
VectorCopy( w->p[0], corner );
|
||||
corner = w->p[0];
|
||||
|
||||
// make tetrahedrons to all other faces
|
||||
|
||||
@@ -589,10 +571,7 @@ vec_t BrushVolume( brush_t *brush ){
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
plane = &mapplanes[brush->sides[i].planenum];
|
||||
d = -( DotProduct( corner, plane->normal ) - plane->dist );
|
||||
area = WindingArea( w );
|
||||
volume += d * area;
|
||||
volume += -plane3_distance_to_point( mapplanes[brush->sides[i].planenum].plane, corner ) * WindingArea( w );
|
||||
}
|
||||
|
||||
volume /= 3;
|
||||
@@ -627,7 +606,7 @@ void WriteBSPBrushMap( const char *name, brush_t *list ){
|
||||
{
|
||||
// TODO: See if we can use a smaller winding to prevent resolution loss.
|
||||
// Is WriteBSPBrushMap() used only to decompile maps?
|
||||
w = BaseWindingForPlane( mapplanes[s->planenum].normal, mapplanes[s->planenum].dist );
|
||||
w = BaseWindingForPlane( mapplanes[s->planenum].plane );
|
||||
|
||||
fprintf( f, "( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2] );
|
||||
fprintf( f, "( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2] );
|
||||
@@ -791,7 +770,7 @@ void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree ) {
|
||||
*/
|
||||
tree_t *AllocTree( void ){
|
||||
tree_t *tree = safe_calloc( sizeof( *tree ) );
|
||||
ClearBounds( tree->mins, tree->maxs );
|
||||
tree->minmax.clear();
|
||||
return tree;
|
||||
}
|
||||
|
||||
@@ -821,17 +800,12 @@ bool WindingIsTiny( winding_t *w ){
|
||||
return false;
|
||||
*/
|
||||
int i, j;
|
||||
vec_t len;
|
||||
vec3_t delta;
|
||||
int edges;
|
||||
int edges = 0;
|
||||
|
||||
edges = 0;
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
j = i == w->numpoints - 1 ? 0 : i + 1;
|
||||
VectorSubtract( w->p[j], w->p[i], delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > EDGE_LENGTH ) {
|
||||
if ( vector3_length( w->p[j] - w->p[i] ) > EDGE_LENGTH ) {
|
||||
if ( ++edges == 3 ) {
|
||||
return false;
|
||||
}
|
||||
@@ -872,7 +846,7 @@ bool WindingIsHuge( winding_t *w ){
|
||||
int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){
|
||||
int i, j;
|
||||
winding_t *w;
|
||||
vec_t d, max;
|
||||
float max;
|
||||
int side;
|
||||
|
||||
max = 0;
|
||||
@@ -885,7 +859,7 @@ int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){
|
||||
}
|
||||
for ( j = 0 ; j < w->numpoints ; j++ )
|
||||
{
|
||||
d = DotProduct( w->p[j], plane->normal ) - plane->dist;
|
||||
const double d = plane3_distance_to_point( plane->plane, w->p[j] );
|
||||
if ( d > max ) {
|
||||
max = d;
|
||||
side = PSIDE_FRONT;
|
||||
@@ -912,7 +886,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
|
||||
winding_t *w, *cw[2], *midwinding;
|
||||
plane_t *plane, *plane2;
|
||||
side_t *s, *cs;
|
||||
float d, d_front, d_back;
|
||||
float d_front, d_back;
|
||||
|
||||
|
||||
*front = NULL;
|
||||
@@ -929,7 +903,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
|
||||
}
|
||||
for ( j = 0 ; j < w->numpoints ; j++ )
|
||||
{
|
||||
d = DotProduct( w->p[j], plane->normal ) - plane->dist;
|
||||
const double d = plane3_distance_to_point( plane->plane, w->p[j] );
|
||||
if ( d > 0 && d > d_front ) {
|
||||
d_front = d;
|
||||
}
|
||||
@@ -952,11 +926,11 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
|
||||
}
|
||||
|
||||
// create a new winding from the split plane
|
||||
w = BaseWindingForPlane( plane->normal, plane->dist );
|
||||
w = BaseWindingForPlane( plane->plane );
|
||||
for ( i = 0 ; i < brush->numsides && w ; i++ )
|
||||
{
|
||||
plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
|
||||
ChopWindingInPlace( &w, plane2->normal, plane2->dist, 0 ); // PLANESIDE_EPSILON);
|
||||
ChopWindingInPlace( &w, plane2->plane, 0 ); // PLANESIDE_EPSILON);
|
||||
}
|
||||
|
||||
if ( !w || WindingIsTiny( w ) ) { // the brush isn't really split
|
||||
@@ -998,7 +972,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
ClipWindingEpsilonStrict( w, plane->normal, plane->dist,
|
||||
ClipWindingEpsilonStrict( w, plane->plane,
|
||||
0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1] ); /* strict, in parallel case we get the face back because it also is the midwinding */
|
||||
for ( j = 0 ; j < 2 ; j++ )
|
||||
{
|
||||
@@ -1060,7 +1034,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
|
||||
}
|
||||
|
||||
{
|
||||
vec_t v1;
|
||||
float v1;
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/* -------------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 1999-2007 id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
This code has been altered significantly from its original form, to support
|
||||
several games based on the Quake III Arena engine, in the form of "Q3Map2."
|
||||
|
||||
------------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
/* dependencies */
|
||||
#include "q3map2.h"
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------------
|
||||
|
||||
functions
|
||||
|
||||
------------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
ComputeAxisBase()
|
||||
computes the base texture axis for brush primitive texturing
|
||||
note: ComputeAxisBase here and in editor code must always BE THE SAME!
|
||||
warning: special case behaviour of atan2( y, x ) <-> atan( y / x ) might not be the same everywhere when x == 0
|
||||
rotation by (0,RotY,RotZ) assigns X to normal
|
||||
*/
|
||||
|
||||
void ComputeAxisBase( vec3_t normal, vec3_t texX, vec3_t texY ){
|
||||
vec_t RotY, RotZ;
|
||||
|
||||
|
||||
/* do some cleaning */
|
||||
if ( fabs( normal[ 0 ] ) < 1e-6 ) {
|
||||
normal[ 0 ] = 0.0f;
|
||||
}
|
||||
if ( fabs( normal[ 1 ] ) < 1e-6 ) {
|
||||
normal[ 1 ] = 0.0f;
|
||||
}
|
||||
if ( fabs( normal[ 2 ] ) < 1e-6 ) {
|
||||
normal[ 2 ] = 0.0f;
|
||||
}
|
||||
|
||||
/* compute the two rotations around y and z to rotate x to normal */
|
||||
RotY = -atan2( normal[ 2 ], sqrt( normal[ 1 ] * normal[ 1 ] + normal[ 0 ] * normal[ 0 ] ) );
|
||||
RotZ = atan2( normal[ 1 ], normal[ 0 ] );
|
||||
|
||||
/* rotate (0,1,0) and (0,0,1) to compute texX and texY */
|
||||
texX[ 0 ] = -sin( RotZ );
|
||||
texX[ 1 ] = cos( RotZ );
|
||||
texX[ 2 ] = 0;
|
||||
|
||||
/* the texY vector is along -z (t texture coorinates axis) */
|
||||
texY[ 0 ] = -sin( RotY ) * cos( RotZ );
|
||||
texY[ 1 ] = -sin( RotY ) * sin( RotZ );
|
||||
texY[ 2 ] = -cos( RotY );
|
||||
}
|
||||
@@ -125,7 +125,7 @@ static void ProcessAdvertisements( void ) {
|
||||
// store the normal for use at run time.. all ad verts are assumed to
|
||||
// have identical normals (because they should be a simple rectangle)
|
||||
// so just use the first vert's normal
|
||||
VectorCopy( bspDrawVerts[adSurface->firstVert].normal, bspAds[numBSPAds].normal );
|
||||
bspAds[numBSPAds].normal = bspDrawVerts[adSurface->firstVert].normal;
|
||||
|
||||
// store the ad quad for quick use at run time
|
||||
if ( adSurface->surfaceType == MST_PATCH ) {
|
||||
@@ -133,10 +133,10 @@ static void ProcessAdvertisements( void ) {
|
||||
int v1 = adSurface->firstVert + adSurface->numVerts - 1;
|
||||
int v2 = adSurface->firstVert + adSurface->numVerts - adSurface->patchWidth;
|
||||
int v3 = adSurface->firstVert;
|
||||
VectorCopy( bspDrawVerts[v0].xyz, bspAds[numBSPAds].rect[0] );
|
||||
VectorCopy( bspDrawVerts[v1].xyz, bspAds[numBSPAds].rect[1] );
|
||||
VectorCopy( bspDrawVerts[v2].xyz, bspAds[numBSPAds].rect[2] );
|
||||
VectorCopy( bspDrawVerts[v3].xyz, bspAds[numBSPAds].rect[3] );
|
||||
bspAds[numBSPAds].rect[0] = bspDrawVerts[v0].xyz;
|
||||
bspAds[numBSPAds].rect[1] = bspDrawVerts[v1].xyz;
|
||||
bspAds[numBSPAds].rect[2] = bspDrawVerts[v2].xyz;
|
||||
bspAds[numBSPAds].rect[3] = bspDrawVerts[v3].xyz;
|
||||
}
|
||||
else {
|
||||
Error( "Ad cell %d has an unsupported Ad Surface type.", bspAds[numBSPAds].cellId );
|
||||
@@ -441,7 +441,7 @@ void ProcessWorldModel( void ){
|
||||
for ( const auto& light : entities )
|
||||
{
|
||||
entity_t *target;
|
||||
vec3_t origin, targetOrigin, normal, color;
|
||||
Vector3 origin, targetOrigin, normal, color;
|
||||
|
||||
/* get light */
|
||||
if ( light.classname_is( "light" ) ) {
|
||||
@@ -459,13 +459,12 @@ void ProcessWorldModel( void ){
|
||||
target = FindTargetEntity( value );
|
||||
if ( target != NULL ) {
|
||||
target->vectorForKey( "origin", targetOrigin );
|
||||
VectorSubtract( targetOrigin, origin, normal );
|
||||
VectorNormalize( normal, normal );
|
||||
normal = VectorNormalized( targetOrigin - origin );
|
||||
}
|
||||
}
|
||||
else{
|
||||
//% VectorClear( normal );
|
||||
VectorSet( normal, 0, 0, -1 );
|
||||
//% normal.set( 0 );
|
||||
normal = -g_vector3_axis_z;
|
||||
}
|
||||
|
||||
if ( colorsRGB ) {
|
||||
|
||||
@@ -755,7 +755,7 @@ bool entity_t::read_keyvalue_( float &float_value, std::initializer_list<const c
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool entity_t::read_keyvalue_( float (&vector3_value)[3], std::initializer_list<const char*>&& keys ) const {
|
||||
bool entity_t::read_keyvalue_( Vector3& vector3_value, std::initializer_list<const char*>&& keys ) const {
|
||||
for( const char* key : keys ){
|
||||
const char* value = valueForKey( key );
|
||||
if( !strEmpty( value ) ){
|
||||
|
||||
@@ -145,8 +145,8 @@ struct ibspDrawSurface_t
|
||||
int lightmapX, lightmapY;
|
||||
int lightmapWidth, lightmapHeight;
|
||||
|
||||
vec3_t lightmapOrigin;
|
||||
vec3_t lightmapVecs[ 3 ];
|
||||
Vector3 lightmapOrigin;
|
||||
Vector3 lightmapVecs[ 3 ];
|
||||
|
||||
int patchWidth;
|
||||
int patchHeight;
|
||||
@@ -194,10 +194,10 @@ static void CopyDrawSurfacesLump( ibspHeader_t *header ){
|
||||
out->lightmapWidth = in->lightmapWidth;
|
||||
out->lightmapHeight = in->lightmapHeight;
|
||||
|
||||
VectorCopy( in->lightmapOrigin, out->lightmapOrigin );
|
||||
VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );
|
||||
VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );
|
||||
VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );
|
||||
out->lightmapOrigin = in->lightmapOrigin;
|
||||
out->lightmapVecs[ 0 ] = in->lightmapVecs[ 0 ];
|
||||
out->lightmapVecs[ 1 ] = in->lightmapVecs[ 1 ];
|
||||
out->lightmapVecs[ 2 ] = in->lightmapVecs[ 2 ];
|
||||
|
||||
out->patchWidth = in->patchWidth;
|
||||
out->patchHeight = in->patchHeight;
|
||||
@@ -237,10 +237,10 @@ static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header ){
|
||||
out->lightmapWidth = in->lightmapWidth;
|
||||
out->lightmapHeight = in->lightmapHeight;
|
||||
|
||||
VectorCopy( in->lightmapOrigin, out->lightmapOrigin );
|
||||
VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );
|
||||
VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );
|
||||
VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );
|
||||
out->lightmapOrigin = in->lightmapOrigin;
|
||||
out->lightmapVecs[ 0 ] = in->lightmapVecs[ 0 ];
|
||||
out->lightmapVecs[ 1 ] = in->lightmapVecs[ 1 ];
|
||||
out->lightmapVecs[ 2 ] = in->lightmapVecs[ 2 ];
|
||||
|
||||
out->patchWidth = in->patchWidth;
|
||||
out->patchHeight = in->patchHeight;
|
||||
@@ -261,11 +261,11 @@ static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header ){
|
||||
/* drawverts */
|
||||
struct ibspDrawVert_t
|
||||
{
|
||||
vec3_t xyz;
|
||||
float st[ 2 ];
|
||||
float lightmap[ 2 ];
|
||||
vec3_t normal;
|
||||
byte color[ 4 ];
|
||||
Vector3 xyz;
|
||||
Vector2 st;
|
||||
Vector2 lightmap;
|
||||
Vector3 normal;
|
||||
Color4b color;
|
||||
};
|
||||
|
||||
|
||||
@@ -284,20 +284,11 @@ static void CopyDrawVertsLump( ibspHeader_t *header ){
|
||||
out = bspDrawVerts;
|
||||
for ( i = 0; i < numBSPDrawVerts; i++ )
|
||||
{
|
||||
VectorCopy( in->xyz, out->xyz );
|
||||
out->st[ 0 ] = in->st[ 0 ];
|
||||
out->st[ 1 ] = in->st[ 1 ];
|
||||
|
||||
out->lightmap[ 0 ][ 0 ] = in->lightmap[ 0 ];
|
||||
out->lightmap[ 0 ][ 1 ] = in->lightmap[ 1 ];
|
||||
|
||||
VectorCopy( in->normal, out->normal );
|
||||
|
||||
out->color[ 0 ][ 0 ] = in->color[ 0 ];
|
||||
out->color[ 0 ][ 1 ] = in->color[ 1 ];
|
||||
out->color[ 0 ][ 2 ] = in->color[ 2 ];
|
||||
out->color[ 0 ][ 3 ] = in->color[ 3 ];
|
||||
|
||||
out->xyz = in->xyz;
|
||||
out->st = in->st;
|
||||
out->lightmap[ 0 ] = in->lightmap;
|
||||
out->normal = in->normal;
|
||||
out->color[ 0 ] = in->color;
|
||||
in++;
|
||||
out++;
|
||||
}
|
||||
@@ -319,20 +310,11 @@ static void AddDrawVertsLump( FILE *file, ibspHeader_t *header ){
|
||||
out = buffer;
|
||||
for ( i = 0; i < numBSPDrawVerts; i++ )
|
||||
{
|
||||
VectorCopy( in->xyz, out->xyz );
|
||||
out->st[ 0 ] = in->st[ 0 ];
|
||||
out->st[ 1 ] = in->st[ 1 ];
|
||||
|
||||
out->lightmap[ 0 ] = in->lightmap[ 0 ][ 0 ];
|
||||
out->lightmap[ 1 ] = in->lightmap[ 0 ][ 1 ];
|
||||
|
||||
VectorCopy( in->normal, out->normal );
|
||||
|
||||
out->color[ 0 ] = in->color[ 0 ][ 0 ];
|
||||
out->color[ 1 ] = in->color[ 0 ][ 1 ];
|
||||
out->color[ 2 ] = in->color[ 0 ][ 2 ];
|
||||
out->color[ 3 ] = in->color[ 0 ][ 3 ];
|
||||
|
||||
out->xyz = in->xyz;
|
||||
out->st = in->st;
|
||||
out->lightmap = in->lightmap[ 0 ];
|
||||
out->normal = in->normal;
|
||||
out->color = in->color[ 0 ];
|
||||
in++;
|
||||
out++;
|
||||
}
|
||||
@@ -349,8 +331,8 @@ static void AddDrawVertsLump( FILE *file, ibspHeader_t *header ){
|
||||
/* light grid */
|
||||
struct ibspGridPoint_t
|
||||
{
|
||||
byte ambient[ 3 ];
|
||||
byte directed[ 3 ];
|
||||
Vector3b ambient;
|
||||
Vector3b directed;
|
||||
byte latLong[ 2 ];
|
||||
};
|
||||
|
||||
@@ -374,8 +356,8 @@ static void CopyLightGridLumps( ibspHeader_t *header ){
|
||||
{
|
||||
for ( j = 0; j < MAX_LIGHTMAPS; j++ )
|
||||
{
|
||||
VectorCopy( in->ambient, out->ambient[ j ] );
|
||||
VectorCopy( in->directed, out->directed[ j ] );
|
||||
out->ambient[ j ] = in->ambient;
|
||||
out->directed[ j ] = in->directed;
|
||||
out->styles[ j ] = LS_NONE;
|
||||
}
|
||||
|
||||
@@ -409,8 +391,8 @@ static void AddLightGridLumps( FILE *file, ibspHeader_t *header ){
|
||||
out = buffer;
|
||||
for ( i = 0; i < numBSPGridPoints; i++ )
|
||||
{
|
||||
VectorCopy( in->ambient[ 0 ], out->ambient );
|
||||
VectorCopy( in->directed[ 0 ], out->directed );
|
||||
out->ambient = in->ambient[ 0 ];
|
||||
out->directed = in->directed[ 0 ];
|
||||
|
||||
out->latLong[ 0 ] = in->latLong[ 0 ];
|
||||
out->latLong[ 1 ] = in->latLong[ 1 ];
|
||||
|
||||
@@ -41,10 +41,9 @@
|
||||
|
||||
int numLightmapsASE = 0;
|
||||
|
||||
static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin, const int* lmIndices ){
|
||||
static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, const Vector3& origin, const int* lmIndices ){
|
||||
int i, v, face, a, b, c;
|
||||
bspDrawVert_t *dv;
|
||||
vec3_t normal;
|
||||
char name[ 1024 ];
|
||||
|
||||
|
||||
@@ -102,10 +101,8 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur
|
||||
a = bspDrawIndexes[ i + ds->firstIndex ];
|
||||
b = bspDrawIndexes[ i + ds->firstIndex + 1 ];
|
||||
c = bspDrawIndexes[ i + ds->firstIndex + 2 ];
|
||||
VectorCopy( bspDrawVerts[ a ].normal, normal );
|
||||
VectorAdd( normal, bspDrawVerts[ b ].normal, normal );
|
||||
VectorAdd( normal, bspDrawVerts[ c ].normal, normal );
|
||||
if ( VectorNormalize( normal, normal ) ) {
|
||||
Vector3 normal = bspDrawVerts[ a ].normal + bspDrawVerts[ b ].normal + bspDrawVerts[ c ].normal;
|
||||
if ( VectorNormalize( normal ) != 0 ) {
|
||||
fprintf( f, "\t\t\t*MESH_FACENORMAL\t%d\t%f\t%f\t%f\r\n", face, normal[ 0 ], normal[ 1 ], normal[ 2 ] );
|
||||
}
|
||||
}
|
||||
@@ -188,7 +185,7 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur
|
||||
exports a bsp model to an ase chunk
|
||||
*/
|
||||
|
||||
static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, const int* lmIndices ){
|
||||
static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, const Vector3& origin, const int* lmIndices ){
|
||||
int i, s;
|
||||
bspDrawSurface_t *ds;
|
||||
|
||||
@@ -404,7 +401,7 @@ int ConvertBSPToASE( char *bspName ){
|
||||
model = &bspModels[ modelNum ];
|
||||
|
||||
/* get entity origin */
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
e->vectorForKey( "origin", origin );
|
||||
|
||||
/* convert model */
|
||||
|
||||
@@ -325,16 +325,16 @@ int BSPInfo( int count, char **fileNames ){
|
||||
}
|
||||
|
||||
|
||||
static void ExtrapolateTexcoords( const float *axyz, const float *ast, const float *bxyz, const float *bst, const float *cxyz, const float *cst, const float *axyz_new, float *ast_out, const float *bxyz_new, float *bst_out, const float *cxyz_new, float *cst_out ){
|
||||
vec4_t scoeffs, tcoeffs;
|
||||
float md;
|
||||
m4x4_t solvematrix;
|
||||
static void ExtrapolateTexcoords( const float *axyz, const float *ast,
|
||||
const float *bxyz, const float *bst,
|
||||
const float *cxyz, const float *cst,
|
||||
const Vector3& axyz_new, Vector2& ast_out,
|
||||
const Vector3& bxyz_new, Vector2& bst_out,
|
||||
const Vector3& cxyz_new, Vector2& cst_out ){
|
||||
Vector4 scoeffs, tcoeffs;
|
||||
Matrix4 solvematrix;
|
||||
|
||||
vec3_t norm;
|
||||
vec3_t dab, dac;
|
||||
VectorSubtract( bxyz, axyz, dab );
|
||||
VectorSubtract( cxyz, axyz, dac );
|
||||
CrossProduct( dab, dac, norm );
|
||||
const Vector3 norm = vector3_cross( vector3_from_array( bxyz ) - vector3_from_array( axyz ), vector3_from_array( cxyz ) - vector3_from_array( axyz ) );
|
||||
|
||||
// assume:
|
||||
// s = f(x, y, z)
|
||||
@@ -365,24 +365,24 @@ static void ExtrapolateTexcoords( const float *axyz, const float *ast, const flo
|
||||
solvematrix[11] = norm[2];
|
||||
solvematrix[15] = 0;
|
||||
|
||||
md = m4_det( solvematrix );
|
||||
const double md = matrix4_determinant( solvematrix );
|
||||
if ( md * md < 1e-10 ) {
|
||||
Sys_Printf( "Cannot invert some matrix, some texcoords aren't extrapolated!" );
|
||||
return;
|
||||
}
|
||||
|
||||
m4x4_invert( solvematrix );
|
||||
matrix4_full_invert( solvematrix );
|
||||
|
||||
scoeffs[0] = ast[0];
|
||||
scoeffs[1] = bst[0];
|
||||
scoeffs[2] = cst[0];
|
||||
scoeffs[3] = 0;
|
||||
m4x4_transform_vec4( solvematrix, scoeffs );
|
||||
matrix4_transform_vector4( solvematrix, scoeffs );
|
||||
tcoeffs[0] = ast[1];
|
||||
tcoeffs[1] = bst[1];
|
||||
tcoeffs[2] = cst[1];
|
||||
tcoeffs[3] = 0;
|
||||
m4x4_transform_vec4( solvematrix, tcoeffs );
|
||||
matrix4_transform_vector4( solvematrix, tcoeffs );
|
||||
|
||||
ast_out[0] = scoeffs[0] * axyz_new[0] + scoeffs[1] * axyz_new[1] + scoeffs[2] * axyz_new[2] + scoeffs[3];
|
||||
ast_out[1] = tcoeffs[0] * axyz_new[0] + tcoeffs[1] * axyz_new[1] + tcoeffs[2] * axyz_new[2] + tcoeffs[3];
|
||||
@@ -400,8 +400,8 @@ static void ExtrapolateTexcoords( const float *axyz, const float *ast, const flo
|
||||
int ScaleBSPMain( int argc, char **argv ){
|
||||
int i, j;
|
||||
float f, a;
|
||||
vec3_t scale;
|
||||
vec3_t vec;
|
||||
Vector3 scale;
|
||||
Vector3 vec;
|
||||
char str[ 1024 ];
|
||||
int uniform, axis;
|
||||
bool texscale;
|
||||
@@ -469,9 +469,7 @@ int ScaleBSPMain( int argc, char **argv ){
|
||||
if ( entities[i].classname_prefixed( "info_player_" ) ) {
|
||||
vec[2] += spawn_ref;
|
||||
}
|
||||
vec[0] *= scale[0];
|
||||
vec[1] *= scale[1];
|
||||
vec[2] *= scale[2];
|
||||
vec *= scale;
|
||||
if ( entities[i].classname_prefixed( "info_player_" ) ) {
|
||||
vec[2] -= spawn_ref;
|
||||
}
|
||||
@@ -483,7 +481,7 @@ int ScaleBSPMain( int argc, char **argv ){
|
||||
if ( a == -1 || a == -2 ) { // z scale
|
||||
axis = 2;
|
||||
}
|
||||
else if ( fabs( sin( DEG2RAD( a ) ) ) < 0.707 ) {
|
||||
else if ( fabs( sin( degrees_to_radians( a ) ) ) < 0.707 ) {
|
||||
axis = 0;
|
||||
}
|
||||
else{
|
||||
@@ -510,34 +508,22 @@ int ScaleBSPMain( int argc, char **argv ){
|
||||
/* scale models */
|
||||
for ( i = 0; i < numBSPModels; i++ )
|
||||
{
|
||||
bspModels[ i ].mins[0] *= scale[0];
|
||||
bspModels[ i ].mins[1] *= scale[1];
|
||||
bspModels[ i ].mins[2] *= scale[2];
|
||||
bspModels[ i ].maxs[0] *= scale[0];
|
||||
bspModels[ i ].maxs[1] *= scale[1];
|
||||
bspModels[ i ].maxs[2] *= scale[2];
|
||||
bspModels[ i ].minmax.mins *= scale;
|
||||
bspModels[ i ].minmax.maxs *= scale;
|
||||
}
|
||||
|
||||
/* scale nodes */
|
||||
for ( i = 0; i < numBSPNodes; i++ )
|
||||
{
|
||||
bspNodes[ i ].mins[0] *= scale[0];
|
||||
bspNodes[ i ].mins[1] *= scale[1];
|
||||
bspNodes[ i ].mins[2] *= scale[2];
|
||||
bspNodes[ i ].maxs[0] *= scale[0];
|
||||
bspNodes[ i ].maxs[1] *= scale[1];
|
||||
bspNodes[ i ].maxs[2] *= scale[2];
|
||||
bspNodes[ i ].minmax.mins *= scale;
|
||||
bspNodes[ i ].minmax.maxs *= scale;
|
||||
}
|
||||
|
||||
/* scale leafs */
|
||||
for ( i = 0; i < numBSPLeafs; i++ )
|
||||
{
|
||||
bspLeafs[ i ].mins[0] *= scale[0];
|
||||
bspLeafs[ i ].mins[1] *= scale[1];
|
||||
bspLeafs[ i ].mins[2] *= scale[2];
|
||||
bspLeafs[ i ].maxs[0] *= scale[0];
|
||||
bspLeafs[ i ].maxs[1] *= scale[1];
|
||||
bspLeafs[ i ].maxs[2] *= scale[2];
|
||||
bspLeafs[ i ].minmax.mins *= scale;
|
||||
bspLeafs[ i ].minmax.maxs *= scale;
|
||||
}
|
||||
|
||||
if ( texscale ) {
|
||||
@@ -562,7 +548,7 @@ int ScaleBSPMain( int argc, char **argv ){
|
||||
bspDrawVerts[i].normal[0] /= scale[0];
|
||||
bspDrawVerts[i].normal[1] /= scale[1];
|
||||
bspDrawVerts[i].normal[2] /= scale[2];
|
||||
VectorNormalize( bspDrawVerts[i].normal, bspDrawVerts[i].normal );
|
||||
VectorNormalize( bspDrawVerts[i].normal );
|
||||
}
|
||||
|
||||
if ( texscale ) {
|
||||
@@ -600,29 +586,25 @@ int ScaleBSPMain( int argc, char **argv ){
|
||||
if ( uniform ) {
|
||||
for ( i = 0; i < numBSPPlanes; i++ )
|
||||
{
|
||||
bspPlanes[ i ].dist *= scale[0];
|
||||
bspPlanes[ i ].dist() *= scale[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < numBSPPlanes; i++ )
|
||||
{
|
||||
bspPlanes[ i ].normal[0] /= scale[0];
|
||||
bspPlanes[ i ].normal[1] /= scale[1];
|
||||
bspPlanes[ i ].normal[2] /= scale[2];
|
||||
f = 1 / VectorLength( bspPlanes[i].normal );
|
||||
VectorScale( bspPlanes[i].normal, f, bspPlanes[i].normal );
|
||||
bspPlanes[ i ].dist *= f;
|
||||
bspPlanes[i].normal() /= scale;
|
||||
const double len = vector3_length( bspPlanes[i].normal() );
|
||||
bspPlanes[i].normal() /= len;
|
||||
bspPlanes[i].dist() /= len;
|
||||
}
|
||||
}
|
||||
|
||||
/* scale gridsize */
|
||||
if ( !entities[ 0 ].read_keyvalue( vec, "gridsize" ) ) {
|
||||
VectorCopy( gridSize, vec );
|
||||
vec = gridSize;
|
||||
}
|
||||
vec[0] *= scale[0];
|
||||
vec[1] *= scale[1];
|
||||
vec[2] *= scale[2];
|
||||
vec *= scale;
|
||||
sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] );
|
||||
entities[ 0 ].setKeyValue( "gridsize", str );
|
||||
|
||||
@@ -647,8 +629,8 @@ int ScaleBSPMain( int argc, char **argv ){
|
||||
|
||||
int ShiftBSPMain( int argc, char **argv ){
|
||||
int i, j;
|
||||
vec3_t scale;
|
||||
vec3_t vec;
|
||||
Vector3 scale;
|
||||
Vector3 vec;
|
||||
char str[ 1024 ];
|
||||
float spawn_ref = 0;
|
||||
|
||||
@@ -704,9 +686,7 @@ int ShiftBSPMain( int argc, char **argv ){
|
||||
if ( e.classname_prefixed( "info_player_" ) ) {
|
||||
vec[2] += spawn_ref;
|
||||
}
|
||||
vec[0] += scale[0];
|
||||
vec[1] += scale[1];
|
||||
vec[2] += scale[2];
|
||||
vec += scale;
|
||||
if ( e.classname_prefixed( "info_player_" ) ) {
|
||||
vec[2] -= spawn_ref;
|
||||
}
|
||||
@@ -719,65 +699,48 @@ int ShiftBSPMain( int argc, char **argv ){
|
||||
/* shift models */
|
||||
for ( i = 0; i < numBSPModels; i++ )
|
||||
{
|
||||
bspModels[ i ].mins[0] += scale[0];
|
||||
bspModels[ i ].mins[1] += scale[1];
|
||||
bspModels[ i ].mins[2] += scale[2];
|
||||
bspModels[ i ].maxs[0] += scale[0];
|
||||
bspModels[ i ].maxs[1] += scale[1];
|
||||
bspModels[ i ].maxs[2] += scale[2];
|
||||
bspModels[ i ].minmax.mins += scale;
|
||||
bspModels[ i ].minmax.maxs += scale;
|
||||
}
|
||||
|
||||
/* shift nodes */
|
||||
for ( i = 0; i < numBSPNodes; i++ )
|
||||
{
|
||||
bspNodes[ i ].mins[0] += scale[0];
|
||||
bspNodes[ i ].mins[1] += scale[1];
|
||||
bspNodes[ i ].mins[2] += scale[2];
|
||||
bspNodes[ i ].maxs[0] += scale[0];
|
||||
bspNodes[ i ].maxs[1] += scale[1];
|
||||
bspNodes[ i ].maxs[2] += scale[2];
|
||||
bspNodes[ i ].minmax.mins += scale;
|
||||
bspNodes[ i ].minmax.maxs += scale;
|
||||
}
|
||||
|
||||
/* shift leafs */
|
||||
for ( i = 0; i < numBSPLeafs; i++ )
|
||||
{
|
||||
bspLeafs[ i ].mins[0] += scale[0];
|
||||
bspLeafs[ i ].mins[1] += scale[1];
|
||||
bspLeafs[ i ].mins[2] += scale[2];
|
||||
bspLeafs[ i ].maxs[0] += scale[0];
|
||||
bspLeafs[ i ].maxs[1] += scale[1];
|
||||
bspLeafs[ i ].maxs[2] += scale[2];
|
||||
bspLeafs[ i ].minmax.mins += scale;
|
||||
bspLeafs[ i ].minmax.maxs += scale;
|
||||
}
|
||||
|
||||
/* shift drawverts */
|
||||
for ( i = 0; i < numBSPDrawVerts; i++ )
|
||||
{
|
||||
bspDrawVerts[i].xyz[0] += scale[0];
|
||||
bspDrawVerts[i].xyz[1] += scale[1];
|
||||
bspDrawVerts[i].xyz[2] += scale[2];
|
||||
bspDrawVerts[i].xyz += scale;
|
||||
}
|
||||
|
||||
/* shift planes */
|
||||
|
||||
vec3_t point;
|
||||
|
||||
for ( i = 0; i < numBSPPlanes; i++ )
|
||||
{
|
||||
//find point on plane
|
||||
Vector3 point;
|
||||
for ( j=0; j<3; j++ ){
|
||||
//point[j] = bspPlanes[ i ].dist * bspPlanes[ i ].normal[j];
|
||||
if ( fabs( bspPlanes[ i ].normal[j] ) > 0.5 ){
|
||||
point[j] = bspPlanes[ i ].dist / bspPlanes[ i ].normal[j];
|
||||
if ( fabs( bspPlanes[ i ].normal()[j] ) > 0.5 ){
|
||||
point[j] = bspPlanes[ i ].dist() / bspPlanes[ i ].normal()[j];
|
||||
point[(j+1)%3] = point[(j+2)%3] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//shift point
|
||||
for ( j=0; j<3; j++ ){
|
||||
point[j] += scale[j];
|
||||
}
|
||||
point += scale;
|
||||
//calc new plane dist
|
||||
bspPlanes[ i ].dist = DotProduct( point, bspPlanes[ i ].normal );
|
||||
bspPlanes[ i ].dist() = vector3_dot( point, bspPlanes[ i ].normal() );
|
||||
}
|
||||
|
||||
/* scale gridsize */
|
||||
|
||||
@@ -38,11 +38,9 @@
|
||||
exports a map brush
|
||||
*/
|
||||
|
||||
typedef vec_t vec2_t[2];
|
||||
|
||||
static vec_t Det3x3( vec_t a00, vec_t a01, vec_t a02,
|
||||
vec_t a10, vec_t a11, vec_t a12,
|
||||
vec_t a20, vec_t a21, vec_t a22 ){
|
||||
static float Det3x3( float a00, float a01, float a02,
|
||||
float a10, float a11, float a12,
|
||||
float a20, float a21, float a22 ){
|
||||
return
|
||||
a00 * ( a11 * a22 - a12 * a21 )
|
||||
- a01 * ( a10 * a22 - a12 * a20 )
|
||||
@@ -53,10 +51,8 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
||||
bspDrawSurface_t *s;
|
||||
int i;
|
||||
int t;
|
||||
vec_t best = 0;
|
||||
vec_t thisarea;
|
||||
vec3_t normdiff;
|
||||
vec3_t v1v0, v2v0, norm;
|
||||
float best = 0;
|
||||
float thisarea;
|
||||
bspDrawVert_t *vert[3];
|
||||
winding_t *polygon;
|
||||
plane_t *buildPlane = &mapplanes[buildSide->planenum];
|
||||
@@ -80,16 +76,13 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
||||
vert[1] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 1]];
|
||||
vert[2] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 2]];
|
||||
if ( s->surfaceType == MST_PLANAR && VectorCompare( vert[0]->normal, vert[1]->normal ) && VectorCompare( vert[1]->normal, vert[2]->normal ) ) {
|
||||
VectorSubtract( vert[0]->normal, buildPlane->normal, normdiff );
|
||||
if ( VectorLength( normdiff ) >= normalEpsilon ) {
|
||||
if ( vector3_length( vert[0]->normal - buildPlane->normal() ) >= normalEpsilon ) {
|
||||
continue;
|
||||
}
|
||||
VectorSubtract( vert[1]->normal, buildPlane->normal, normdiff );
|
||||
if ( VectorLength( normdiff ) >= normalEpsilon ) {
|
||||
if ( vector3_length( vert[1]->normal - buildPlane->normal() ) >= normalEpsilon ) {
|
||||
continue;
|
||||
}
|
||||
VectorSubtract( vert[2]->normal, buildPlane->normal, normdiff );
|
||||
if ( VectorLength( normdiff ) >= normalEpsilon ) {
|
||||
if ( vector3_length( vert[2]->normal - buildPlane->normal() ) >= normalEpsilon ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -97,23 +90,20 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
||||
{
|
||||
// this is more prone to roundoff errors, but with embedded
|
||||
// models, there is no better way
|
||||
VectorSubtract( vert[1]->xyz, vert[0]->xyz, v1v0 );
|
||||
VectorSubtract( vert[2]->xyz, vert[0]->xyz, v2v0 );
|
||||
CrossProduct( v2v0, v1v0, norm );
|
||||
VectorNormalize( norm, norm );
|
||||
VectorSubtract( norm, buildPlane->normal, normdiff );
|
||||
if ( VectorLength( normdiff ) >= normalEpsilon ) {
|
||||
Plane3f plane;
|
||||
PlaneFromPoints( plane, vert[0]->xyz, vert[1]->xyz, vert[2]->xyz );
|
||||
if ( vector3_length( plane.normal() - buildPlane->normal() ) >= normalEpsilon ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// fixme? better distance epsilon
|
||||
if ( abs( DotProduct( vert[0]->xyz, buildPlane->normal ) - buildPlane->dist ) > 1 ) {
|
||||
if ( abs( plane3_distance_to_point( buildPlane->plane, vert[0]->xyz ) ) > 1 ) {
|
||||
continue;
|
||||
}
|
||||
if ( abs( DotProduct( vert[1]->xyz, buildPlane->normal ) - buildPlane->dist ) > 1 ) {
|
||||
if ( abs( plane3_distance_to_point( buildPlane->plane, vert[1]->xyz ) ) > 1 ) {
|
||||
continue;
|
||||
}
|
||||
if ( abs( DotProduct( vert[2]->xyz, buildPlane->normal ) - buildPlane->dist ) > 1 ) {
|
||||
if ( abs( plane3_distance_to_point( buildPlane->plane, vert[2]->xyz ) ) > 1 ) {
|
||||
continue;
|
||||
}
|
||||
// Okay. Correct surface type, correct shader, correct plane. Let's start with the business...
|
||||
@@ -123,16 +113,12 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
||||
// 0: 1, 2
|
||||
// 1: 2, 0
|
||||
// 2; 0, 1
|
||||
vec3_t *v1 = &vert[( i + 1 ) % 3]->xyz;
|
||||
vec3_t *v2 = &vert[( i + 2 ) % 3]->xyz;
|
||||
vec3_t triNormal;
|
||||
vec_t triDist;
|
||||
vec3_t sideDirection;
|
||||
// we now need to generate triNormal and triDist so that they represent the plane spanned by normal and (v2 - v1).
|
||||
VectorSubtract( *v2, *v1, sideDirection );
|
||||
CrossProduct( sideDirection, buildPlane->normal, triNormal );
|
||||
triDist = DotProduct( *v1, triNormal );
|
||||
ChopWindingInPlace( &polygon, triNormal, triDist, distanceEpsilon );
|
||||
const Vector3& v1 = vert[( i + 1 ) % 3]->xyz;
|
||||
const Vector3& v2 = vert[( i + 2 ) % 3]->xyz;
|
||||
// we now need to generate the plane spanned by normal and (v2 - v1).
|
||||
Plane3f plane( vector3_cross( v2 - v1, buildPlane->normal() ), 0 );
|
||||
plane.dist() = vector3_dot( v1, plane.normal() );
|
||||
ChopWindingInPlace( &polygon, plane, distanceEpsilon );
|
||||
if ( !polygon ) {
|
||||
goto exwinding;
|
||||
}
|
||||
@@ -157,7 +143,7 @@ exwinding:
|
||||
}
|
||||
|
||||
#define FRAC( x ) ( ( x ) - floor( x ) )
|
||||
static void ConvertOriginBrush( FILE *f, int num, vec3_t origin, bool brushPrimitives ){
|
||||
static void ConvertOriginBrush( FILE *f, int num, const Vector3& origin, bool brushPrimitives ){
|
||||
int originSize = 256;
|
||||
|
||||
char pattern[6][7][4] = {
|
||||
@@ -217,14 +203,14 @@ static void ConvertOriginBrush( FILE *f, int num, vec3_t origin, bool brushPrimi
|
||||
fprintf( f, "\t}\n\n" );
|
||||
}
|
||||
|
||||
static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bool brushPrimitives ){
|
||||
static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, const Vector3& origin, bool brushPrimitives ){
|
||||
int i;
|
||||
bspBrushSide_t *side;
|
||||
side_t *buildSide;
|
||||
bspShader_t *shader;
|
||||
const char *texture;
|
||||
plane_t *buildPlane;
|
||||
vec3_t pts[ 3 ];
|
||||
Vector3 pts[ 3 ];
|
||||
|
||||
|
||||
/* clear out build brush */
|
||||
@@ -325,12 +311,11 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, vec3_t origin
|
||||
}
|
||||
|
||||
{
|
||||
vec3_t vecs[ 2 ];
|
||||
MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] );
|
||||
VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] );
|
||||
VectorAdd( pts[ 0 ], origin, pts[ 0 ] );
|
||||
VectorMA( pts[ 0 ], 256.0f, vecs[ 0 ], pts[ 1 ] );
|
||||
VectorMA( pts[ 0 ], 256.0f, vecs[ 1 ], pts[ 2 ] );
|
||||
Vector3 vecs[ 2 ];
|
||||
MakeNormalVectors( buildPlane->normal(), vecs[ 0 ], vecs[ 1 ] );
|
||||
pts[ 0 ] = buildPlane->normal() * buildPlane->dist() + origin;
|
||||
pts[ 1 ] = pts[ 0 ] + vecs[ 0 ] * 256.0f;
|
||||
pts[ 2 ] = pts[ 0 ] + vecs[ 1 ] * 256.0f;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -366,14 +351,14 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, vec3_t origin
|
||||
fprintf( f, "\t}\n\n" );
|
||||
}
|
||||
|
||||
static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bool brushPrimitives ){
|
||||
static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& origin, bool brushPrimitives ){
|
||||
int i, j;
|
||||
bspBrushSide_t *side;
|
||||
side_t *buildSide;
|
||||
bspShader_t *shader;
|
||||
const char *texture;
|
||||
plane_t *buildPlane;
|
||||
vec3_t pts[ 3 ];
|
||||
Vector3 pts[ 3 ];
|
||||
bspDrawVert_t *vert[3];
|
||||
|
||||
|
||||
@@ -469,8 +454,8 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
|
||||
// st-texcoords -> texMat block
|
||||
// start out with dummy
|
||||
VectorSet( buildSide->texMat[0], 1 / 32.0, 0, 0 );
|
||||
VectorSet( buildSide->texMat[1], 0, 1 / 32.0, 0 );
|
||||
buildSide->texMat[0] = { 1 / 32.0, 0, 0 };
|
||||
buildSide->texMat[1] = { 0, 1 / 32.0, 0 };
|
||||
|
||||
// find surface for this side (by brute force)
|
||||
// surface format:
|
||||
@@ -490,11 +475,11 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
/* recheck and fix winding points, fails occur somehow */
|
||||
int match = 0;
|
||||
for ( j = 0; j < buildSide->winding->numpoints; j++ ){
|
||||
if ( fabs( DotProduct( buildSide->winding->p[ j ], buildPlane->normal ) - buildPlane->dist ) >= distanceEpsilon ) {
|
||||
if ( fabs( plane3_distance_to_point( buildPlane->plane, buildSide->winding->p[ j ] ) ) >= distanceEpsilon ) {
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
VectorCopy( buildSide->winding->p[ j ], pts[ match ] );
|
||||
pts[ match ] = buildSide->winding->p[ j ];
|
||||
match++;
|
||||
/* got 3 fine points? */
|
||||
if( match > 2 )
|
||||
@@ -504,9 +489,9 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
|
||||
if( match > 2 ){
|
||||
//Sys_Printf( "pointsKK " );
|
||||
vec4_t testplane;
|
||||
if ( PlaneFromPoints( testplane, pts[0], pts[1], pts[2] ) ){
|
||||
if( !PlaneEqual( buildPlane, testplane, testplane[3] ) ){
|
||||
Plane3f testplane;
|
||||
if ( PlaneFromPoints( testplane, pts ) ){
|
||||
if( !PlaneEqual( buildPlane, testplane ) ){
|
||||
//Sys_Printf( "1: %f %f %f %f\n2: %f %f %f %f\n", buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], buildPlane->dist, testplane[0], testplane[1], testplane[2], testplane[3] );
|
||||
match--;
|
||||
//Sys_Printf( "planentEQ " );
|
||||
@@ -522,34 +507,33 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
//Sys_Printf( "ok " );
|
||||
/* offset by origin */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
VectorAdd( pts[ j ], origin, pts[ j ] );
|
||||
pts[ j ] += origin;
|
||||
}
|
||||
else{
|
||||
vec3_t vecs[ 2 ];
|
||||
MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] );
|
||||
VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] );
|
||||
VectorAdd( pts[ 0 ], origin, pts[ 0 ] );
|
||||
VectorMA( pts[ 0 ], 256.0f, vecs[ 0 ], pts[ 1 ] );
|
||||
VectorMA( pts[ 0 ], 256.0f, vecs[ 1 ], pts[ 2 ] );
|
||||
Vector3 vecs[ 2 ];
|
||||
MakeNormalVectors( buildPlane->normal(), vecs[ 0 ], vecs[ 1 ] );
|
||||
pts[ 0 ] = buildPlane->normal() * buildPlane->dist() + origin;
|
||||
pts[ 1 ] = pts[ 0 ] + vecs[ 0 ] * 256.0f;
|
||||
pts[ 2 ] = pts[ 0 ] + vecs[ 1 ] * 256.0f;
|
||||
//Sys_Printf( "not\n" );
|
||||
}
|
||||
|
||||
if ( vert[0] && vert[1] && vert[2] ) {
|
||||
if ( brushPrimitives ) {
|
||||
int i;
|
||||
vec3_t texX, texY;
|
||||
vec2_t xyI, xyJ, xyK;
|
||||
vec2_t stI, stJ, stK;
|
||||
vec_t D, D0, D1, D2;
|
||||
Vector3 texX, texY;
|
||||
float xyI[2], xyJ[2], xyK[2];
|
||||
float stI[2], stJ[2], stK[2];
|
||||
float D, D0, D1, D2;
|
||||
|
||||
ComputeAxisBase( buildPlane->normal, texX, texY );
|
||||
ComputeAxisBase( buildPlane->normal(), texX, texY );
|
||||
|
||||
xyI[0] = DotProduct( vert[0]->xyz, texX );
|
||||
xyI[1] = DotProduct( vert[0]->xyz, texY );
|
||||
xyJ[0] = DotProduct( vert[1]->xyz, texX );
|
||||
xyJ[1] = DotProduct( vert[1]->xyz, texY );
|
||||
xyK[0] = DotProduct( vert[2]->xyz, texX );
|
||||
xyK[1] = DotProduct( vert[2]->xyz, texY );
|
||||
xyI[0] = vector3_dot( vert[0]->xyz, texX );
|
||||
xyI[1] = vector3_dot( vert[0]->xyz, texY );
|
||||
xyJ[0] = vector3_dot( vert[1]->xyz, texX );
|
||||
xyJ[1] = vector3_dot( vert[1]->xyz, texY );
|
||||
xyK[0] = vector3_dot( vert[2]->xyz, texX );
|
||||
xyK[1] = vector3_dot( vert[2]->xyz, texY );
|
||||
stI[0] = vert[0]->st[0]; stI[1] = vert[0]->st[1];
|
||||
stJ[0] = vert[1]->st[0]; stJ[1] = vert[1]->st[1];
|
||||
stK[0] = vert[2]->st[0]; stK[1] = vert[2]->st[1];
|
||||
@@ -581,12 +565,12 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
xyJ[0], xyJ[1], stJ[i],
|
||||
xyK[0], xyK[1], stK[i]
|
||||
);
|
||||
VectorSet( buildSide->texMat[i], D0 / D, D1 / D, D2 / D );
|
||||
buildSide->texMat[i] = { D0 / D, D1 / D, D2 / D };
|
||||
}
|
||||
}
|
||||
else{
|
||||
fprintf( stderr, "degenerate triangle found when solving texMat equations for\n(%f %f %f) (%f %f %f) (%f %f %f)\n( %f %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n",
|
||||
buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2],
|
||||
buildPlane->normal()[0], buildPlane->normal()[1], buildPlane->normal()[2],
|
||||
vert[0]->normal[0], vert[0]->normal[1], vert[0]->normal[2],
|
||||
texX[0], texX[1], texX[2], texY[0], texY[1], texY[2],
|
||||
vert[0]->xyz[0], vert[0]->xyz[1], vert[0]->xyz[2], xyI[0], xyI[1],
|
||||
@@ -611,13 +595,13 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
{
|
||||
// invert QuakeTextureVecs
|
||||
int i;
|
||||
vec3_t vecs[2];
|
||||
Vector3 vecs[2];
|
||||
int sv, tv;
|
||||
vec2_t stI, stJ, stK;
|
||||
vec3_t sts[2];
|
||||
vec2_t shift, scale;
|
||||
vec_t rotate;
|
||||
vec_t D, D0, D1, D2;
|
||||
float stI[2], stJ[2], stK[2];
|
||||
Vector3 sts[2];
|
||||
float shift[2], scale[2];
|
||||
float rotate;
|
||||
float D, D0, D1, D2;
|
||||
|
||||
TextureAxisFromPlane( buildPlane, vecs[0], vecs[1] );
|
||||
if ( vecs[0][0] ) {
|
||||
@@ -666,18 +650,18 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
vert[1]->xyz[sv], vert[1]->xyz[tv], stJ[i],
|
||||
vert[2]->xyz[sv], vert[2]->xyz[tv], stK[i]
|
||||
);
|
||||
VectorSet( sts[i], D0 / D, D1 / D, D2 / D );
|
||||
sts[i] = { D0 / D, D1 / D, D2 / D };
|
||||
//Sys_Printf( "%.3f %.3f %.3f \n", sts[i][0], sts[i][1], sts[i][2] );
|
||||
}
|
||||
}
|
||||
else{
|
||||
fprintf( stderr, "degenerate triangle found when solving texDef equations\n" ); // FIXME add stuff here
|
||||
VectorSet( sts[0], 2.f, 0.f, 0.f );
|
||||
VectorSet( sts[1], 0.f, -2.f, 0.f );
|
||||
sts[0] = { 2.f, 0.f, 0.f };
|
||||
sts[1] = { 0.f, -2.f, 0.f };
|
||||
}
|
||||
// now we must solve:
|
||||
// // now we must invert:
|
||||
// ang = rotate / 180 * Q_PI;
|
||||
// ang = degrees_to_radians( rotate );
|
||||
// sinv = sin(ang);
|
||||
// cosv = cos(ang);
|
||||
// ns = cosv * vecs[0][sv];
|
||||
@@ -690,7 +674,7 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
// vecsrotscaled[1][tv] = nt / scale[1];
|
||||
scale[0] = 1.0 / sqrt( sts[0][0] * sts[0][0] + sts[0][1] * sts[0][1] );
|
||||
scale[1] = 1.0 / sqrt( sts[1][0] * sts[1][0] + sts[1][1] * sts[1][1] );
|
||||
rotate = atan2( sts[0][1] * vecs[0][sv] - sts[1][0] * vecs[1][tv], sts[0][0] * vecs[0][sv] + sts[1][1] * vecs[1][tv] ) * ( 180.0f / Q_PI );
|
||||
rotate = radians_to_degrees( atan2( sts[0][1] * vecs[0][sv] - sts[1][0] * vecs[1][tv], sts[0][0] * vecs[0][sv] + sts[1][1] * vecs[1][tv] ) );
|
||||
shift[0] = buildSide->shaderInfo->shaderWidth * FRAC( sts[0][2] / buildSide->shaderInfo->shaderWidth );
|
||||
shift[1] = buildSide->shaderInfo->shaderHeight * FRAC( sts[1][2] / buildSide->shaderInfo->shaderHeight );
|
||||
|
||||
@@ -708,7 +692,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
}
|
||||
else
|
||||
{
|
||||
//vec3_t vecs[ 2 ];
|
||||
if ( !striEqualPrefix( buildSide->shaderInfo->shader, "textures/common/" ) ) {
|
||||
if ( !strEqual( buildSide->shaderInfo->shader, "noshader" ) ) {
|
||||
if ( !strEqual( buildSide->shaderInfo->shader, "default" ) ) {
|
||||
@@ -717,12 +700,7 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] );
|
||||
VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] );
|
||||
VectorMA( pts[ 0 ], 256.0f, vecs[ 1 ], pts[ 2 ] );
|
||||
VectorMA( pts[ 0 ], 256.0f, vecs[ 0 ], pts[ 1 ] );
|
||||
*/
|
||||
|
||||
if ( brushPrimitives ) {
|
||||
fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n",
|
||||
pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ],
|
||||
@@ -828,12 +806,11 @@ for ( i = 0; i < brush->numSides; i++ )
|
||||
|
||||
*/
|
||||
|
||||
static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, vec3_t origin ){
|
||||
static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, const Vector3& origin ){
|
||||
int x, y;
|
||||
bspShader_t *shader;
|
||||
const char *texture;
|
||||
bspDrawVert_t *dv;
|
||||
vec3_t xyz;
|
||||
|
||||
|
||||
/* only patches */
|
||||
@@ -877,7 +854,7 @@ static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, vec3_t origin
|
||||
dv = &bspDrawVerts[ ds->firstVert + ( y * ds->patchWidth ) + x ];
|
||||
|
||||
/* offset it */
|
||||
VectorAdd( origin, dv->xyz, xyz );
|
||||
const Vector3 xyz = dv->xyz + origin;
|
||||
|
||||
/* print vertex */
|
||||
fprintf( f, " ( %f %f %f %f %f )", xyz[ 0 ], xyz[ 1 ], xyz[ 2 ], dv->st[ 0 ], dv->st[ 1 ] );
|
||||
@@ -900,7 +877,7 @@ static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, vec3_t origin
|
||||
exports a bsp model to a map file
|
||||
*/
|
||||
|
||||
static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, bool brushPrimitives ){
|
||||
static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, const Vector3& origin, bool brushPrimitives ){
|
||||
int i, num;
|
||||
bspBrush_t *brush;
|
||||
bspDrawSurface_t *ds;
|
||||
@@ -911,9 +888,8 @@ static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origi
|
||||
AUTOEXPAND_BY_REALLOC( mapplanes, nummapplanes, allocatedmapplanes, 1024 );
|
||||
for ( i = 0; i < numBSPPlanes; i++ )
|
||||
{
|
||||
VectorCopy( bspPlanes[ i ].normal, mapplanes[ i ].normal );
|
||||
mapplanes[ i ].dist = bspPlanes[ i ].dist;
|
||||
mapplanes[ i ].type = PlaneTypeForNormal( mapplanes[ i ].normal );
|
||||
mapplanes[ i ].plane = bspPlanes[ i ];
|
||||
mapplanes[ i ].type = PlaneTypeForNormal( mapplanes[ i ].normal() );
|
||||
mapplanes[ i ].hash_chain = 0;
|
||||
}
|
||||
|
||||
@@ -1048,7 +1024,7 @@ int ConvertBSPToMap_Ext( char *bspName, bool brushPrimitives ){
|
||||
model = &bspModels[ modelNum ];
|
||||
|
||||
/* get entity origin */
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
e->vectorForKey( "origin", origin );
|
||||
|
||||
/* convert model */
|
||||
|
||||
@@ -44,7 +44,7 @@ int lastLightmap = -1;
|
||||
int objVertexCount = 0;
|
||||
int objLastShaderNum = -1;
|
||||
|
||||
static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin, const int* lmIndices ){
|
||||
static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, const Vector3& origin, const int* lmIndices ){
|
||||
int i, v, a, b, c;
|
||||
bspDrawVert_t *dv;
|
||||
|
||||
@@ -127,7 +127,7 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr
|
||||
exports a bsp model to an ase chunk
|
||||
*/
|
||||
|
||||
static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, const int* lmIndices ){
|
||||
static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, const Vector3& origin, const int* lmIndices ){
|
||||
int i, s;
|
||||
bspDrawSurface_t *ds;
|
||||
|
||||
@@ -358,7 +358,7 @@ int ConvertBSPToOBJ( char *bspName ){
|
||||
model = &bspModels[ modelNum ];
|
||||
|
||||
/* get entity origin */
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
e->vectorForKey( "origin", origin );
|
||||
|
||||
/* convert model */
|
||||
|
||||
+108
-168
@@ -38,12 +38,12 @@
|
||||
struct decalProjector_t
|
||||
{
|
||||
shaderInfo_t *si;
|
||||
vec3_t mins, maxs;
|
||||
vec3_t center;
|
||||
MinMax minmax;
|
||||
Vector3 center;
|
||||
float radius, radius2;
|
||||
int numPlanes; /* either 5 or 6, for quad or triangle projectors */
|
||||
vec4_t planes[ 6 ];
|
||||
vec4_t texMat[ 2 ];
|
||||
Plane3f planes[ 6 ];
|
||||
Vector4 texMat[ 2 ];
|
||||
};
|
||||
|
||||
static int numProjectors = 0;
|
||||
@@ -51,37 +51,10 @@ static decalProjector_t projectors[ MAX_PROJECTORS ];
|
||||
|
||||
static int numDecalSurfaces = 0;
|
||||
|
||||
static vec3_t entityOrigin;
|
||||
static Vector3 entityOrigin;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
DVectorNormalize()
|
||||
normalizes a vector, returns the length, operates using doubles
|
||||
*/
|
||||
|
||||
typedef double dvec_t;
|
||||
typedef dvec_t dvec3_t[ 3 ];
|
||||
|
||||
dvec_t DVectorNormalize( dvec3_t in, dvec3_t out ){
|
||||
dvec_t len, ilen;
|
||||
|
||||
|
||||
len = (dvec_t) sqrt( in[ 0 ] * in[ 0 ] + in[ 1 ] * in[ 1 ] + in[ 2 ] * in[ 2 ] );
|
||||
if ( len == 0.0 ) {
|
||||
VectorClear( out );
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
ilen = 1.0 / len;
|
||||
out[ 0 ] = in[ 0 ] * ilen;
|
||||
out[ 1 ] = in[ 1 ] * ilen;
|
||||
out[ 2 ] = in[ 2 ] * ilen;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
MakeTextureMatrix()
|
||||
@@ -91,21 +64,18 @@ dvec_t DVectorNormalize( dvec3_t in, dvec3_t out ){
|
||||
|
||||
#define Vector2Subtract( a,b,c ) ( ( c )[ 0 ] = ( a )[ 0 ] - ( b )[ 0 ], ( c )[ 1 ] = ( a )[ 1 ] - ( b )[ 1 ] )
|
||||
|
||||
static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *c ){
|
||||
static bool MakeTextureMatrix( decalProjector_t *dp, const Plane3f& projection, bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *c ){
|
||||
int i, j;
|
||||
double bb, s, t, d;
|
||||
dvec3_t pa, pb, pc;
|
||||
dvec3_t bary, xyz;
|
||||
dvec3_t vecs[ 3 ], axis[ 3 ], lengths;
|
||||
double bb, s, t;
|
||||
DoubleVector3 pa, pb, pc;
|
||||
DoubleVector3 bary, xyz;
|
||||
DoubleVector3 vecs[ 3 ], axis[ 3 ], lengths;
|
||||
|
||||
|
||||
/* project triangle onto plane of projection */
|
||||
d = DotProduct( a->xyz, projection ) - projection[ 3 ];
|
||||
VectorMA( a->xyz, -d, projection, pa );
|
||||
d = DotProduct( b->xyz, projection ) - projection[ 3 ];
|
||||
VectorMA( b->xyz, -d, projection, pb );
|
||||
d = DotProduct( c->xyz, projection ) - projection[ 3 ];
|
||||
VectorMA( c->xyz, -d, projection, pc );
|
||||
pa = plane3_project_point( projection, a->xyz );
|
||||
pb = plane3_project_point( projection, b->xyz );
|
||||
pc = plane3_project_point( projection, c->xyz );
|
||||
|
||||
/* two methods */
|
||||
#if 1
|
||||
@@ -142,8 +112,8 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV
|
||||
xyz[ 1 ] = bary[ 0 ] * pa[ 1 ] + bary[ 1 ] * pb[ 1 ] + bary[ 2 ] * pc[ 1 ];
|
||||
xyz[ 2 ] = bary[ 0 ] * pa[ 2 ] + bary[ 1 ] * pb[ 2 ] + bary[ 2 ] * pc[ 2 ];
|
||||
|
||||
//% VectorSubtract( xyz, origin, vecs[ 0 ] );
|
||||
VectorSubtract( xyz, pa, vecs[ 0 ] );
|
||||
//% vecs[ 0 ] = xyz - origin;
|
||||
vecs[ 0 ] = xyz - pa;
|
||||
|
||||
/* calculate t vector */
|
||||
s = a->st[ 0 ] + 0.0;
|
||||
@@ -156,29 +126,31 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV
|
||||
xyz[ 1 ] = bary[ 0 ] * pa[ 1 ] + bary[ 1 ] * pb[ 1 ] + bary[ 2 ] * pc[ 1 ];
|
||||
xyz[ 2 ] = bary[ 0 ] * pa[ 2 ] + bary[ 1 ] * pb[ 2 ] + bary[ 2 ] * pc[ 2 ];
|
||||
|
||||
//% VectorSubtract( xyz, origin, vecs[ 1 ] );
|
||||
VectorSubtract( xyz, pa, vecs[ 1 ] );
|
||||
//% vecs[ 1 ] = xyz - origin;
|
||||
vecs[ 1 ] = xyz - pa;
|
||||
|
||||
/* calcuate r vector */
|
||||
VectorScale( projection, -1.0, vecs[ 2 ] );
|
||||
vecs[ 2 ] = -projection.normal();
|
||||
|
||||
/* calculate transform axis */
|
||||
for ( i = 0; i < 3; i++ )
|
||||
lengths[ i ] = DVectorNormalize( vecs[ i ], axis[ i ] );
|
||||
for ( i = 0; i < 3; i++ ){
|
||||
axis[ i ] = vecs[ i ];
|
||||
lengths[ i ] = VectorNormalize( axis[ i ] );
|
||||
}
|
||||
for ( i = 0; i < 2; i++ )
|
||||
for ( j = 0; j < 3; j++ )
|
||||
dp->texMat[ i ][ j ] = lengths[ i ] > 0.0 ? ( axis[ i ][ j ] / lengths[ i ] ) : 0.0;
|
||||
dp->texMat[ i ][ j ] = lengths[ i ] != 0.0 ? ( axis[ i ][ j ] / lengths[ i ] ) : 0.0;
|
||||
//% dp->texMat[ i ][ j ] = fabs( vecs[ i ][ j ] ) > 0.0 ? (1.0 / vecs[ i ][ j ]) : 0.0;
|
||||
//% dp->texMat[ i ][ j ] = axis[ i ][ j ] > 0.0 ? (1.0 / axis[ i ][ j ]) : 0.0;
|
||||
|
||||
/* calculalate translation component */
|
||||
dp->texMat[ 0 ][ 3 ] = a->st[ 0 ] - DotProduct( a->xyz, dp->texMat[ 0 ] );
|
||||
dp->texMat[ 1 ][ 3 ] = a->st[ 1 ] - DotProduct( a->xyz, dp->texMat[ 1 ] );
|
||||
dp->texMat[ 0 ][ 3 ] = a->st[ 0 ] - vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() );
|
||||
dp->texMat[ 1 ][ 3 ] = a->st[ 1 ] - vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() );
|
||||
}
|
||||
#else
|
||||
{
|
||||
int k;
|
||||
dvec3_t origin, deltas[ 3 ];
|
||||
DoubleVector3 deltas[ 3 ];
|
||||
double texDeltas[ 3 ][ 2 ];
|
||||
double delta, texDelta;
|
||||
|
||||
@@ -186,9 +158,9 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV
|
||||
/* new code */
|
||||
|
||||
/* calculate deltas */
|
||||
VectorSubtract( pa, pb, deltas[ 0 ] );
|
||||
VectorSubtract( pa, pc, deltas[ 1 ] );
|
||||
VectorSubtract( pb, pc, deltas[ 2 ] );
|
||||
deltas[ 0 ] = pa - pb;
|
||||
deltas[ 1 ] = pa - pc;
|
||||
deltas[ 2 ] = pb - pc;
|
||||
Vector2Subtract( a->st, b->st, texDeltas[ 0 ] );
|
||||
Vector2Subtract( a->st, c->st, texDeltas[ 1 ] );
|
||||
Vector2Subtract( b->st, c->st, texDeltas[ 2 ] );
|
||||
@@ -223,42 +195,42 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV
|
||||
}
|
||||
|
||||
/* set translation component */
|
||||
dp->texMat[ i ][ 3 ] = a->st[ i ] - DotProduct( pa, dp->texMat[ i ] );
|
||||
dp->texMat[ i ][ 3 ] = a->st[ i ] - vector3_dot( pa, dp->texMat[ i ].vec3() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* debug code */
|
||||
#if 1
|
||||
Sys_Printf( "Mat: [ %f %f %f %f ] [ %f %f %f %f ] Theta: %f (%f)\n",
|
||||
Sys_Printf( "Mat: [ %f %f %f %f ] [ %f %f %f %f ] Theta: %lf (%lf)\n",
|
||||
dp->texMat[ 0 ][ 0 ], dp->texMat[ 0 ][ 1 ], dp->texMat[ 0 ][ 2 ], dp->texMat[ 0 ][ 3 ],
|
||||
dp->texMat[ 1 ][ 0 ], dp->texMat[ 1 ][ 1 ], dp->texMat[ 1 ][ 2 ], dp->texMat[ 1 ][ 3 ],
|
||||
RAD2DEG( acos( DotProduct( dp->texMat[ 0 ], dp->texMat[ 1 ] ) ) ),
|
||||
RAD2DEG( acos( DotProduct( axis[ 0 ], axis[ 1 ] ) ) ) );
|
||||
radians_to_degrees( acos( vector3_dot( dp->texMat[ 0 ].vec3(), dp->texMat[ 1 ].vec3() ) ) ),
|
||||
radians_to_degrees( acos( vector3_dot( axis[ 0 ], axis[ 1 ] ) ) ) );
|
||||
|
||||
Sys_Printf( "XYZ: %f %f %f ST: %f %f ST(t): %f %f\n",
|
||||
a->xyz[ 0 ], a->xyz[ 1 ], a->xyz[ 2 ],
|
||||
a->st[ 0 ], a->st[ 1 ],
|
||||
DotProduct( a->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ], DotProduct( a->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ] );
|
||||
vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ], vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ] );
|
||||
#endif
|
||||
|
||||
/* test texture matrix */
|
||||
s = DotProduct( a->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = DotProduct( a->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ];
|
||||
s = vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
if ( fabs( s - a->st[ 0 ] ) > 0.01 || fabs( t - a->st[ 1 ] ) > 0.01 ) {
|
||||
Sys_Printf( "Bad texture matrix! (A) (%f, %f) != (%f, %f)\n",
|
||||
s, t, a->st[ 0 ], a->st[ 1 ] );
|
||||
//% return false;
|
||||
}
|
||||
s = DotProduct( b->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = DotProduct( b->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ];
|
||||
s = vector3_dot( b->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( b->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
if ( fabs( s - b->st[ 0 ] ) > 0.01 || fabs( t - b->st[ 1 ] ) > 0.01 ) {
|
||||
Sys_Printf( "Bad texture matrix! (B) (%f, %f) != (%f, %f)\n",
|
||||
s, t, b->st[ 0 ], b->st[ 1 ] );
|
||||
//% return false;
|
||||
}
|
||||
s = DotProduct( c->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = DotProduct( c->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ];
|
||||
s = vector3_dot( c->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( c->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
if ( fabs( s - c->st[ 0 ] ) > 0.01 || fabs( t - c->st[ 1 ] ) > 0.01 ) {
|
||||
Sys_Printf( "Bad texture matrix! (C) (%f, %f) != (%f, %f)\n",
|
||||
s, t, c->st[ 0 ], c->st[ 1 ] );
|
||||
@@ -277,7 +249,7 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV
|
||||
note: non-normalized axes will screw up the plane transform
|
||||
*/
|
||||
|
||||
static void TransformDecalProjector( decalProjector_t *in, vec3_t axis[ 3 ], vec3_t origin, decalProjector_t *out ){
|
||||
static void TransformDecalProjector( decalProjector_t *in, Vector3 axis[ 3 ], const Vector3& origin, decalProjector_t *out ){
|
||||
int i;
|
||||
|
||||
|
||||
@@ -286,28 +258,28 @@ static void TransformDecalProjector( decalProjector_t *in, vec3_t axis[ 3 ], vec
|
||||
out->numPlanes = in->numPlanes;
|
||||
|
||||
/* translate bounding box and sphere (note: rotated projector bounding box will be invalid!) */
|
||||
VectorSubtract( in->mins, origin, out->mins );
|
||||
VectorSubtract( in->maxs, origin, out->maxs );
|
||||
VectorSubtract( in->center, origin, out->center );
|
||||
out->minmax.mins = in->minmax.mins - origin;
|
||||
out->minmax.maxs = in->minmax.maxs - origin;
|
||||
out->center = in->center - origin;
|
||||
out->radius = in->radius;
|
||||
out->radius2 = in->radius2;
|
||||
|
||||
/* translate planes */
|
||||
for ( i = 0; i < in->numPlanes; i++ )
|
||||
{
|
||||
out->planes[ i ][ 0 ] = DotProduct( in->planes[ i ], axis[ 0 ] );
|
||||
out->planes[ i ][ 1 ] = DotProduct( in->planes[ i ], axis[ 1 ] );
|
||||
out->planes[ i ][ 2 ] = DotProduct( in->planes[ i ], axis[ 2 ] );
|
||||
out->planes[ i ][ 3 ] = in->planes[ i ][ 3 ] - DotProduct( out->planes[ i ], origin );
|
||||
out->planes[ i ].a = vector3_dot( in->planes[ i ].normal(), axis[ 0 ] );
|
||||
out->planes[ i ].b = vector3_dot( in->planes[ i ].normal(), axis[ 1 ] );
|
||||
out->planes[ i ].c = vector3_dot( in->planes[ i ].normal(), axis[ 2 ] );
|
||||
out->planes[ i ].d = in->planes[ i ].dist() - vector3_dot( out->planes[ i ].normal(), origin );
|
||||
}
|
||||
|
||||
/* translate texture matrix */
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
out->texMat[ i ][ 0 ] = DotProduct( in->texMat[ i ], axis[ 0 ] );
|
||||
out->texMat[ i ][ 1 ] = DotProduct( in->texMat[ i ], axis[ 1 ] );
|
||||
out->texMat[ i ][ 2 ] = DotProduct( in->texMat[ i ], axis[ 2 ] );
|
||||
out->texMat[ i ][ 3 ] = in->texMat[ i ][ 3 ] + DotProduct( out->texMat[ i ], origin );
|
||||
out->texMat[ i ][ 0 ] = vector3_dot( in->texMat[ i ].vec3(), axis[ 0 ] );
|
||||
out->texMat[ i ][ 1 ] = vector3_dot( in->texMat[ i ].vec3(), axis[ 1 ] );
|
||||
out->texMat[ i ][ 2 ] = vector3_dot( in->texMat[ i ].vec3(), axis[ 2 ] );
|
||||
out->texMat[ i ][ 3 ] = vector3_dot( out->texMat[ i ].vec3(), origin ) + in->texMat[ i ][ 3 ];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,10 +290,9 @@ static void TransformDecalProjector( decalProjector_t *in, vec3_t axis[ 3 ], vec
|
||||
creates a new decal projector from a triangle
|
||||
*/
|
||||
|
||||
static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distance, int numVerts, bspDrawVert_t **dv ){
|
||||
static int MakeDecalProjector( shaderInfo_t *si, const Plane3f& projection, float distance, int numVerts, bspDrawVert_t **dv ){
|
||||
int i, j;
|
||||
decalProjector_t *dp;
|
||||
vec3_t xyz;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
@@ -349,19 +320,16 @@ static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distan
|
||||
}
|
||||
|
||||
/* bound the projector */
|
||||
ClearBounds( dp->mins, dp->maxs );
|
||||
dp->minmax.clear();
|
||||
for ( i = 0; i < numVerts; i++ )
|
||||
{
|
||||
AddPointToBounds( dv[ i ]->xyz, dp->mins, dp->maxs );
|
||||
VectorMA( dv[ i ]->xyz, distance, projection, xyz );
|
||||
AddPointToBounds( xyz, dp->mins, dp->maxs );
|
||||
dp->minmax.extend( dv[ i ]->xyz );
|
||||
dp->minmax.extend( dv[ i ]->xyz + projection.normal() * distance );
|
||||
}
|
||||
|
||||
/* make bouding sphere */
|
||||
VectorAdd( dp->mins, dp->maxs, dp->center );
|
||||
VectorScale( dp->center, 0.5f, dp->center );
|
||||
VectorSubtract( dp->maxs, dp->center, xyz );
|
||||
dp->radius = VectorLength( xyz );
|
||||
dp->center = dp->minmax.origin();
|
||||
dp->radius = vector3_length( dp->minmax.maxs - dp->center );
|
||||
dp->radius2 = dp->radius * dp->radius;
|
||||
|
||||
/* make the front plane */
|
||||
@@ -370,16 +338,14 @@ static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distan
|
||||
}
|
||||
|
||||
/* make the back plane */
|
||||
VectorSubtract( vec3_origin, dp->planes[ 0 ], dp->planes[ 1 ] );
|
||||
VectorMA( dv[ 0 ]->xyz, distance, projection, xyz );
|
||||
dp->planes[ 1 ][ 3 ] = DotProduct( xyz, dp->planes[ 1 ] );
|
||||
dp->planes[ 1 ].normal() = -dp->planes[ 0 ].normal();
|
||||
dp->planes[ 1 ].dist() = vector3_dot( dv[ 0 ]->xyz + projection.normal() * distance, dp->planes[ 1 ].normal() );
|
||||
|
||||
/* make the side planes */
|
||||
for ( i = 0; i < numVerts; i++ )
|
||||
{
|
||||
j = ( i + 1 ) % numVerts;
|
||||
VectorMA( dv[ i ]->xyz, distance, projection, xyz );
|
||||
if ( !PlaneFromPoints( dp->planes[ i + 2 ], dv[ j ]->xyz, dv[ i ]->xyz, xyz ) ) {
|
||||
if ( !PlaneFromPoints( dp->planes[ i + 2 ], dv[ j ]->xyz, dv[ i ]->xyz, dv[ i ]->xyz + projection.normal() * distance ) ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -401,8 +367,7 @@ static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distan
|
||||
void ProcessDecals( void ){
|
||||
int j, x, y, pw[ 5 ], r, iterations;
|
||||
float distance;
|
||||
vec4_t projection, plane;
|
||||
vec3_t origin, target, delta;
|
||||
Plane3f projection, plane;
|
||||
entity_t *e2;
|
||||
parseMesh_t *p;
|
||||
mesh_t *mesh, *subdivided;
|
||||
@@ -439,20 +404,18 @@ void ProcessDecals( void ){
|
||||
for ( p = e.patches; p != NULL; p = e.patches )
|
||||
{
|
||||
/* setup projector */
|
||||
if ( VectorCompare( e.origin, vec3_origin ) ) {
|
||||
VectorAdd( p->eMins, p->eMaxs, origin );
|
||||
VectorScale( origin, 0.5f, origin );
|
||||
Vector3 origin;
|
||||
if ( VectorCompare( e.origin, g_vector3_identity ) ) {
|
||||
origin = p->eMinmax.origin();
|
||||
}
|
||||
else{
|
||||
VectorCopy( e.origin, origin );
|
||||
origin = e.origin;
|
||||
}
|
||||
|
||||
VectorCopy( e2->origin, target );
|
||||
VectorSubtract( target, origin, delta );
|
||||
|
||||
/* setup projection plane */
|
||||
distance = VectorNormalize( delta, projection );
|
||||
projection[ 3 ] = DotProduct( origin, projection );
|
||||
projection.normal() = e2->origin - origin;
|
||||
distance = VectorNormalize( projection.normal() );
|
||||
projection.dist() = vector3_dot( origin, projection.normal() );
|
||||
|
||||
/* create projectors */
|
||||
if ( distance > 0.125f ) {
|
||||
@@ -467,7 +430,7 @@ void ProcessDecals( void ){
|
||||
|
||||
/* offset by projector origin */
|
||||
for ( j = 0; j < ( mesh->width * mesh->height ); j++ )
|
||||
VectorAdd( mesh->verts[ j ].xyz, e.origin, mesh->verts[ j ].xyz );
|
||||
mesh->verts[ j ].xyz += e.origin;
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( y = 0; y < ( mesh->height - 1 ); y++ )
|
||||
@@ -491,9 +454,8 @@ void ProcessDecals( void ){
|
||||
dv[ 3 ] = &mesh->verts[ pw[ r + 3 ] ];
|
||||
|
||||
/* planar? (nuking this optimization as it doesn't work on non-rectangular quads) */
|
||||
plane[ 0 ] = 0.0f; /* stupid msvc */
|
||||
if ( 0 && PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) &&
|
||||
fabs( DotProduct( dv[ 1 ]->xyz, plane ) - plane[ 3 ] ) <= PLANAR_EPSILON ) {
|
||||
fabs( plane3_distance_to_point( plane, dv[ 1 ]->xyz ) ) <= PLANAR_EPSILON ) {
|
||||
/* make a quad projector */
|
||||
MakeDecalProjector( p->shaderInfo, projection, distance, 4, dv );
|
||||
}
|
||||
@@ -542,7 +504,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
winding_t *front, *back;
|
||||
mapDrawSurface_t *ds2;
|
||||
bspDrawVert_t *dv;
|
||||
vec4_t plane;
|
||||
Plane3f plane;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
@@ -553,7 +515,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
|
||||
/* offset by entity origin */
|
||||
for ( i = 0; i < w->numpoints; i++ )
|
||||
VectorAdd( w->p[ i ], entityOrigin, w->p[ i ] );
|
||||
w->p[ i ] += entityOrigin;
|
||||
|
||||
/* make a plane from the winding */
|
||||
if ( !PlaneFromPoints( plane, w->p[ 0 ], w->p[ 1 ], w->p[ 2 ] ) ) {
|
||||
@@ -562,8 +524,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
}
|
||||
|
||||
/* backface check */
|
||||
d = DotProduct( dp->planes[ 0 ], plane );
|
||||
if ( d < -0.0001f ) {
|
||||
if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) {
|
||||
FreeWinding( w );
|
||||
return;
|
||||
}
|
||||
@@ -572,7 +533,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
for ( i = 0; i < dp->numPlanes; i++ )
|
||||
{
|
||||
/* chop winding by the plane */
|
||||
ClipWindingEpsilonStrict( w, dp->planes[ i ], dp->planes[ i ][ 3 ], 0.0625f, &front, &back ); /* strict, if identical plane we don't want to keep it */
|
||||
ClipWindingEpsilonStrict( w, dp->planes[ i ], 0.0625f, &front, &back ); /* strict, if identical plane we don't want to keep it */
|
||||
FreeWinding( w );
|
||||
|
||||
/* lose the front fragment */
|
||||
@@ -618,8 +579,8 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
dv = &ds2->verts[ i ];
|
||||
|
||||
/* set alpha */
|
||||
d = DotProduct( w->p[ i ], dp->planes[ 0 ] ) - dp->planes[ 0 ][ 3 ];
|
||||
d2 = DotProduct( w->p[ i ], dp->planes[ 1 ] ) - dp->planes[ 1 ][ 3 ];
|
||||
d = plane3_distance_to_point( dp->planes[ 0 ], w->p[ i ] );
|
||||
d2 = plane3_distance_to_point( dp->planes[ 1 ], w->p[ i ] );
|
||||
alpha = 255.0f * d2 / ( d + d2 );
|
||||
if ( alpha > 255 ) {
|
||||
alpha = 255;
|
||||
@@ -629,18 +590,15 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
}
|
||||
|
||||
/* set misc */
|
||||
VectorSubtract( w->p[ i ], entityOrigin, dv->xyz );
|
||||
VectorCopy( plane, dv->normal );
|
||||
dv->st[ 0 ] = DotProduct( dv->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ];
|
||||
dv->st[ 1 ] = DotProduct( dv->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ];
|
||||
dv->xyz = w->p[ i ] - entityOrigin;
|
||||
dv->normal = plane.normal();
|
||||
dv->st[ 0 ] = vector3_dot( dv->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
dv->st[ 1 ] = vector3_dot( dv->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
|
||||
/* set color */
|
||||
for ( j = 0; j < MAX_LIGHTMAPS; j++ )
|
||||
{
|
||||
dv->color[ j ][ 0 ] = 255;
|
||||
dv->color[ j ][ 1 ] = 255;
|
||||
dv->color[ j ][ 2 ] = 255;
|
||||
dv->color[ j ][ 3 ] = alpha;
|
||||
dv->color[ j ] = { 255, 255, 255, alpha };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -653,11 +611,6 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
||||
*/
|
||||
|
||||
static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
vec4_t plane;
|
||||
float d;
|
||||
winding_t *w;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( ds->sideRef == NULL || ds->sideRef->side == NULL ) {
|
||||
return;
|
||||
@@ -665,16 +618,15 @@ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
|
||||
/* backface check */
|
||||
if ( ds->planar ) {
|
||||
VectorCopy( mapplanes[ ds->planeNum ].normal, plane );
|
||||
plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin );
|
||||
d = DotProduct( dp->planes[ 0 ], plane );
|
||||
if ( d < -0.0001f ) {
|
||||
Plane3f plane = mapplanes[ ds->planeNum ].plane;
|
||||
plane.dist() += vector3_dot( plane.normal(), entityOrigin );
|
||||
if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate decal */
|
||||
w = WindingFromDrawSurf( ds );
|
||||
winding_t *w = WindingFromDrawSurf( ds );
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
}
|
||||
|
||||
@@ -687,18 +639,15 @@ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
|
||||
static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
int x, y, pw[ 5 ], r, iterations;
|
||||
vec4_t plane;
|
||||
float d;
|
||||
mesh_t src, *mesh, *subdivided;
|
||||
winding_t *w;
|
||||
|
||||
|
||||
/* backface check */
|
||||
if ( ds->planar ) {
|
||||
VectorCopy( mapplanes[ ds->planeNum ].normal, plane );
|
||||
plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin );
|
||||
d = DotProduct( dp->planes[ 0 ], plane );
|
||||
if ( d < -0.0001f ) {
|
||||
Plane3f plane = mapplanes[ ds->planeNum ].plane;
|
||||
plane.dist() += vector3_dot( plane.normal(), entityOrigin );
|
||||
if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -733,17 +682,17 @@ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
/* generate decal for first triangle */
|
||||
w = AllocWinding( 3 );
|
||||
w->numpoints = 3;
|
||||
VectorCopy( mesh->verts[ pw[ r + 0 ] ].xyz, w->p[ 0 ] );
|
||||
VectorCopy( mesh->verts[ pw[ r + 1 ] ].xyz, w->p[ 1 ] );
|
||||
VectorCopy( mesh->verts[ pw[ r + 2 ] ].xyz, w->p[ 2 ] );
|
||||
w->p[ 0 ] = mesh->verts[ pw[ r + 0 ] ].xyz;
|
||||
w->p[ 1 ] = mesh->verts[ pw[ r + 1 ] ].xyz;
|
||||
w->p[ 2 ] = mesh->verts[ pw[ r + 2 ] ].xyz;
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
|
||||
/* generate decal for second triangle */
|
||||
w = AllocWinding( 3 );
|
||||
w->numpoints = 3;
|
||||
VectorCopy( mesh->verts[ pw[ r + 0 ] ].xyz, w->p[ 0 ] );
|
||||
VectorCopy( mesh->verts[ pw[ r + 2 ] ].xyz, w->p[ 1 ] );
|
||||
VectorCopy( mesh->verts[ pw[ r + 3 ] ].xyz, w->p[ 2 ] );
|
||||
w->p[ 0 ] = mesh->verts[ pw[ r + 0 ] ].xyz;
|
||||
w->p[ 1 ] = mesh->verts[ pw[ r + 2 ] ].xyz;
|
||||
w->p[ 2 ] = mesh->verts[ pw[ r + 3 ] ].xyz;
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
}
|
||||
}
|
||||
@@ -760,12 +709,7 @@ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
*/
|
||||
|
||||
static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
int i;
|
||||
vec4_t plane;
|
||||
float d;
|
||||
winding_t *w;
|
||||
|
||||
|
||||
|
||||
/* triangle surfaces without shaders don't get marks by default */
|
||||
if ( ds->type == ESurfaceType::Triangles && ds->shaderInfo->shaderText == NULL ) {
|
||||
return;
|
||||
@@ -773,23 +717,22 @@ static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *d
|
||||
|
||||
/* backface check */
|
||||
if ( ds->planar ) {
|
||||
VectorCopy( mapplanes[ ds->planeNum ].normal, plane );
|
||||
plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin );
|
||||
d = DotProduct( dp->planes[ 0 ], plane );
|
||||
if ( d < -0.0001f ) {
|
||||
Plane3f plane = mapplanes[ ds->planeNum ].plane;
|
||||
plane.dist() += vector3_dot( plane.normal(), entityOrigin );
|
||||
if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* iterate through triangles */
|
||||
for ( i = 0; i < ds->numIndexes; i += 3 )
|
||||
for ( int i = 0; i < ds->numIndexes; i += 3 )
|
||||
{
|
||||
/* generate decal */
|
||||
w = AllocWinding( 3 );
|
||||
winding_t *w = AllocWinding( 3 );
|
||||
w->numpoints = 3;
|
||||
VectorCopy( ds->verts[ ds->indexes[ i ] ].xyz, w->p[ 0 ] );
|
||||
VectorCopy( ds->verts[ ds->indexes[ i + 1 ] ].xyz, w->p[ 1 ] );
|
||||
VectorCopy( ds->verts[ ds->indexes[ i + 2 ] ].xyz, w->p[ 2 ] );
|
||||
w->p[ 0 ] = ds->verts[ ds->indexes[ i ] ].xyz;
|
||||
w->p[ 1 ] = ds->verts[ ds->indexes[ i + 1 ] ].xyz;
|
||||
w->p[ 2 ] = ds->verts[ ds->indexes[ i + 2 ] ].xyz;
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
}
|
||||
}
|
||||
@@ -805,17 +748,14 @@ void MakeEntityDecals( entity_t *e ){
|
||||
int i, j, k, f, fOld, start;
|
||||
decalProjector_t dp;
|
||||
mapDrawSurface_t *ds;
|
||||
vec3_t identityAxis[ 3 ] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
|
||||
Vector3 identityAxis[ 3 ] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
|
||||
|
||||
|
||||
/* note it */
|
||||
Sys_FPrintf( SYS_VRB, "--- MakeEntityDecals ---\n" );
|
||||
|
||||
/* set entity origin */
|
||||
VectorCopy( e->origin, entityOrigin );
|
||||
|
||||
/* transform projector instead of geometry */
|
||||
VectorClear( entityOrigin );
|
||||
entityOrigin.set( 0 );
|
||||
|
||||
/* init pacifier */
|
||||
fOld = -1;
|
||||
@@ -850,8 +790,8 @@ void MakeEntityDecals( entity_t *e ){
|
||||
|
||||
/* bounds check */
|
||||
for ( k = 0; k < 3; k++ )
|
||||
if ( ds->mins[ k ] >= ( dp.center[ k ] + dp.radius ) ||
|
||||
ds->maxs[ k ] <= ( dp.center[ k ] - dp.radius ) ) {
|
||||
if ( ds->minmax.mins[ k ] >= ( dp.center[ k ] + dp.radius ) ||
|
||||
ds->minmax.maxs[ k ] <= ( dp.center[ k ] - dp.radius ) ) {
|
||||
break;
|
||||
}
|
||||
if ( k < 3 ) {
|
||||
|
||||
@@ -71,11 +71,8 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
|
||||
face_t *check;
|
||||
face_t *bestSplit;
|
||||
int splits, facing, front, back;
|
||||
int side;
|
||||
plane_t *plane;
|
||||
int value, bestValue;
|
||||
int i;
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
int planenum;
|
||||
float sizeBias;
|
||||
@@ -96,11 +93,9 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
|
||||
if ( blockSize[ i ] <= 0 ) {
|
||||
continue;
|
||||
}
|
||||
dist = blockSize[ i ] * ( floor( node->mins[ i ] / blockSize[ i ] ) + 1 );
|
||||
if ( node->maxs[ i ] > dist ) {
|
||||
VectorClear( normal );
|
||||
normal[ i ] = 1;
|
||||
planenum = FindFloatPlane( normal, dist, 0, NULL );
|
||||
dist = blockSize[ i ] * ( floor( node->minmax.mins[ i ] / blockSize[ i ] ) + 1 );
|
||||
if ( node->minmax.maxs[ i ] > dist ) {
|
||||
planenum = FindFloatPlane( g_vector3_axes[i], dist, 0, NULL );
|
||||
*splitPlaneNum = planenum;
|
||||
return;
|
||||
}
|
||||
@@ -120,7 +115,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
|
||||
//if ( split->checked )
|
||||
// continue;
|
||||
|
||||
plane = &mapplanes[ split->planenum ];
|
||||
const plane_t& plane = mapplanes[ split->planenum ];
|
||||
splits = 0;
|
||||
facing = 0;
|
||||
front = 0;
|
||||
@@ -131,14 +126,14 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
|
||||
//check->checked = true; // won't need to test this plane again
|
||||
continue;
|
||||
}
|
||||
side = WindingOnPlaneSide( check->w, plane->normal, plane->dist );
|
||||
if ( side == SIDE_CROSS ) {
|
||||
const EPlaneSide side = WindingOnPlaneSide( check->w, plane.plane );
|
||||
if ( side == eSideCross ) {
|
||||
splits++;
|
||||
}
|
||||
else if ( side == SIDE_FRONT ) {
|
||||
else if ( side == eSideFront ) {
|
||||
front++;
|
||||
}
|
||||
else if ( side == SIDE_BACK ) {
|
||||
else if ( side == eSideBack ) {
|
||||
back++;
|
||||
}
|
||||
}
|
||||
@@ -151,7 +146,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
|
||||
|
||||
//Base score = 20000 perfectly balanced
|
||||
value = 20000 - ( abs( front - back ) );
|
||||
value -= plane->counter; // If we've already used this plane sometime in the past try not to use it again
|
||||
value -= plane.counter; // If we've already used this plane sometime in the past try not to use it again
|
||||
value -= facing ; // if we're going to have alot of other surfs use this plane, we want to get it in quickly.
|
||||
value -= splits * 5; //more splits = bad
|
||||
value += sizeBias * 10; //We want a huge score bias based on plane size
|
||||
@@ -159,7 +154,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
|
||||
else
|
||||
{
|
||||
value = 5 * facing - 5 * splits; // - abs(front-back);
|
||||
if ( plane->type < 3 ) {
|
||||
if ( plane.type < ePlaneNonAxial ) {
|
||||
value += 5; // axial is better
|
||||
}
|
||||
}
|
||||
@@ -231,8 +226,6 @@ int CountFaceList( face_t *list ){
|
||||
void BuildFaceTree_r( node_t *node, face_t *list ){
|
||||
face_t *split;
|
||||
face_t *next;
|
||||
int side;
|
||||
plane_t *plane;
|
||||
face_t *newFace;
|
||||
face_t *childLists[2];
|
||||
winding_t *frontWinding, *backWinding;
|
||||
@@ -261,7 +254,7 @@ void BuildFaceTree_r( node_t *node, face_t *list ){
|
||||
node->planenum = splitPlaneNum;
|
||||
node->compileFlags = compileFlags;
|
||||
node->has_structural_children = !( compileFlags & C_DETAIL ) && !node->opaque;
|
||||
plane = &mapplanes[ splitPlaneNum ];
|
||||
const plane_t& plane = mapplanes[ splitPlaneNum ];
|
||||
childLists[0] = NULL;
|
||||
childLists[1] = NULL;
|
||||
|
||||
@@ -283,11 +276,11 @@ void BuildFaceTree_r( node_t *node, face_t *list ){
|
||||
#endif
|
||||
|
||||
/* determine which side the face falls on */
|
||||
side = WindingOnPlaneSide( split->w, plane->normal, plane->dist );
|
||||
const EPlaneSide side = WindingOnPlaneSide( split->w, plane.plane );
|
||||
|
||||
/* switch on side */
|
||||
if ( side == SIDE_CROSS ) {
|
||||
ClipWindingEpsilonStrict( split->w, plane->normal, plane->dist, CLIP_EPSILON * 2,
|
||||
if ( side == eSideCross ) {
|
||||
ClipWindingEpsilonStrict( split->w, plane.plane, CLIP_EPSILON * 2,
|
||||
&frontWinding, &backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */
|
||||
if ( frontWinding ) {
|
||||
newFace = AllocBspFace();
|
||||
@@ -309,11 +302,11 @@ void BuildFaceTree_r( node_t *node, face_t *list ){
|
||||
}
|
||||
FreeBspFace( split );
|
||||
}
|
||||
else if ( side == SIDE_FRONT ) {
|
||||
else if ( side == eSideFront ) {
|
||||
split->next = childLists[0];
|
||||
childLists[0] = split;
|
||||
}
|
||||
else if ( side == SIDE_BACK ) {
|
||||
else if ( side == eSideBack ) {
|
||||
split->next = childLists[1];
|
||||
childLists[1] = split;
|
||||
}
|
||||
@@ -324,19 +317,18 @@ void BuildFaceTree_r( node_t *node, face_t *list ){
|
||||
for ( i = 0 ; i < 2 ; i++ ) {
|
||||
node->children[i] = AllocNode();
|
||||
node->children[i]->parent = node;
|
||||
VectorCopy( node->mins, node->children[i]->mins );
|
||||
VectorCopy( node->maxs, node->children[i]->maxs );
|
||||
node->children[i]->minmax = node->minmax;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
if ( plane->normal[i] == 1 ) {
|
||||
node->children[0]->mins[i] = plane->dist;
|
||||
node->children[1]->maxs[i] = plane->dist;
|
||||
if ( plane.normal()[i] == 1 ) {
|
||||
node->children[0]->minmax.mins[i] = plane.dist();
|
||||
node->children[1]->minmax.maxs[i] = plane.dist();
|
||||
break;
|
||||
}
|
||||
if ( plane->normal[i] == -1 ) {
|
||||
node->children[0]->maxs[i] = -plane->dist;
|
||||
node->children[1]->mins[i] = -plane->dist;
|
||||
if ( plane.normal()[i] == -1 ) {
|
||||
node->children[0]->minmax.maxs[i] = -plane.dist();
|
||||
node->children[1]->minmax.mins[i] = -plane.dist();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -386,7 +378,7 @@ tree_t *FaceBSP( face_t *list ) {
|
||||
count++;
|
||||
for ( i = 0; i < face->w->numpoints; i++ )
|
||||
{
|
||||
AddPointToBounds( face->w->p[ i ], tree->mins, tree->maxs );
|
||||
tree->minmax.extend( face->w->p[ i ] );
|
||||
}
|
||||
}
|
||||
Sys_FPrintf( SYS_VRB, "%9d faces\n", count );
|
||||
@@ -397,8 +389,7 @@ tree_t *FaceBSP( face_t *list ) {
|
||||
}
|
||||
|
||||
tree->headnode = AllocNode();
|
||||
VectorCopy( tree->mins, tree->headnode->mins );
|
||||
VectorCopy( tree->maxs, tree->headnode->maxs );
|
||||
tree->headnode->minmax = tree->minmax;
|
||||
c_faceLeafs = 0;
|
||||
|
||||
BuildFaceTree_r( tree->headnode, list );
|
||||
|
||||
+31
-71
@@ -63,7 +63,7 @@ mesh_t *DrawSurfToMesh( mapDrawSurface_t *ds ){
|
||||
chops a mesh by a plane
|
||||
*/
|
||||
|
||||
void SplitMeshByPlane( mesh_t *in, vec3_t normal, float dist, mesh_t **front, mesh_t **back ){
|
||||
void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front, mesh_t **back ){
|
||||
int w, h, split;
|
||||
float d[MAX_PATCH_SIZE][MAX_PATCH_SIZE];
|
||||
bspDrawVert_t *dv, *v1, *v2;
|
||||
@@ -80,7 +80,7 @@ void SplitMeshByPlane( mesh_t *in, vec3_t normal, float dist, mesh_t **front, me
|
||||
c_on = 0;
|
||||
for ( h = 0 ; h < in->height ; h++ ) {
|
||||
for ( w = 0 ; w < in->width ; w++, dv++ ) {
|
||||
d[h][w] = DotProduct( dv->xyz, normal ) - dist;
|
||||
d[h][w] = plane3_distance_to_point( plane, dv->xyz );
|
||||
if ( d[h][w] > ON_EPSILON ) {
|
||||
c_front++;
|
||||
}
|
||||
@@ -247,7 +247,6 @@ void SplitMeshByPlane( mesh_t *in, vec3_t normal, float dist, mesh_t **front, me
|
||||
bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
int i, j;
|
||||
side_t *s;
|
||||
plane_t *plane;
|
||||
mesh_t *outside[MAX_BRUSH_SIDES];
|
||||
int numOutside;
|
||||
mesh_t *m, *front, *back;
|
||||
@@ -261,9 +260,9 @@ bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
|
||||
for ( i = 4 ; i <= 5 ; i++ ) {
|
||||
s = &b->sides[ i ];
|
||||
plane = &mapplanes[ s->planenum ];
|
||||
const plane_t& plane = mapplanes[ s->planenum ];
|
||||
|
||||
SplitMeshByPlane( m, plane->normal, plane->dist, &front, &back );
|
||||
SplitMeshByPlane( m, plane.plane, &front, &back );
|
||||
|
||||
if ( !back ) {
|
||||
// nothing actually contained inside
|
||||
@@ -340,14 +339,14 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){
|
||||
// (actually send the whole draw surface would be cool?)
|
||||
if ( ds->numVerts >= MAX_POINTS_ON_WINDING ) {
|
||||
int max = ds->numVerts;
|
||||
vec3_t p[256];
|
||||
Vector3 p[256];
|
||||
|
||||
if ( max > 256 ) {
|
||||
max = 256;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < max ; i++ ) {
|
||||
VectorCopy( ds->verts[i].xyz, p[i] );
|
||||
p[i] = ds->verts[i].xyz;
|
||||
}
|
||||
|
||||
xml_Winding( "WindingFromDrawSurf failed: MAX_POINTS_ON_WINDING exceeded", p, max, true );
|
||||
@@ -356,7 +355,7 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){
|
||||
w = AllocWinding( ds->numVerts );
|
||||
w->numpoints = ds->numVerts;
|
||||
for ( i = 0 ; i < ds->numVerts ; i++ ) {
|
||||
VectorCopy( ds->verts[i].xyz, w->p[i] );
|
||||
w->p[i] = ds->verts[i].xyz;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
@@ -371,7 +370,6 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){
|
||||
bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
int i, j;
|
||||
side_t *s;
|
||||
plane_t *plane;
|
||||
winding_t *w;
|
||||
winding_t *front, *back;
|
||||
winding_t *outside[ MAX_BRUSH_SIDES ];
|
||||
@@ -393,7 +391,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
{
|
||||
/* get brush side and plane */
|
||||
s = &b->sides[ i ];
|
||||
plane = &mapplanes[ s->planenum ];
|
||||
const plane_t& plane = mapplanes[ s->planenum ];
|
||||
|
||||
/* handle coplanar outfacing (don't fog) */
|
||||
if ( ds->sideRef->side->planenum == s->planenum ) {
|
||||
@@ -406,7 +404,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
}
|
||||
|
||||
/* general case */
|
||||
ClipWindingEpsilonStrict( w, plane->normal, plane->dist, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */
|
||||
ClipWindingEpsilonStrict( w, plane.plane, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */
|
||||
FreeWinding( w );
|
||||
|
||||
if ( back == NULL ) {
|
||||
@@ -468,10 +466,9 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
*/
|
||||
|
||||
void FogDrawSurfaces( entity_t *e ){
|
||||
int i, j, k, fogNum;
|
||||
int i, j, fogNum;
|
||||
fog_t *fog;
|
||||
mapDrawSurface_t *ds;
|
||||
vec3_t mins, maxs;
|
||||
int fogged, numFogged;
|
||||
int numBaseDrawSurfs;
|
||||
|
||||
@@ -512,24 +509,13 @@ void FogDrawSurfaces( entity_t *e ){
|
||||
else
|
||||
{
|
||||
/* find drawsurface bounds */
|
||||
ClearBounds( mins, maxs );
|
||||
MinMax minmax;
|
||||
for ( j = 0; j < ds->numVerts; j++ )
|
||||
AddPointToBounds( ds->verts[ j ].xyz, mins, maxs );
|
||||
minmax.extend( ds->verts[ j ].xyz );
|
||||
|
||||
/* check against the fog brush */
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
if ( mins[ k ] > fog->brush->maxs[ k ] ) {
|
||||
break;
|
||||
}
|
||||
if ( maxs[ k ] < fog->brush->mins[ k ] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* no intersection? */
|
||||
if ( k < 3 ) {
|
||||
continue;
|
||||
if( !minmax.test( fog->brush->minmax ) ){
|
||||
continue; /* no intersection */
|
||||
}
|
||||
|
||||
/* ydnar: gs mods: handle the various types of surfaces */
|
||||
@@ -580,12 +566,10 @@ void FogDrawSurfaces( entity_t *e ){
|
||||
gets the fog number for a point in space
|
||||
*/
|
||||
|
||||
int FogForPoint( vec3_t point, float epsilon ){
|
||||
int FogForPoint( const Vector3& point, float epsilon ){
|
||||
int fogNum, i, j;
|
||||
float dot;
|
||||
bool inside;
|
||||
brush_t *brush;
|
||||
plane_t *plane;
|
||||
|
||||
|
||||
/* start with bogus fog num */
|
||||
@@ -607,10 +591,7 @@ int FogForPoint( vec3_t point, float epsilon ){
|
||||
inside = true;
|
||||
for ( j = 0; j < brush->numsides && inside; j++ )
|
||||
{
|
||||
plane = &mapplanes[ brush->sides[ j ].planenum ]; /* note usage of map planes here */
|
||||
dot = DotProduct( point, plane->normal );
|
||||
dot -= plane->dist;
|
||||
if ( dot > epsilon ) {
|
||||
if ( plane3_distance_to_point( mapplanes[ brush->sides[ j ].planenum ].plane, point ) > epsilon ) {
|
||||
inside = false;
|
||||
}
|
||||
}
|
||||
@@ -633,18 +614,14 @@ int FogForPoint( vec3_t point, float epsilon ){
|
||||
gets the fog number for a bounding box
|
||||
*/
|
||||
|
||||
int FogForBounds( vec3_t mins, vec3_t maxs, float epsilon ){
|
||||
int fogNum, i, j;
|
||||
float highMin, lowMax, volume, bestVolume;
|
||||
vec3_t fogMins, fogMaxs, overlap;
|
||||
brush_t *brush;
|
||||
|
||||
int FogForBounds( const MinMax& minmax, float epsilon ){
|
||||
int fogNum, i;
|
||||
|
||||
/* start with bogus fog num */
|
||||
fogNum = defaultFogNum;
|
||||
|
||||
/* init */
|
||||
bestVolume = 0.0f;
|
||||
float bestVolume = 0.0f;
|
||||
|
||||
/* walk the list of fog volumes */
|
||||
for ( i = 0; i < numMapFogs; i++ )
|
||||
@@ -656,37 +633,21 @@ int FogForBounds( vec3_t mins, vec3_t maxs, float epsilon ){
|
||||
}
|
||||
|
||||
/* get fog brush */
|
||||
brush = mapFogs[ i ].brush;
|
||||
brush_t *brush = mapFogs[ i ].brush;
|
||||
|
||||
/* get bounds */
|
||||
fogMins[ 0 ] = brush->mins[ 0 ] - epsilon;
|
||||
fogMins[ 1 ] = brush->mins[ 1 ] - epsilon;
|
||||
fogMins[ 2 ] = brush->mins[ 2 ] - epsilon;
|
||||
fogMaxs[ 0 ] = brush->maxs[ 0 ] + epsilon;
|
||||
fogMaxs[ 1 ] = brush->maxs[ 1 ] + epsilon;
|
||||
fogMaxs[ 2 ] = brush->maxs[ 2 ] + epsilon;
|
||||
|
||||
const MinMax fogMinmax( brush->minmax.mins - Vector3( epsilon, epsilon, epsilon ),
|
||||
brush->minmax.maxs + Vector3( epsilon, epsilon, epsilon ) );
|
||||
/* check against bounds */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
if ( mins[ j ] > fogMaxs[ j ] || maxs[ j ] < fogMins[ j ] ) {
|
||||
break;
|
||||
}
|
||||
highMin = mins[ j ] > fogMins[ j ] ? mins[ j ] : fogMins[ j ];
|
||||
lowMax = maxs[ j ] < fogMaxs[ j ] ? maxs[ j ] : fogMaxs[ j ];
|
||||
overlap[ j ] = lowMax - highMin;
|
||||
if ( overlap[ j ] < 1.0f ) {
|
||||
overlap[ j ] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* no overlap */
|
||||
if ( j < 3 ) {
|
||||
continue;
|
||||
if( !minmax.test( fogMinmax ) ){
|
||||
continue; /* no overlap */
|
||||
}
|
||||
const Vector3 overlap( std::max( 1.f, std::min( minmax.maxs[0], fogMinmax.maxs[0] ) - std::max( minmax.mins[0], fogMinmax.mins[0] ) ),
|
||||
std::max( 1.f, std::min( minmax.maxs[1], fogMinmax.maxs[1] ) - std::max( minmax.mins[1], fogMinmax.mins[1] ) ),
|
||||
std::max( 1.f, std::min( minmax.maxs[2], fogMinmax.maxs[2] ) - std::max( minmax.mins[2], fogMinmax.mins[2] ) ) );
|
||||
|
||||
/* get volume */
|
||||
volume = overlap[ 0 ] * overlap[ 1 ] * overlap[ 2 ];
|
||||
const float volume = overlap[0] * overlap[1] * overlap[2];
|
||||
|
||||
/* test against best volume */
|
||||
if ( volume > bestVolume ) {
|
||||
@@ -710,7 +671,6 @@ void CreateMapFogs( void ){
|
||||
int j;
|
||||
brush_t *brush;
|
||||
fog_t *fog;
|
||||
vec3_t invFogDir;
|
||||
|
||||
|
||||
/* skip? */
|
||||
@@ -744,14 +704,14 @@ void CreateMapFogs( void ){
|
||||
fog->visibleSide = -1;
|
||||
|
||||
/* if shader specifies an explicit direction, then find a matching brush side with an opposed normal */
|
||||
if ( VectorLength( fog->si->fogDir ) ) {
|
||||
if ( vector3_length( fog->si->fogDir ) ) {
|
||||
/* flip it */
|
||||
VectorScale( fog->si->fogDir, -1.0f, invFogDir );
|
||||
const Vector3 invFogDir = -fog->si->fogDir;
|
||||
|
||||
/* find the brush side */
|
||||
for ( j = 0; j < brush->numsides; j++ )
|
||||
{
|
||||
if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ j ].planenum ].normal ) ) {
|
||||
if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ j ].planenum ].normal() ) ) {
|
||||
fog->visibleSide = j;
|
||||
//% Sys_Printf( "Brush num: %d Side num: %d\n", fog->brushNum, fog->visibleSide );
|
||||
break;
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
=============
|
||||
*/
|
||||
xmlNodePtr LeakFile( tree_t *tree ){
|
||||
vec3_t mid;
|
||||
Vector3 mid;
|
||||
FILE *linefile;
|
||||
node_t *node;
|
||||
int count;
|
||||
@@ -97,7 +97,7 @@ xmlNodePtr LeakFile( tree_t *tree ){
|
||||
}
|
||||
}
|
||||
node = nextnode;
|
||||
WindingCenter( nextportal->winding, mid );
|
||||
mid = WindingCenter( nextportal->winding );
|
||||
fprintf( linefile, "%f %f %f\n", mid[0], mid[1], mid[2] );
|
||||
point = xml_NodeForVec( mid );
|
||||
xmlAddChild( xml_node, point );
|
||||
|
||||
+132
-158
@@ -41,7 +41,7 @@
|
||||
static void CreateSunLight( sun_t *sun ){
|
||||
int i;
|
||||
float photons, d, angle, elevation, da, de;
|
||||
vec3_t direction;
|
||||
Vector3 direction;
|
||||
light_t *light;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ static void CreateSunLight( sun_t *sun ){
|
||||
{
|
||||
/* calculate sun direction */
|
||||
if ( i == 0 ) {
|
||||
VectorCopy( sun->direction, direction );
|
||||
direction = sun->direction;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -92,7 +92,7 @@ static void CreateSunLight( sun_t *sun ){
|
||||
elevation += de;
|
||||
|
||||
/* debug code */
|
||||
//% Sys_Printf( "%d: Angle: %3.4f Elevation: %3.3f\n", sun->numSamples, (angle / Q_PI * 180.0f), (elevation / Q_PI * 180.0f) );
|
||||
//% Sys_Printf( "%d: Angle: %3.4lf Elevation: %3.3lf\n", sun->numSamples, radians_to_degrees( angle ), radians_to_degrees( elevation ) );
|
||||
|
||||
/* create new vector */
|
||||
direction[ 0 ] = cos( angle ) * cos( elevation );
|
||||
@@ -115,14 +115,14 @@ static void CreateSunLight( sun_t *sun ){
|
||||
light->style = noStyles ? LS_NORMAL : sun->style;
|
||||
|
||||
/* set the light's position out to infinity */
|
||||
VectorMA( vec3_origin, ( MAX_WORLD_COORD * 8.0f ), direction, light->origin ); /* MAX_WORLD_COORD * 2.0f */
|
||||
light->origin = -direction * ( MAX_WORLD_COORD * 8.0f ); /* MAX_WORLD_COORD * 2.0f */
|
||||
|
||||
/* set the facing to be the inverse of the sun direction */
|
||||
VectorScale( direction, -1.0, light->normal );
|
||||
light->dist = DotProduct( light->origin, light->normal );
|
||||
light->normal = -direction;
|
||||
light->dist = vector3_dot( light->origin, light->normal );
|
||||
|
||||
/* set color and photons */
|
||||
VectorCopy( sun->color, light->color );
|
||||
light->color = sun->color;
|
||||
light->photons = photons * skyScale;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ static void CreateSunLight( sun_t *sun ){
|
||||
simulates sky light with multiple suns
|
||||
*/
|
||||
|
||||
static void CreateSkyLights( vec3_t color, float value, int iterations, float filterRadius, int style ){
|
||||
static void CreateSkyLights( const Vector3& color, float value, int iterations, float filterRadius, int style ){
|
||||
int i, j, numSuns;
|
||||
int angleSteps, elevationSteps;
|
||||
float angle, elevation;
|
||||
@@ -153,7 +153,7 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi
|
||||
}
|
||||
|
||||
/* basic sun setup */
|
||||
VectorCopy( color, sun.color );
|
||||
sun.color = color;
|
||||
sun.deviance = 0.0f;
|
||||
sun.filterRadius = filterRadius;
|
||||
sun.numSamples = 1;
|
||||
@@ -164,8 +164,8 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi
|
||||
elevationSteps = iterations - 1;
|
||||
angleSteps = elevationSteps * 4;
|
||||
angle = 0.0f;
|
||||
elevationStep = DEG2RAD( 90.0f / iterations ); /* skip elevation 0 */
|
||||
angleStep = DEG2RAD( 360.0f / angleSteps );
|
||||
elevationStep = degrees_to_radians( 90.0f / iterations ); /* skip elevation 0 */
|
||||
angleStep = degrees_to_radians( 360.0f / angleSteps );
|
||||
|
||||
/* calc individual sun brightness */
|
||||
numSuns = angleSteps * elevationSteps + 1;
|
||||
@@ -195,7 +195,7 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi
|
||||
}
|
||||
|
||||
/* create vertical sun */
|
||||
VectorSet( sun.direction, 0.0f, 0.0f, 1.0f );
|
||||
sun.direction = g_vector3_axis_z;
|
||||
CreateSunLight( &sun );
|
||||
|
||||
/* short circuit */
|
||||
@@ -371,11 +371,11 @@ void CreateEntityLights( void ){
|
||||
light->color[2] = Image_LinearFloatFromsRGBFloat( light->color[2] );
|
||||
}
|
||||
if ( !( light->flags & LightFlags::Unnormalized ) ) {
|
||||
ColorNormalize( light->color, light->color );
|
||||
ColorNormalize( light->color );
|
||||
}
|
||||
}
|
||||
else{
|
||||
VectorSet( light->color, 1.f, 1.f, 1.f );
|
||||
light->color.set( 1 );
|
||||
}
|
||||
|
||||
|
||||
@@ -406,10 +406,10 @@ void CreateEntityLights( void ){
|
||||
numSpotLights++;
|
||||
|
||||
/* make a spotlight */
|
||||
vec3_t dest;
|
||||
Vector3 dest;
|
||||
e2->vectorForKey( "origin", dest );
|
||||
VectorSubtract( dest, light->origin, light->normal );
|
||||
float dist = VectorNormalize( light->normal, light->normal );
|
||||
light->normal = dest - light->origin;
|
||||
float dist = VectorNormalize( light->normal );
|
||||
float radius = e->floatForKey( "radius" );
|
||||
if ( !radius ) {
|
||||
radius = 64;
|
||||
@@ -435,10 +435,10 @@ void CreateEntityLights( void ){
|
||||
|
||||
/* make a sun */
|
||||
sun_t sun;
|
||||
VectorScale( light->normal, -1.0f, sun.direction );
|
||||
VectorCopy( light->color, sun.color );
|
||||
sun.direction = -light->normal;
|
||||
sun.color = light->color;
|
||||
sun.photons = intensity;
|
||||
sun.deviance = deviance / 180.0f * Q_PI;
|
||||
sun.deviance = degrees_to_radians( deviance );
|
||||
sun.numSamples = numSamples;
|
||||
sun.style = noStyles ? LS_NORMAL : light->style;
|
||||
sun.next = NULL;
|
||||
@@ -504,7 +504,6 @@ void CreateSurfaceLights( void ){
|
||||
shaderInfo_t *si;
|
||||
light_t *light;
|
||||
float subdivide;
|
||||
vec3_t origin;
|
||||
clipWork_t cw;
|
||||
|
||||
|
||||
@@ -540,10 +539,6 @@ void CreateSurfaceLights( void ){
|
||||
|
||||
/* autosprite shaders become point lights */
|
||||
if ( si->autosprite ) {
|
||||
/* create an average xyz */
|
||||
VectorAdd( info->mins, info->maxs, origin );
|
||||
VectorScale( origin, 0.5f, origin );
|
||||
|
||||
/* create a light */
|
||||
light = safe_calloc( sizeof( *light ) );
|
||||
light->next = lights;
|
||||
@@ -555,8 +550,8 @@ void CreateSurfaceLights( void ){
|
||||
light->photons = si->value * pointScale;
|
||||
light->fade = 1.0f;
|
||||
light->si = si;
|
||||
VectorCopy( origin, light->origin );
|
||||
VectorCopy( si->color, light->color );
|
||||
light->origin = info->minmax.origin();
|
||||
light->color = si->color;
|
||||
light->falloffTolerance = falloffTolerance;
|
||||
light->style = si->lightStyle;
|
||||
|
||||
@@ -622,7 +617,7 @@ void SetEntityOrigins( void ){
|
||||
dm = &bspModels[ modelnum ];
|
||||
|
||||
/* get entity origin */
|
||||
vec3_t origin = { 0.f, 0.f, 0.f };
|
||||
Vector3 origin( 0, 0, 0 );
|
||||
if ( !e.read_keyvalue( origin, "origin" ) ) {
|
||||
continue;
|
||||
}
|
||||
@@ -637,7 +632,7 @@ void SetEntityOrigins( void ){
|
||||
for ( k = 0; k < ds->numVerts; k++ )
|
||||
{
|
||||
f = ds->firstVert + k;
|
||||
VectorAdd( origin, bspDrawVerts[ f ].xyz, yDrawVerts[ f ].xyz );
|
||||
yDrawVerts[ f ].xyz = origin + bspDrawVerts[ f ].xyz;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -656,10 +651,9 @@ void SetEntityOrigins( void ){
|
||||
|
||||
#define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f))
|
||||
|
||||
float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ){
|
||||
vec3_t triVector, triNormal;
|
||||
float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t *w ){
|
||||
int i, j;
|
||||
vec3_t dirs[ MAX_POINTS_ON_WINDING ];
|
||||
Vector3 dirs[ MAX_POINTS_ON_WINDING ];
|
||||
float total;
|
||||
float dot, angle, facing;
|
||||
|
||||
@@ -667,12 +661,12 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w
|
||||
/* this is expensive */
|
||||
for ( i = 0; i < w->numpoints; i++ )
|
||||
{
|
||||
VectorSubtract( w->p[ i ], point, dirs[ i ] );
|
||||
VectorFastNormalize( dirs[ i ], dirs[ i ] );
|
||||
dirs[ i ] = w->p[ i ] - point;
|
||||
VectorFastNormalize( dirs[ i ] );
|
||||
}
|
||||
|
||||
/* duplicate first vertex to avoid mod operation */
|
||||
VectorCopy( dirs[ 0 ], dirs[ i ] );
|
||||
dirs[ i ] = dirs[ 0 ];
|
||||
|
||||
/* calculcate relative area */
|
||||
total = 0.0f;
|
||||
@@ -680,7 +674,7 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w
|
||||
{
|
||||
/* get a triangle */
|
||||
j = i + 1;
|
||||
dot = DotProduct( dirs[ i ], dirs[ j ] );
|
||||
dot = vector3_dot( dirs[ i ], dirs[ j ] );
|
||||
|
||||
/* roundoff can cause slight creep, which gives an IND from acos */
|
||||
if ( dot > 1.0f ) {
|
||||
@@ -693,12 +687,12 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w
|
||||
/* get the angle */
|
||||
angle = acos( dot );
|
||||
|
||||
CrossProduct( dirs[ i ], dirs[ j ], triVector );
|
||||
if ( VectorFastNormalize( triVector, triNormal ) < 0.0001f ) {
|
||||
Vector3 triNormal = vector3_cross( dirs[ i ], dirs[ j ] );
|
||||
if ( VectorFastNormalize( triNormal ) < 0.0001f ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
facing = DotProduct( normal, triNormal );
|
||||
facing = vector3_dot( normal, triNormal );
|
||||
total += facing * angle;
|
||||
|
||||
/* ydnar: this was throwing too many errors with radiosity + crappy maps. ignoring it. */
|
||||
@@ -735,9 +729,9 @@ int LightContributionToSample( trace_t *trace ){
|
||||
|
||||
/* clear color */
|
||||
trace->forceSubsampling = 0.0f; /* to make sure */
|
||||
VectorClear( trace->color );
|
||||
VectorClear( trace->colorNoShadow );
|
||||
VectorClear( trace->directionContribution );
|
||||
trace->color.set( 0 );
|
||||
trace->colorNoShadow.set( 0 );
|
||||
trace->directionContribution.set( 0 );
|
||||
|
||||
colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f / 255.0f );
|
||||
|
||||
@@ -750,7 +744,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
if ( light->type != ELightType::Sun ) {
|
||||
/* MrE: if the light is behind the surface */
|
||||
if ( !trace->twoSided ) {
|
||||
if ( DotProduct( light->origin, trace->normal ) - DotProduct( trace->origin, trace->normal ) < 0.0f ) {
|
||||
if ( vector3_dot( light->origin, trace->normal ) - vector3_dot( trace->origin, trace->normal ) < 0.0f ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -765,10 +759,10 @@ int LightContributionToSample( trace_t *trace ){
|
||||
if ( light->type == ELightType::Area ) {
|
||||
float factor;
|
||||
float d;
|
||||
vec3_t pushedOrigin;
|
||||
Vector3 pushedOrigin;
|
||||
|
||||
/* project sample point into light plane */
|
||||
d = DotProduct( trace->origin, light->normal ) - light->dist;
|
||||
d = vector3_dot( trace->origin, light->normal ) - light->dist;
|
||||
if ( d < 3.0f ) {
|
||||
/* sample point behind plane? */
|
||||
if ( !( light->flags & LightFlags::Twosided ) && d < -1.0f ) {
|
||||
@@ -776,7 +770,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
|
||||
/* sample plane coincident? */
|
||||
if ( d > -3.0f && DotProduct( trace->normal, light->normal ) > 0.9f ) {
|
||||
if ( d > -3.0f && vector3_dot( trace->normal, light->normal ) > 0.9f ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -784,14 +778,14 @@ int LightContributionToSample( trace_t *trace ){
|
||||
/* nudge the point so that it is clearly forward of the light */
|
||||
/* so that surfaces meeting a light emitter don't get black edges */
|
||||
if ( d > -8.0f && d < 8.0f ) {
|
||||
VectorMA( trace->origin, ( 8.0f - d ), light->normal, pushedOrigin );
|
||||
pushedOrigin = trace->origin + light->normal * ( 8.0f - d );
|
||||
}
|
||||
else{
|
||||
VectorCopy( trace->origin, pushedOrigin );
|
||||
pushedOrigin = trace->origin;
|
||||
}
|
||||
|
||||
/* get direction and distance */
|
||||
VectorCopy( light->origin, trace->end );
|
||||
trace->end = light->origin;
|
||||
dist = SetupTrace( trace );
|
||||
if ( dist >= light->envelope ) {
|
||||
return 0;
|
||||
@@ -800,7 +794,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
/* ptpff approximation */
|
||||
if ( faster ) {
|
||||
/* angle attenuation */
|
||||
angle = DotProduct( trace->normal, trace->direction );
|
||||
angle = vector3_dot( trace->normal, trace->direction );
|
||||
|
||||
/* twosided lighting */
|
||||
if ( trace->twoSided && angle < 0 ) {
|
||||
@@ -811,7 +805,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
|
||||
/* attenuate */
|
||||
angle *= -DotProduct( light->normal, trace->direction );
|
||||
angle *= -vector3_dot( light->normal, trace->direction );
|
||||
if ( angle == 0.0f ) {
|
||||
return 0;
|
||||
}
|
||||
@@ -853,7 +847,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
factor = -factor;
|
||||
|
||||
/* push light origin to other side of the plane */
|
||||
VectorMA( light->origin, -2.0f, light->normal, trace->end );
|
||||
trace->end = light->origin - light->normal * 2.f;
|
||||
dist = SetupTrace( trace );
|
||||
if ( dist >= light->envelope ) {
|
||||
return 0;
|
||||
@@ -868,7 +862,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
|
||||
/* also don't deluxe if the direction is on the wrong side */
|
||||
if ( DotProduct( trace->normal, trace->direction ) < 0 ) {
|
||||
if ( vector3_dot( trace->normal, trace->direction ) < 0 ) {
|
||||
/* no deluxemap contribution from "other side" light */
|
||||
doAddDeluxe = false;
|
||||
}
|
||||
@@ -885,7 +879,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
/* point/spot lights */
|
||||
else if ( light->type == ELightType::Point || light->type == ELightType::Spot ) {
|
||||
/* get direction and distance */
|
||||
VectorCopy( light->origin, trace->end );
|
||||
trace->end = light->origin;
|
||||
dist = SetupTrace( trace );
|
||||
if ( dist >= light->envelope ) {
|
||||
return 0;
|
||||
@@ -900,7 +894,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
/* angle attenuation */
|
||||
if ( light->flags & LightFlags::AttenAngle ) {
|
||||
/* standard Lambert attenuation */
|
||||
float dot = DotProduct( trace->normal, trace->direction );
|
||||
float dot = vector3_dot( trace->normal, trace->direction );
|
||||
|
||||
/* twosided lighting */
|
||||
if ( trace->twoSided && dot < 0 ) {
|
||||
@@ -980,18 +974,15 @@ int LightContributionToSample( trace_t *trace ){
|
||||
|
||||
/* handle spotlights */
|
||||
if ( light->type == ELightType::Spot ) {
|
||||
float distByNormal, radiusAtDist, sampleRadius;
|
||||
vec3_t pointAtDist, distToSample;
|
||||
|
||||
/* do cone calculation */
|
||||
distByNormal = -DotProduct( trace->displacement, light->normal );
|
||||
const float distByNormal = -vector3_dot( trace->displacement, light->normal );
|
||||
if ( distByNormal < 0.0f ) {
|
||||
return 0;
|
||||
}
|
||||
VectorMA( light->origin, distByNormal, light->normal, pointAtDist );
|
||||
radiusAtDist = light->radiusByDist * distByNormal;
|
||||
VectorSubtract( trace->origin, pointAtDist, distToSample );
|
||||
sampleRadius = VectorLength( distToSample );
|
||||
const Vector3 pointAtDist = light->origin + light->normal * distByNormal;
|
||||
const float radiusAtDist = light->radiusByDist * distByNormal;
|
||||
const Vector3 distToSample = trace->origin - pointAtDist;
|
||||
const float sampleRadius = vector3_length( distToSample );
|
||||
|
||||
/* outside the cone */
|
||||
if ( sampleRadius >= radiusAtDist ) {
|
||||
@@ -1017,13 +1008,13 @@ int LightContributionToSample( trace_t *trace ){
|
||||
/* ydnar: sunlight */
|
||||
else if ( light->type == ELightType::Sun ) {
|
||||
/* get origin and direction */
|
||||
VectorAdd( trace->origin, light->origin, trace->end );
|
||||
trace->end = trace->origin + light->origin;
|
||||
dist = SetupTrace( trace );
|
||||
|
||||
/* angle attenuation */
|
||||
if ( light->flags & LightFlags::AttenAngle ) {
|
||||
/* standard Lambert attenuation */
|
||||
float dot = DotProduct( trace->normal, trace->direction );
|
||||
float dot = vector3_dot( trace->normal, trace->direction );
|
||||
|
||||
/* twosided lighting */
|
||||
if ( trace->twoSided && dot < 0 ) {
|
||||
@@ -1074,7 +1065,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
|
||||
/* VorteX: set noShadow color */
|
||||
VectorScale( light->color, add, trace->colorNoShadow );
|
||||
trace->colorNoShadow = light->color * add;
|
||||
|
||||
addDeluxe *= colorBrightness;
|
||||
|
||||
@@ -1085,11 +1076,11 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
}
|
||||
|
||||
VectorScale( trace->direction, addDeluxe, trace->directionContribution );
|
||||
trace->directionContribution = trace->direction * addDeluxe;
|
||||
|
||||
/* setup trace */
|
||||
trace->testAll = true;
|
||||
VectorScale( light->color, add, trace->color );
|
||||
trace->color = light->color * add;
|
||||
|
||||
/* trace to point */
|
||||
if ( trace->testOcclusion && !trace->forceSunlight ) {
|
||||
@@ -1097,8 +1088,8 @@ int LightContributionToSample( trace_t *trace ){
|
||||
TraceLine( trace );
|
||||
trace->forceSubsampling *= add;
|
||||
if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) {
|
||||
VectorClear( trace->color );
|
||||
VectorClear( trace->directionContribution );
|
||||
trace->color.set( 0 );
|
||||
trace->directionContribution.set( 0 );
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1112,7 +1103,7 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
|
||||
/* VorteX: set noShadow color */
|
||||
VectorScale( light->color, add, trace->colorNoShadow );
|
||||
trace->colorNoShadow = light->color * add;
|
||||
|
||||
/* ydnar: changed to a variable number */
|
||||
if ( add <= 0.0f || ( add <= light->falloffTolerance && ( light->flags & LightFlags::FastActual ) ) ) {
|
||||
@@ -1142,19 +1133,19 @@ int LightContributionToSample( trace_t *trace ){
|
||||
}
|
||||
|
||||
if ( doAddDeluxe ) {
|
||||
VectorScale( trace->direction, addDeluxe, trace->directionContribution );
|
||||
trace->directionContribution = trace->direction * addDeluxe;
|
||||
}
|
||||
|
||||
/* setup trace */
|
||||
trace->testAll = false;
|
||||
VectorScale( light->color, add, trace->color );
|
||||
trace->color = light->color * add;
|
||||
|
||||
/* raytrace */
|
||||
TraceLine( trace );
|
||||
trace->forceSubsampling *= add;
|
||||
if ( trace->passSolid || trace->opaque ) {
|
||||
VectorClear( trace->color );
|
||||
VectorClear( trace->directionContribution );
|
||||
trace->color.set( 0 );
|
||||
trace->directionContribution.set( 0 );
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1170,13 +1161,13 @@ int LightContributionToSample( trace_t *trace ){
|
||||
determines the amount of light reaching a sample (luxel or vertex)
|
||||
*/
|
||||
|
||||
void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colors[ MAX_LIGHTMAPS ] ){
|
||||
void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] ){
|
||||
int i, lightmapNum;
|
||||
|
||||
|
||||
/* clear colors */
|
||||
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
|
||||
VectorClear( colors[ lightmapNum ] );
|
||||
colors[ lightmapNum ].set( 0 );
|
||||
|
||||
/* ydnar: normalmap */
|
||||
if ( normalmap ) {
|
||||
@@ -1188,7 +1179,7 @@ void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colo
|
||||
|
||||
/* ydnar: don't bounce ambient all the time */
|
||||
if ( !bouncing ) {
|
||||
VectorCopy( ambientColor, colors[ 0 ] );
|
||||
colors[ 0 ] = ambientColor;
|
||||
}
|
||||
|
||||
/* ydnar: trace to all the list of lights pre-stored in tw */
|
||||
@@ -1219,14 +1210,14 @@ void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colo
|
||||
|
||||
/* handle negative light */
|
||||
if ( trace->light->flags & LightFlags::Negative ) {
|
||||
VectorScale( trace->color, -1.0f, trace->color );
|
||||
vector3_negate( trace->color );
|
||||
}
|
||||
|
||||
/* set style */
|
||||
styles[ lightmapNum ] = trace->light->style;
|
||||
|
||||
/* add it */
|
||||
VectorAdd( colors[ lightmapNum ], trace->color, colors[ lightmapNum ] );
|
||||
colors[ lightmapNum ] += trace->color;
|
||||
|
||||
/* cheap mode */
|
||||
if ( cheap &&
|
||||
@@ -1255,7 +1246,7 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
light = trace->light;
|
||||
|
||||
/* clear color */
|
||||
VectorClear( trace->color );
|
||||
trace->color.set( 0 );
|
||||
|
||||
/* ydnar: early out */
|
||||
if ( !( light->flags & LightFlags::Grid ) || light->envelope <= 0.0f ) {
|
||||
@@ -1276,19 +1267,17 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
}
|
||||
|
||||
/* ydnar: check origin against light's pvs envelope */
|
||||
if ( trace->origin[ 0 ] > light->maxs[ 0 ] || trace->origin[ 0 ] < light->mins[ 0 ] ||
|
||||
trace->origin[ 1 ] > light->maxs[ 1 ] || trace->origin[ 1 ] < light->mins[ 1 ] ||
|
||||
trace->origin[ 2 ] > light->maxs[ 2 ] || trace->origin[ 2 ] < light->mins[ 2 ] ) {
|
||||
if ( !light->minmax.test( trace->origin ) ) {
|
||||
gridBoundsCulled++;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* set light origin */
|
||||
if ( light->type == ELightType::Sun ) {
|
||||
VectorAdd( trace->origin, light->origin, trace->end );
|
||||
trace->end = trace->origin + light->origin;
|
||||
}
|
||||
else{
|
||||
VectorCopy( light->origin, trace->end );
|
||||
trace->end = light->origin;
|
||||
}
|
||||
|
||||
/* set direction */
|
||||
@@ -1315,11 +1304,11 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
/* exact point to polygon form factor */
|
||||
else if ( light->type == ELightType::Area ) {
|
||||
float factor, d;
|
||||
vec3_t pushedOrigin;
|
||||
Vector3 pushedOrigin;
|
||||
|
||||
|
||||
/* see if the point is behind the light */
|
||||
d = DotProduct( trace->origin, light->normal ) - light->dist;
|
||||
d = vector3_dot( trace->origin, light->normal ) - light->dist;
|
||||
if ( !( light->flags & LightFlags::Twosided ) && d < -1.0f ) {
|
||||
return false;
|
||||
}
|
||||
@@ -1327,10 +1316,10 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
/* nudge the point so that it is clearly forward of the light */
|
||||
/* so that surfaces meeting a light emiter don't get black edges */
|
||||
if ( d > -8.0f && d < 8.0f ) {
|
||||
VectorMA( trace->origin, ( 8.0f - d ), light->normal, pushedOrigin );
|
||||
pushedOrigin = trace->origin + light->normal * ( 8.0f - d );
|
||||
}
|
||||
else{
|
||||
VectorCopy( trace->origin, pushedOrigin );
|
||||
pushedOrigin = trace->origin;
|
||||
}
|
||||
|
||||
/* calculate the contribution (ydnar 2002-10-21: [bug 642] bad normal calc) */
|
||||
@@ -1372,19 +1361,15 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
|
||||
/* handle spotlights */
|
||||
if ( light->type == ELightType::Spot ) {
|
||||
float distByNormal, radiusAtDist, sampleRadius;
|
||||
vec3_t pointAtDist, distToSample;
|
||||
|
||||
|
||||
/* do cone calculation */
|
||||
distByNormal = -DotProduct( trace->displacement, light->normal );
|
||||
const float distByNormal = -vector3_dot( trace->displacement, light->normal );
|
||||
if ( distByNormal < 0.0f ) {
|
||||
return false;
|
||||
}
|
||||
VectorMA( light->origin, distByNormal, light->normal, pointAtDist );
|
||||
radiusAtDist = light->radiusByDist * distByNormal;
|
||||
VectorSubtract( trace->origin, pointAtDist, distToSample );
|
||||
sampleRadius = VectorLength( distToSample );
|
||||
const Vector3 pointAtDist = light->origin + light->normal * distByNormal;
|
||||
const float radiusAtDist = light->radiusByDist * distByNormal;
|
||||
const Vector3 distToSample = trace->origin - pointAtDist;
|
||||
const float sampleRadius = vector3_length( distToSample );
|
||||
|
||||
/* outside the cone */
|
||||
if ( sampleRadius >= radiusAtDist ) {
|
||||
@@ -1408,14 +1393,14 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
|
||||
/* setup trace */
|
||||
trace->testAll = true;
|
||||
VectorScale( light->color, add, trace->color );
|
||||
trace->color = light->color * add;
|
||||
|
||||
/* trace to point */
|
||||
if ( trace->testOcclusion && !trace->forceSunlight ) {
|
||||
/* trace */
|
||||
TraceLine( trace );
|
||||
if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) {
|
||||
VectorClear( trace->color );
|
||||
trace->color.set( 0 );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1436,12 +1421,12 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
|
||||
/* setup trace */
|
||||
trace->testAll = false;
|
||||
VectorScale( light->color, add, trace->color );
|
||||
trace->color = light->color * add;
|
||||
|
||||
/* trace */
|
||||
TraceLine( trace );
|
||||
if ( trace->passSolid ) {
|
||||
VectorClear( trace->color );
|
||||
trace->color.set( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1461,16 +1446,16 @@ bool LightContributionToPoint( trace_t *trace ){
|
||||
|
||||
struct contribution_t
|
||||
{
|
||||
vec3_t dir;
|
||||
vec3_t color;
|
||||
vec3_t ambient;
|
||||
Vector3 dir;
|
||||
Vector3 color;
|
||||
Vector3 ambient;
|
||||
int style;
|
||||
};
|
||||
|
||||
void TraceGrid( int num ){
|
||||
int i, j, x, y, z, mod, numCon, numStyles;
|
||||
float d, step;
|
||||
vec3_t baseOrigin, cheapColor, color, thisdir;
|
||||
Vector3 cheapColor, thisdir;
|
||||
rawGridPoint_t *gp;
|
||||
bspGridPoint_t *bgp;
|
||||
contribution_t contributions[ MAX_CONTRIBUTIONS ];
|
||||
@@ -1507,10 +1492,10 @@ void TraceGrid( int num ){
|
||||
trace.cluster = ClusterForPointExt( trace.origin, GRID_EPSILON );
|
||||
if ( trace.cluster < 0 ) {
|
||||
/* try to nudge the origin around to find a valid point */
|
||||
VectorCopy( trace.origin, baseOrigin );
|
||||
const Vector3 baseOrigin( trace.origin );
|
||||
for ( step = 0; ( step += 0.005 ) <= 1.0; )
|
||||
{
|
||||
VectorCopy( baseOrigin, trace.origin );
|
||||
trace.origin = baseOrigin;
|
||||
trace.origin[ 0 ] += step * ( Random() - 0.5 ) * gridSize[0];
|
||||
trace.origin[ 1 ] += step * ( Random() - 0.5 ) * gridSize[1];
|
||||
trace.origin[ 2 ] += step * ( Random() - 0.5 ) * gridSize[2];
|
||||
@@ -1539,7 +1524,7 @@ void TraceGrid( int num ){
|
||||
|
||||
/* clear */
|
||||
numCon = 0;
|
||||
VectorClear( cheapColor );
|
||||
cheapColor.set( 0 );
|
||||
|
||||
/* trace to all the lights, find the major light direction, and divide the
|
||||
total light between that along the direction and the remaining in the ambient */
|
||||
@@ -1555,19 +1540,19 @@ void TraceGrid( int num ){
|
||||
|
||||
/* handle negative light */
|
||||
if ( trace.light->flags & LightFlags::Negative ) {
|
||||
VectorScale( trace.color, -1.0f, trace.color );
|
||||
vector3_negate( trace.color );
|
||||
}
|
||||
|
||||
/* add a contribution */
|
||||
VectorCopy( trace.color, contributions[ numCon ].color );
|
||||
VectorCopy( trace.direction, contributions[ numCon ].dir );
|
||||
VectorClear( contributions[ numCon ].ambient );
|
||||
contributions[ numCon ].color = trace.color;
|
||||
contributions[ numCon ].dir = trace.direction;
|
||||
contributions[ numCon ].ambient.set( 0 );
|
||||
contributions[ numCon ].style = trace.light->style;
|
||||
numCon++;
|
||||
|
||||
/* push average direction around */
|
||||
addSize = VectorLength( trace.color );
|
||||
VectorMA( gp->dir, addSize, trace.direction, gp->dir );
|
||||
addSize = vector3_length( trace.color );
|
||||
gp->dir += trace.direction * addSize;
|
||||
|
||||
/* stop after a while */
|
||||
if ( numCon >= ( MAX_CONTRIBUTIONS - 1 ) ) {
|
||||
@@ -1575,7 +1560,7 @@ void TraceGrid( int num ){
|
||||
}
|
||||
|
||||
/* ydnar: cheap mode */
|
||||
VectorAdd( cheapColor, trace.color, cheapColor );
|
||||
cheapColor += trace.color;
|
||||
if ( cheapgrid && cheapColor[ 0 ] >= 255.0f && cheapColor[ 1 ] >= 255.0f && cheapColor[ 2 ] >= 255.0f ) {
|
||||
break;
|
||||
}
|
||||
@@ -1586,7 +1571,7 @@ void TraceGrid( int num ){
|
||||
if ( floodlighty ) {
|
||||
int k;
|
||||
float addSize, f;
|
||||
vec3_t dir = { 0, 0, 1 };
|
||||
Vector3 dir = g_vector3_axis_z;
|
||||
float ambientFrac = 0.25f;
|
||||
|
||||
trace.testOcclusion = true;
|
||||
@@ -1597,37 +1582,27 @@ void TraceGrid( int num ){
|
||||
for ( k = 0; k < 2; k++ )
|
||||
{
|
||||
if ( k == 0 ) { // upper hemisphere
|
||||
trace.normal[0] = 0;
|
||||
trace.normal[1] = 0;
|
||||
trace.normal[2] = 1;
|
||||
trace.normal = g_vector3_axis_z;
|
||||
}
|
||||
else //lower hemisphere
|
||||
{
|
||||
trace.normal[0] = 0;
|
||||
trace.normal[1] = 0;
|
||||
trace.normal[2] = -1;
|
||||
trace.normal = -g_vector3_axis_z;
|
||||
}
|
||||
|
||||
f = FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality );
|
||||
|
||||
/* add a fraction as pure ambient, half as top-down direction */
|
||||
contributions[ numCon ].color[0] = floodlightRGB[0] * floodlightIntensity * f * ( 1.0f - ambientFrac );
|
||||
contributions[ numCon ].color[1] = floodlightRGB[1] * floodlightIntensity * f * ( 1.0f - ambientFrac );
|
||||
contributions[ numCon ].color[2] = floodlightRGB[2] * floodlightIntensity * f * ( 1.0f - ambientFrac );
|
||||
contributions[ numCon ].color = floodlightRGB * ( floodlightIntensity * f * ( 1.0f - ambientFrac ) );
|
||||
|
||||
contributions[ numCon ].ambient[0] = floodlightRGB[0] * floodlightIntensity * f * ambientFrac;
|
||||
contributions[ numCon ].ambient[1] = floodlightRGB[1] * floodlightIntensity * f * ambientFrac;
|
||||
contributions[ numCon ].ambient[2] = floodlightRGB[2] * floodlightIntensity * f * ambientFrac;
|
||||
contributions[ numCon ].ambient = floodlightRGB * ( floodlightIntensity * f * ambientFrac );
|
||||
|
||||
contributions[ numCon ].dir[0] = dir[0];
|
||||
contributions[ numCon ].dir[1] = dir[1];
|
||||
contributions[ numCon ].dir[2] = dir[2];
|
||||
contributions[ numCon ].dir = dir;
|
||||
|
||||
contributions[ numCon ].style = 0;
|
||||
|
||||
/* push average direction around */
|
||||
addSize = VectorLength( contributions[ numCon ].color );
|
||||
VectorMA( gp->dir, addSize, dir, gp->dir );
|
||||
addSize = vector3_length( contributions[ numCon ].color );
|
||||
gp->dir += dir * addSize;
|
||||
|
||||
numCon++;
|
||||
}
|
||||
@@ -1635,7 +1610,7 @@ void TraceGrid( int num ){
|
||||
/////////////////////
|
||||
|
||||
/* normalize to get primary light direction */
|
||||
VectorNormalize( gp->dir, thisdir );
|
||||
thisdir = VectorNormalized( gp->dir );
|
||||
|
||||
/* now that we have identified the primary light direction,
|
||||
go back and separate all the light into directed and ambient */
|
||||
@@ -1644,7 +1619,7 @@ void TraceGrid( int num ){
|
||||
for ( i = 0; i < numCon; i++ )
|
||||
{
|
||||
/* get relative directed strength */
|
||||
d = DotProduct( contributions[ i ].dir, thisdir );
|
||||
d = vector3_dot( contributions[ i ].dir, thisdir );
|
||||
/* we map 1 to gridDirectionality, and 0 to gridAmbientDirectionality */
|
||||
d = gridAmbientDirectionality + d * ( gridDirectionality - gridAmbientDirectionality );
|
||||
if ( d < 0.0f ) {
|
||||
@@ -1676,7 +1651,7 @@ void TraceGrid( int num ){
|
||||
}
|
||||
|
||||
/* add the directed color */
|
||||
VectorMA( gp->directed[ j ], d, contributions[ i ].color, gp->directed[ j ] );
|
||||
gp->directed[ j ] += contributions[ i ].color * d;
|
||||
|
||||
/* ambient light will be at 1/4 the value of directed light */
|
||||
/* (ydnar: nuke this in favor of more dramatic lighting?) */
|
||||
@@ -1684,9 +1659,9 @@ void TraceGrid( int num ){
|
||||
// d = 0.25f;
|
||||
/* (Hobbes: always setting it to .25 is hardly any better) */
|
||||
d = 0.25f * ( 1.0f - d );
|
||||
VectorMA( gp->ambient[ j ], d, contributions[ i ].color, gp->ambient[ j ] );
|
||||
gp->ambient[ j ] += contributions[ i ].color * d;
|
||||
|
||||
VectorAdd( gp->ambient[ j ], contributions[ i ].ambient, gp->ambient[ j ] );
|
||||
gp->ambient[ j ] += contributions[ i ].ambient;
|
||||
|
||||
/*
|
||||
* div0:
|
||||
@@ -1714,7 +1689,7 @@ void TraceGrid( int num ){
|
||||
#endif
|
||||
|
||||
/* set minimum light and copy off to bytes */
|
||||
VectorCopy( gp->ambient[ i ], color );
|
||||
Vector3 color = gp->ambient[ i ];
|
||||
for ( j = 0; j < 3; j++ )
|
||||
if ( color[ j ] < minGridLight[ j ] ) {
|
||||
color[ j ] = minGridLight[ j ];
|
||||
@@ -1731,7 +1706,7 @@ void TraceGrid( int num ){
|
||||
*/
|
||||
if( bgp->ambient[i][0] + bgp->ambient[i][1] + bgp->ambient[i][2] == 0
|
||||
&& bgp->directed[i][0] + bgp->directed[i][1] + bgp->directed[i][2] != 0 )
|
||||
VectorSet( bgp->ambient[i], 1, 1, 1 );
|
||||
bgp->ambient[i].set( 1 );
|
||||
}
|
||||
|
||||
/* debug code */
|
||||
@@ -1756,7 +1731,6 @@ void TraceGrid( int num ){
|
||||
|
||||
void SetupGrid( void ){
|
||||
int i, j;
|
||||
vec3_t maxs, oldGridSize;
|
||||
char temp[ 64 ];
|
||||
|
||||
|
||||
@@ -1769,7 +1743,7 @@ void SetupGrid( void ){
|
||||
entities[ 0 ].read_keyvalue( gridSize, "gridsize" );
|
||||
|
||||
/* quantize it */
|
||||
VectorCopy( gridSize, oldGridSize );
|
||||
const Vector3 oldGridSize = gridSize;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
gridSize[ i ] = gridSize[ i ] >= 8.0f ? floor( gridSize[ i ] ) : 8.0f;
|
||||
|
||||
@@ -1781,9 +1755,9 @@ void SetupGrid( void ){
|
||||
/* get world bounds */
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
gridMins[ i ] = gridSize[ i ] * ceil( bspModels[ 0 ].mins[ i ] / gridSize[ i ] );
|
||||
maxs[ i ] = gridSize[ i ] * floor( bspModels[ 0 ].maxs[ i ] / gridSize[ i ] );
|
||||
gridBounds[ i ] = ( maxs[ i ] - gridMins[ i ] ) / gridSize[ i ] + 1;
|
||||
gridMins[ i ] = gridSize[ i ] * ceil( bspModels[ 0 ].minmax.mins[ i ] / gridSize[ i ] );
|
||||
const float max = gridSize[ i ] * floor( bspModels[ 0 ].minmax.maxs[ i ] / gridSize[ i ] );
|
||||
gridBounds[ i ] = ( max - gridMins[ i ] ) / gridSize[ i ] + 1;
|
||||
}
|
||||
|
||||
/* set grid size */
|
||||
@@ -1818,7 +1792,7 @@ void SetupGrid( void ){
|
||||
for ( i = 0; i < numRawGridPoints; i++ )
|
||||
{
|
||||
for ( j = 0; j < MAX_LIGHTMAPS; j++ )
|
||||
VectorCopy( ambientColor, rawGridPoints[ i ].ambient[ j ] );
|
||||
rawGridPoints[ i ].ambient[ j ] = ambientColor;
|
||||
|
||||
rawGridPoints[ i ].styles[ 0 ] = LS_NORMAL;
|
||||
bspGridPoints[ i ].styles[ 0 ] = LS_NORMAL;
|
||||
@@ -1841,7 +1815,7 @@ void SetupGrid( void ){
|
||||
*/
|
||||
|
||||
void LightWorld( bool fastAllocate ){
|
||||
vec3_t color;
|
||||
Vector3 color;
|
||||
float f;
|
||||
int b, bt;
|
||||
bool minVertex, minGrid;
|
||||
@@ -1860,31 +1834,31 @@ void LightWorld( bool fastAllocate ){
|
||||
color[1] = Image_LinearFloatFromsRGBFloat( color[1] );
|
||||
color[2] = Image_LinearFloatFromsRGBFloat( color[2] );
|
||||
}
|
||||
if ( VectorLength( color ) == 0.0f ) {
|
||||
VectorSet( color, 1.0, 1.0, 1.0 );
|
||||
if ( vector3_length( color ) == 0.0f ) {
|
||||
color.set( 1 );
|
||||
}
|
||||
|
||||
/* ambient */
|
||||
f = entities[ 0 ].floatForKey( "_ambient", "ambient" );
|
||||
VectorScale( color, f, ambientColor );
|
||||
ambientColor = color * f;
|
||||
|
||||
/* minvertexlight */
|
||||
if ( ( minVertex = entities[ 0 ].read_keyvalue( f, "_minvertexlight" ) ) ) {
|
||||
VectorScale( color, f, minVertexLight );
|
||||
minVertexLight = color * f;
|
||||
}
|
||||
|
||||
/* mingridlight */
|
||||
if ( ( minGrid = entities[ 0 ].read_keyvalue( f, "_mingridlight" ) ) ) {
|
||||
VectorScale( color, f, minGridLight );
|
||||
minGridLight = color * f;
|
||||
}
|
||||
|
||||
/* minlight */
|
||||
if ( entities[ 0 ].read_keyvalue( f, "_minlight" ) ) {
|
||||
VectorScale( color, f, minLight );
|
||||
minLight = color * f;
|
||||
if ( !minVertex )
|
||||
VectorScale( color, f, minVertexLight );
|
||||
minVertexLight = color * f;
|
||||
if ( !minGrid )
|
||||
VectorScale( color, f, minGridLight );
|
||||
minGridLight = color * f;
|
||||
}
|
||||
|
||||
/* maxlight */
|
||||
@@ -1982,7 +1956,7 @@ void LightWorld( bool fastAllocate ){
|
||||
|
||||
/* flag bouncing */
|
||||
bouncing = true;
|
||||
VectorClear( ambientColor );
|
||||
ambientColor.set( 0 );
|
||||
floodlighty = false;
|
||||
|
||||
/* generate diffuse lights */
|
||||
|
||||
@@ -65,13 +65,13 @@ void RadFreeLights( void ){
|
||||
based off the regular clip winding code
|
||||
*/
|
||||
|
||||
static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, radWinding_t *front, radWinding_t *back, clipWork_t *cw ){
|
||||
vec_t *dists;
|
||||
int *sides;
|
||||
static void RadClipWindingEpsilon( radWinding_t *in, const Vector3& normal, float dist,
|
||||
float epsilon, radWinding_t *front, radWinding_t *back, clipWork_t *cw ){
|
||||
float *dists;
|
||||
EPlaneSide *sides;
|
||||
int counts[ 3 ];
|
||||
vec_t dot; /* ydnar: changed from static b/c of threading */ /* VC 4.2 optimizer bug if not static? */
|
||||
int i, j, k;
|
||||
float dot; /* ydnar: changed from static b/c of threading */ /* VC 4.2 optimizer bug if not static? */
|
||||
int i, k;
|
||||
radVert_t *v1, *v2, mid;
|
||||
int maxPoints;
|
||||
|
||||
@@ -86,17 +86,15 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist,
|
||||
/* determine sides for each point */
|
||||
for ( i = 0; i < in->numVerts; i++ )
|
||||
{
|
||||
dot = DotProduct( in->verts[ i ].xyz, normal );
|
||||
dot -= dist;
|
||||
dists[ i ] = dot;
|
||||
if ( dot > epsilon ) {
|
||||
sides[ i ] = SIDE_FRONT;
|
||||
dists[ i ] = vector3_dot( in->verts[ i ].xyz, normal ) - dist;
|
||||
if ( dists[ i ] > epsilon ) {
|
||||
sides[ i ] = eSideFront;
|
||||
}
|
||||
else if ( dot < -epsilon ) {
|
||||
sides[ i ] = SIDE_BACK;
|
||||
else if ( dists[ i ] < -epsilon ) {
|
||||
sides[ i ] = eSideBack;
|
||||
}
|
||||
else{
|
||||
sides[ i ] = SIDE_ON;
|
||||
sides[ i ] = eSideOn;
|
||||
}
|
||||
counts[ sides[ i ] ]++;
|
||||
}
|
||||
@@ -125,21 +123,21 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist,
|
||||
/* do simple vertex copies first */
|
||||
v1 = &in->verts[ i ];
|
||||
|
||||
if ( sides[ i ] == SIDE_ON ) {
|
||||
if ( sides[ i ] == eSideOn ) {
|
||||
memcpy( &front->verts[ front->numVerts++ ], v1, sizeof( radVert_t ) );
|
||||
memcpy( &back->verts[ back->numVerts++ ], v1, sizeof( radVert_t ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[ i ] == SIDE_FRONT ) {
|
||||
if ( sides[ i ] == eSideFront ) {
|
||||
memcpy( &front->verts[ front->numVerts++ ], v1, sizeof( radVert_t ) );
|
||||
}
|
||||
|
||||
if ( sides[ i ] == SIDE_BACK ) {
|
||||
if ( sides[ i ] == eSideBack ) {
|
||||
memcpy( &back->verts[ back->numVerts++ ], v1, sizeof( radVert_t ) );
|
||||
}
|
||||
|
||||
if ( sides[ i + 1 ] == SIDE_ON || sides[ i + 1 ] == sides[ i ] ) {
|
||||
if ( sides[ i + 1 ] == eSideOn || sides[ i + 1 ] == sides[ i ] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -149,30 +147,20 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist,
|
||||
dot = dists[ i ] / ( dists[ i ] - dists[ i + 1 ] );
|
||||
|
||||
/* average vertex values */
|
||||
for ( j = 0; j < 4; j++ )
|
||||
{
|
||||
/* color */
|
||||
if ( j < 4 ) {
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
mid.color[ k ][ j ] = v1->color[ k ][ j ] + dot * ( v2->color[ k ][ j ] - v1->color[ k ][ j ] );
|
||||
}
|
||||
|
||||
/* xyz, normal */
|
||||
if ( j < 3 ) {
|
||||
mid.xyz[ j ] = v1->xyz[ j ] + dot * ( v2->xyz[ j ] - v1->xyz[ j ] );
|
||||
mid.normal[ j ] = v1->normal[ j ] + dot * ( v2->normal[ j ] - v1->normal[ j ] );
|
||||
}
|
||||
|
||||
/* st, lightmap */
|
||||
if ( j < 2 ) {
|
||||
mid.st[ j ] = v1->st[ j ] + dot * ( v2->st[ j ] - v1->st[ j ] );
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
mid.lightmap[ k ][ j ] = v1->lightmap[ k ][ j ] + dot * ( v2->lightmap[ k ][ j ] - v1->lightmap[ k ][ j ] );
|
||||
}
|
||||
/* color */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ ){
|
||||
mid.color[ k ] = v1->color[ k ] + ( v2->color[ k ] - v1->color[ k ] ) * dot;
|
||||
}
|
||||
/* xyz, normal */
|
||||
mid.xyz = v1->xyz + ( v2->xyz - v1->xyz ) * dot;
|
||||
mid.normal = v1->normal + ( v2->normal - v1->normal ) * dot;
|
||||
/* st, lightmap */
|
||||
mid.st = v1->st + ( v2->st - v1->st ) * dot;
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
mid.lightmap[ k ] = v1->lightmap[ k ] + ( v2->lightmap[ k ] - v1->lightmap[ k ] ) * dot;
|
||||
|
||||
/* normalize the averaged normal */
|
||||
VectorNormalize( mid.normal, mid.normal );
|
||||
VectorNormalize( mid.normal );
|
||||
|
||||
/* copy the midpoint to both windings */
|
||||
memcpy( &front->verts[ front->numVerts++ ], &mid, sizeof( radVert_t ) );
|
||||
@@ -201,11 +189,11 @@ float Modulo1IfNegative( float f ){
|
||||
returns false if pixels are bad
|
||||
*/
|
||||
|
||||
bool RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float color[ 4 ] ){
|
||||
bool RadSampleImage( byte *pixels, int width, int height, const Vector2& st, Color4f& color ){
|
||||
int x, y;
|
||||
|
||||
/* clear color first */
|
||||
color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 255;
|
||||
color.set( 255 );
|
||||
|
||||
/* dummy check */
|
||||
if ( pixels == NULL || width < 1 || height < 1 ) {
|
||||
@@ -220,8 +208,8 @@ bool RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float c
|
||||
|
||||
/* get pixel */
|
||||
pixels += ( y * width * 4 ) + ( x * 4 );
|
||||
VectorCopy( pixels, color );
|
||||
color[ 3 ] = pixels[ 3 ];
|
||||
VectorCopy( pixels, color.rgb() );
|
||||
color.alpha() = pixels[ 3 ];
|
||||
|
||||
if ( texturesRGB ) {
|
||||
color[0] = Image_LinearFloatFromsRGBFloat( color[0] * ( 1.0 / 255.0 ) ) * 255.0;
|
||||
@@ -243,22 +231,20 @@ bool RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float c
|
||||
#define MAX_SAMPLES 150
|
||||
#define SAMPLE_GRANULARITY 6
|
||||
|
||||
static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si, radWinding_t *rw, vec3_t average, vec3_t gradient, int *style ){
|
||||
int i, j, k, l, v, x, y, samples, avgcolor;
|
||||
vec3_t color, mins, maxs;
|
||||
vec4_t textureColor;
|
||||
float alpha, alphaI, bf;
|
||||
vec3_t blend;
|
||||
float st[ 2 ], lightmap[ 2 ], *radLuxel;
|
||||
static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si, radWinding_t *rw, Vector3& average, Vector3& gradient, int *style ){
|
||||
int i, j, k, l, v, x, y, samples;
|
||||
Vector3 color;
|
||||
MinMax minmax;
|
||||
Color4f textureColor;
|
||||
float alpha, alphaI;
|
||||
radVert_t *rv[ 3 ];
|
||||
|
||||
if (!bouncing)
|
||||
if ( !bouncing )
|
||||
Sys_Printf( "BUG: RadSample: !bouncing shouldn't happen\n" );
|
||||
|
||||
/* initial setup */
|
||||
ClearBounds( mins, maxs );
|
||||
VectorClear( average );
|
||||
VectorClear( gradient );
|
||||
average.set( 0 );
|
||||
gradient.set( 0 );
|
||||
alpha = 0;
|
||||
|
||||
/* dummy check */
|
||||
@@ -275,19 +261,18 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
|
||||
{
|
||||
/* multiply by texture color */
|
||||
if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, rw->verts[ samples ].st, textureColor ) ) {
|
||||
VectorCopy( si->averageColor, textureColor );
|
||||
textureColor[ 3 ] = 255.0f;
|
||||
textureColor.rgb() = si->averageColor.rgb();
|
||||
textureColor.alpha() = 255.0f;
|
||||
}
|
||||
avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
color[ i ] = ( ( textureColor[ i ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f );
|
||||
// color[ i ] = ( textureColor[ i ] / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f );
|
||||
const float avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
|
||||
color = ( ( textureColor.rgb() * bounceColorRatio + Vector3().set( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ].rgb() / 255.0f );
|
||||
// color = ( textureColor.rgb / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ].rgb / 255.0f );
|
||||
|
||||
AddPointToBounds( color, mins, maxs );
|
||||
VectorAdd( average, color, average );
|
||||
minmax.extend( color );
|
||||
average += color;
|
||||
|
||||
/* get alpha */
|
||||
alpha += ( textureColor[ 3 ] / 255.0f ) * ( rw->verts[ samples ].color[ lightmapNum ][ 3 ] / 255.0f );
|
||||
alpha += ( textureColor.alpha() / 255.0f ) * ( rw->verts[ samples ].color[ lightmapNum ].alpha() / 255.0f );
|
||||
}
|
||||
|
||||
/* set style */
|
||||
@@ -313,23 +298,18 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
|
||||
for ( k = 1; k < SAMPLE_GRANULARITY && samples < MAX_SAMPLES; k++ )
|
||||
{
|
||||
/* create a blend vector (barycentric coordinates) */
|
||||
blend[ 0 ] = i;
|
||||
blend[ 1 ] = j;
|
||||
blend[ 2 ] = k;
|
||||
bf = ( 1.0 / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] ) );
|
||||
VectorScale( blend, bf, blend );
|
||||
DoubleVector3 blend( i, j, k );
|
||||
blend *= 1.0 / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] );
|
||||
|
||||
/* create a blended sample */
|
||||
st[ 0 ] = st[ 1 ] = 0.0f;
|
||||
lightmap[ 0 ] = lightmap[ 1 ] = 0.0f;
|
||||
Vector2 st( 0, 0 );
|
||||
Vector2 lightmap( 0, 0 );
|
||||
alphaI = 0.0f;
|
||||
for ( l = 0; l < 3; l++ )
|
||||
{
|
||||
st[ 0 ] += ( rv[ l ]->st[ 0 ] * blend[ l ] );
|
||||
st[ 1 ] += ( rv[ l ]->st[ 1 ] * blend[ l ] );
|
||||
lightmap[ 0 ] += ( rv[ l ]->lightmap[ lightmapNum ][ 0 ] * blend[ l ] );
|
||||
lightmap[ 1 ] += ( rv[ l ]->lightmap[ lightmapNum ][ 1 ] * blend[ l ] );
|
||||
alphaI += ( rv[ l ]->color[ lightmapNum ][ 3 ] * blend[ l ] );
|
||||
st += rv[ l ]->st * blend[ l ];
|
||||
lightmap += rv[ l ]->lightmap[ lightmapNum ] * blend[ l ];
|
||||
alphaI += rv[ l ]->color[ lightmapNum ].alpha() * blend[ l ];
|
||||
}
|
||||
|
||||
/* get lightmap xy coords */
|
||||
@@ -349,7 +329,7 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
|
||||
}
|
||||
|
||||
/* get radiosity luxel */
|
||||
radLuxel = RAD_LUXEL( lightmapNum, x, y );
|
||||
const Vector3& radLuxel = lm->getRadLuxel( lightmapNum, x, y );
|
||||
|
||||
/* ignore unlit/unused luxels */
|
||||
if ( radLuxel[ 0 ] < 0.0f ) {
|
||||
@@ -361,19 +341,17 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
|
||||
|
||||
/* multiply by texture color */
|
||||
if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, st, textureColor ) ) {
|
||||
VectorCopy( si->averageColor, textureColor );
|
||||
textureColor[ 3 ] = 255;
|
||||
textureColor.rgb() = si->averageColor.rgb();
|
||||
textureColor.alpha() = 255;
|
||||
}
|
||||
avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
|
||||
for ( l = 0; l < 3; l++ ){
|
||||
color[ l ] = ( ( textureColor[ l ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( radLuxel[ l ] / 255 );
|
||||
//Sys_Printf( "%i %i %i %i %i \n", (int) textureColor[ 0 ], (int) textureColor[ 1 ], (int) textureColor[ 2 ], (int) avgcolor, (int) color[ i ] );
|
||||
}
|
||||
AddPointToBounds( color, mins, maxs );
|
||||
VectorAdd( average, color, average );
|
||||
const float avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
|
||||
color = ( ( textureColor.rgb() * bounceColorRatio + Vector3().set( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( radLuxel / 255 );
|
||||
//Sys_Printf( "%i %i %i %i %i \n", (int) textureColor.rgb[ 0 ], (int) textureColor.rgb[ 1 ], (int) textureColor.rgb[ 2 ], (int) avgcolor, (int) color[ i ] );
|
||||
minmax.extend( color );
|
||||
average += color;
|
||||
|
||||
/* get alpha */
|
||||
alpha += ( textureColor[ 3 ] / 255 ) * ( alphaI / 255 );
|
||||
alpha += ( textureColor.alpha() / 255 ) * ( alphaI / 255 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,19 +367,18 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
|
||||
}
|
||||
|
||||
/* average the color */
|
||||
VectorScale( average, ( 1.0 / samples ), average );
|
||||
average *= ( 1.0 / samples );
|
||||
|
||||
/* create the color gradient */
|
||||
//% VectorSubtract( maxs, mins, delta );
|
||||
//% VectorSubtract( minmax.maxs, minmax.mins, delta );
|
||||
|
||||
/* new: color gradient will always be 0-1.0, expressed as the range of light relative to overall light */
|
||||
//% gradient[ 0 ] = maxs[ 0 ] > 0.0f ? (maxs[ 0 ] - mins[ 0 ]) / maxs[ 0 ] : 0.0f;
|
||||
//% gradient[ 1 ] = maxs[ 1 ] > 0.0f ? (maxs[ 1 ] - mins[ 1 ]) / maxs[ 1 ] : 0.0f;
|
||||
//% gradient[ 2 ] = maxs[ 2 ] > 0.0f ? (maxs[ 2 ] - mins[ 2 ]) / maxs[ 2 ] : 0.0f;
|
||||
//% gradient[ 0 ] = minmax.maxs[ 0 ] > 0.0f ? (minmax.maxs[ 0 ] - minmax.mins[ 0 ]) / minmax.maxs[ 0 ] : 0.0f;
|
||||
//% gradient[ 1 ] = minmax.maxs[ 1 ] > 0.0f ? (minmax.maxs[ 1 ] - minmax.mins[ 1 ]) / minmax.maxs[ 1 ] : 0.0f;
|
||||
//% gradient[ 2 ] = minmax.maxs[ 2 ] > 0.0f ? (minmax.maxs[ 2 ] - minmax.mins[ 2 ]) / minmax.maxs[ 2 ] : 0.0f;
|
||||
|
||||
/* newer: another contrast function */
|
||||
for ( i = 0; i < 3; i++ )
|
||||
gradient[ i ] = ( maxs[ i ] - mins[ i ] ) * maxs[ i ];
|
||||
gradient = ( minmax.maxs - minmax.mins ) * minmax.maxs;
|
||||
}
|
||||
|
||||
|
||||
@@ -422,7 +399,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
float scale, float subdivide, radWinding_t *rw, clipWork_t *cw ){
|
||||
int i, style = 0;
|
||||
float dist, area, value;
|
||||
vec3_t mins, maxs, normal, d1, d2, cross, color, gradient;
|
||||
Vector3 normal, color, gradient;
|
||||
light_t *light, *splash;
|
||||
winding_t *w, *splash_w;
|
||||
|
||||
@@ -433,24 +410,22 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
}
|
||||
|
||||
/* get bounds for winding */
|
||||
ClearBounds( mins, maxs );
|
||||
MinMax minmax;
|
||||
for ( i = 0; i < rw->numVerts; i++ )
|
||||
AddPointToBounds( rw->verts[ i ].xyz, mins, maxs );
|
||||
minmax.extend( rw->verts[ i ].xyz );
|
||||
|
||||
/* subdivide if necessary */
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( maxs[ i ] - mins[ i ] > subdivide ) {
|
||||
if ( minmax.maxs[ i ] - minmax.mins[ i ] > subdivide ) {
|
||||
auto front = std::make_unique<radWinding_t>();
|
||||
auto back = std::make_unique<radWinding_t>();
|
||||
|
||||
/* make axial plane */
|
||||
VectorClear( normal );
|
||||
normal[ i ] = 1;
|
||||
dist = ( maxs[ i ] + mins[ i ] ) * 0.5f;
|
||||
dist = ( minmax.maxs[ i ] + minmax.mins[ i ] ) * 0.5f;
|
||||
|
||||
/* clip the winding */
|
||||
RadClipWindingEpsilon( rw, normal, dist, RADIOSITY_CLIP_EPSILON, front.get(), back.get(), cw );
|
||||
RadClipWindingEpsilon( rw, g_vector3_axes[i], dist, RADIOSITY_CLIP_EPSILON, front.get(), back.get(), cw );
|
||||
|
||||
/* recurse */
|
||||
RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, front.get(), cw );
|
||||
@@ -463,10 +438,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
area = 0.0f;
|
||||
for ( i = 2; i < rw->numVerts; i++ )
|
||||
{
|
||||
VectorSubtract( rw->verts[ i - 1 ].xyz, rw->verts[ 0 ].xyz, d1 );
|
||||
VectorSubtract( rw->verts[ i ].xyz, rw->verts[ 0 ].xyz, d2 );
|
||||
CrossProduct( d1, d2, cross );
|
||||
area += 0.5f * VectorLength( cross );
|
||||
area += 0.5f * vector3_length( vector3_cross( rw->verts[ i - 1 ].xyz - rw->verts[ 0 ].xyz, rw->verts[ i ].xyz - rw->verts[ 0 ].xyz ) );
|
||||
}
|
||||
if ( area < 1.0f || area > 20000000.0f ) {
|
||||
return;
|
||||
@@ -488,24 +460,24 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
/* create a regular winding and an average normal */
|
||||
w = AllocWinding( rw->numVerts );
|
||||
w->numpoints = rw->numVerts;
|
||||
VectorClear( normal );
|
||||
normal.set( 0 );
|
||||
for ( i = 0; i < rw->numVerts; i++ )
|
||||
{
|
||||
VectorCopy( rw->verts[ i ].xyz, w->p[ i ] );
|
||||
VectorAdd( normal, rw->verts[ i ].normal, normal );
|
||||
w->p[ i ] = rw->verts[ i ].xyz;
|
||||
normal += rw->verts[ i ].normal;
|
||||
}
|
||||
VectorScale( normal, ( 1.0f / rw->numVerts ), normal );
|
||||
if ( VectorNormalize( normal, normal ) == 0.0f ) {
|
||||
normal /= rw->numVerts;
|
||||
if ( VectorNormalize( normal ) == 0.0f ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* early out? */
|
||||
if ( bouncing && VectorLength( color ) < RADIOSITY_MIN ) {
|
||||
if ( bouncing && vector3_length( color ) < RADIOSITY_MIN ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* debug code */
|
||||
//% Sys_Printf( "Size: %d %d %d\n", (int) (maxs[ 0 ] - mins[ 0 ]), (int) (maxs[ 1 ] - mins[ 1 ]), (int) (maxs[ 2 ] - mins[ 2 ]) );
|
||||
//% Sys_Printf( "Size: %d %d %d\n", (int) (minmax.maxs[ 0 ] - minmax.mins[ 0 ]), (int) (minmax.maxs[ 1 ] - minmax.mins[ 1 ]), (int) (minmax.maxs[ 2 ] - minmax.mins[ 2 ]) );
|
||||
//% Sys_Printf( "Grad: %f %f %f\n", gradient[ 0 ], gradient[ 1 ], gradient[ 2 ] );
|
||||
|
||||
/* increment counts */
|
||||
@@ -553,21 +525,20 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
value = si->value;
|
||||
light->photons = value * area * areaScale;
|
||||
light->add = value * formFactorValueScale * areaScale;
|
||||
VectorCopy( si->color, light->color );
|
||||
VectorScale( light->color, light->add, light->emitColor );
|
||||
light->color = si->color;
|
||||
light->emitColor = light->color * light->add;
|
||||
light->style = noStyles ? LS_NORMAL : si->lightStyle;
|
||||
if ( light->style < LS_NORMAL || light->style >= LS_NONE ) {
|
||||
light->style = LS_NORMAL;
|
||||
}
|
||||
|
||||
/* set origin */
|
||||
VectorAdd( mins, maxs, light->origin );
|
||||
VectorScale( light->origin, 0.5f, light->origin );
|
||||
light->origin = minmax.origin();
|
||||
|
||||
/* nudge it off the plane a bit */
|
||||
VectorCopy( normal, light->normal );
|
||||
VectorMA( light->origin, 1.0f, light->normal, light->origin );
|
||||
light->dist = DotProduct( light->origin, normal );
|
||||
light->normal = normal;
|
||||
light->origin += light->normal;
|
||||
light->dist = vector3_dot( light->origin, normal );
|
||||
|
||||
#if 0
|
||||
/* optionally create a point backsplash light */
|
||||
@@ -587,8 +558,8 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
|
||||
splash->fade = 1.0f;
|
||||
splash->si = si;
|
||||
VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
|
||||
VectorCopy( si->color, splash->color );
|
||||
splash->origin = normal * si->backsplashDistance + light->origin;
|
||||
splash->color = si->color;
|
||||
|
||||
splash->falloffTolerance = falloffTolerance;
|
||||
splash->style = noStyles ? LS_NORMAL : light->style;
|
||||
@@ -616,8 +587,8 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
splash->add = light->add * 7.0f * si->backsplashFraction;
|
||||
splash->fade = 1.0f;
|
||||
splash->si = si;
|
||||
VectorCopy( si->color, splash->color );
|
||||
VectorScale( splash->color, splash->add, splash->emitColor );
|
||||
splash->color = si->color;
|
||||
splash->emitColor = splash->color * splash->add;
|
||||
splash->falloffTolerance = falloffTolerance;
|
||||
splash->style = noStyles ? LS_NORMAL : si->lightStyle;
|
||||
if ( splash->style < LS_NORMAL || splash->style >= LS_NONE ) {
|
||||
@@ -628,12 +599,12 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
splash_w = AllocWinding( rw->numVerts );
|
||||
splash_w->numpoints = rw->numVerts;
|
||||
for ( i = 0; i < rw->numVerts; i++ )
|
||||
VectorMA( rw->verts[rw->numVerts - 1 - i].xyz, si->backsplashDistance, normal, splash_w->p[ i ] );
|
||||
splash_w->p[ i ] = normal * si->backsplashDistance + rw->verts[rw->numVerts - 1 - i].xyz;
|
||||
splash->w = splash_w;
|
||||
|
||||
VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
|
||||
VectorNegate( normal, splash->normal );
|
||||
splash->dist = DotProduct( splash->origin, splash->normal );
|
||||
splash->origin = normal * si->backsplashDistance + light->origin;
|
||||
splash->normal = -normal;
|
||||
splash->dist = vector3_dot( splash->origin, splash->normal );
|
||||
|
||||
// splash->flags |= LightFlags::Twosided;
|
||||
}
|
||||
@@ -646,20 +617,20 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
value = RADIOSITY_VALUE * si->bounceScale * 0.375f;
|
||||
light->photons = value * area * bounceScale;
|
||||
light->add = value * formFactorValueScale * bounceScale;
|
||||
VectorCopy( color, light->color );
|
||||
VectorScale( light->color, light->add, light->emitColor );
|
||||
light->color = color;
|
||||
light->emitColor = light->color * light->add;
|
||||
light->style = noStyles ? LS_NORMAL : style;
|
||||
if ( light->style < LS_NORMAL || light->style >= LS_NONE ) {
|
||||
light->style = LS_NORMAL;
|
||||
}
|
||||
|
||||
/* set origin */
|
||||
WindingCenter( w, light->origin );
|
||||
light->origin = WindingCenter( w );
|
||||
|
||||
/* nudge it off the plane a bit */
|
||||
VectorCopy( normal, light->normal );
|
||||
VectorMA( light->origin, 1.0f, light->normal, light->origin );
|
||||
light->dist = DotProduct( light->origin, normal );
|
||||
light->normal = normal;
|
||||
light->origin += light->normal;
|
||||
light->dist = vector3_dot( light->origin, normal );
|
||||
}
|
||||
|
||||
if (light->photons < 0 || light->add < 0 || light->color[0] < 0 || light->color[1] < 0 || light->color[2] < 0)
|
||||
@@ -685,7 +656,6 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
||||
void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t *si, float scale, float subdivide, clipWork_t *cw ){
|
||||
int i, j, k, v;
|
||||
bspDrawSurface_t *ds;
|
||||
float *radVertexLuxel;
|
||||
radWinding_t rw;
|
||||
|
||||
|
||||
@@ -708,9 +678,8 @@ void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderIn
|
||||
/* fix colors */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
radVertexLuxel = RAD_VERTEX_LUXEL( k, ds->firstVert + bspDrawIndexes[ ds->firstIndex + i + j ] );
|
||||
VectorCopy( radVertexLuxel, rw.verts[ j ].color[ k ] );
|
||||
rw.verts[ j ].color[ k ][ 3 ] = yDrawVerts[ v ].color[ k ][ 3 ];
|
||||
rw.verts[ j ].color[ k ].rgb() = getRadVertexLuxel( k, ds->firstVert + bspDrawIndexes[ ds->firstIndex + i + j ] );
|
||||
rw.verts[ j ].color[ k ].alpha() = yDrawVerts[ v ].color[ k ].alpha();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,9 +704,6 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t
|
||||
bspDrawVert_t *bogus;
|
||||
bspDrawVert_t *dv[ 4 ];
|
||||
mesh_t src, *subdivided, *mesh;
|
||||
float *radVertexLuxel;
|
||||
float dist;
|
||||
vec4_t plane;
|
||||
bool planar;
|
||||
radWinding_t rw;
|
||||
|
||||
@@ -798,10 +764,10 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t
|
||||
dv[ 3 ] = &mesh->verts[ pw[ r + 3 ] ];
|
||||
|
||||
/* planar? */
|
||||
Plane3f plane;
|
||||
planar = PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz );
|
||||
if ( planar ) {
|
||||
dist = DotProduct( dv[ 1 ]->xyz, plane ) - plane[ 3 ];
|
||||
if ( fabs( dist ) > PLANAR_EPSILON ) {
|
||||
if ( fabs( plane3_distance_to_point( plane, dv[ 1 ]->xyz ) ) > PLANAR_EPSILON ) {
|
||||
planar = false;
|
||||
}
|
||||
}
|
||||
@@ -817,9 +783,8 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t
|
||||
/* fix colors */
|
||||
for ( i = 0; i < MAX_LIGHTMAPS; i++ )
|
||||
{
|
||||
radVertexLuxel = RAD_VERTEX_LUXEL( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] );
|
||||
VectorCopy( radVertexLuxel, rw.verts[ v ].color[ i ] );
|
||||
rw.verts[ v ].color[ i ][ 3 ] = dv[ v ]->color[ i ][ 3 ];
|
||||
rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] );
|
||||
rw.verts[ v ].color[ i ].alpha() = dv[ v ]->color[ i ].alpha();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,9 +811,8 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t
|
||||
/* fix colors */
|
||||
for ( i = 0; i < MAX_LIGHTMAPS; i++ )
|
||||
{
|
||||
radVertexLuxel = RAD_VERTEX_LUXEL( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] );
|
||||
VectorCopy( radVertexLuxel, rw.verts[ v ].color[ i ] );
|
||||
rw.verts[ v ].color[ i ][ 3 ] = dv[ v ]->color[ i ][ 3 ];
|
||||
rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] );
|
||||
rw.verts[ v ].color[ i ].alpha() = dv[ v ]->color[ i ].alpha();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+132
-147
@@ -38,7 +38,6 @@
|
||||
|
||||
|
||||
#define Vector2Copy( a, b ) ( ( b )[ 0 ] = ( a )[ 0 ], ( b )[ 1 ] = ( a )[ 1 ] )
|
||||
#define Vector4Copy( a, b ) ( ( b )[ 0 ] = ( a )[ 0 ], ( b )[ 1 ] = ( a )[ 1 ], ( b )[ 2 ] = ( a )[ 2 ], ( b )[ 3 ] = ( a )[ 3 ] )
|
||||
|
||||
#define MAX_NODE_ITEMS 5
|
||||
#define MAX_NODE_TRIANGLES 5
|
||||
@@ -60,8 +59,8 @@
|
||||
|
||||
struct traceVert_t
|
||||
{
|
||||
vec3_t xyz;
|
||||
float st[ 2 ];
|
||||
Vector3 xyz;
|
||||
Vector2 st;
|
||||
};
|
||||
|
||||
struct traceInfo_t
|
||||
@@ -73,14 +72,14 @@ struct traceInfo_t
|
||||
|
||||
struct traceWinding_t
|
||||
{
|
||||
vec4_t plane;
|
||||
Plane3f plane;
|
||||
int infoNum, numVerts;
|
||||
traceVert_t v[ MAX_TW_VERTS ];
|
||||
};
|
||||
|
||||
struct traceTriangle_t
|
||||
{
|
||||
vec3_t edge1, edge2;
|
||||
Vector3 edge1, edge2;
|
||||
int infoNum;
|
||||
traceVert_t v[ 3 ];
|
||||
};
|
||||
@@ -88,8 +87,8 @@ struct traceTriangle_t
|
||||
struct traceNode_t
|
||||
{
|
||||
int type;
|
||||
vec4_t plane;
|
||||
vec3_t mins, maxs;
|
||||
Plane3f plane;
|
||||
MinMax minmax;
|
||||
int children[ 2 ];
|
||||
int numItems, maxItems;
|
||||
int *items;
|
||||
@@ -165,7 +164,7 @@ static int AllocTraceNode( void ){
|
||||
/* add the node */
|
||||
memset( &traceNodes[ numTraceNodes ], 0, sizeof( traceNode_t ) );
|
||||
traceNodes[ numTraceNodes ].type = TRACE_LEAF;
|
||||
ClearBounds( traceNodes[ numTraceNodes ].mins, traceNodes[ numTraceNodes ].maxs );
|
||||
traceNodes[ numTraceNodes ].minmax.clear();
|
||||
|
||||
/* Sys_Printf("alloc node %d\n", numTraceNodes); */
|
||||
|
||||
@@ -233,8 +232,8 @@ static int AddTraceTriangle( traceTriangle_t *tt ){
|
||||
}
|
||||
|
||||
/* find vectors for two edges sharing the first vert */
|
||||
VectorSubtract( tt->v[ 1 ].xyz, tt->v[ 0 ].xyz, tt->edge1 );
|
||||
VectorSubtract( tt->v[ 2 ].xyz, tt->v[ 0 ].xyz, tt->edge2 );
|
||||
tt->edge1 = tt->v[ 1 ].xyz - tt->v[ 0 ].xyz;
|
||||
tt->edge2 = tt->v[ 2 ].xyz - tt->v[ 0 ].xyz;
|
||||
|
||||
/* add the triangle */
|
||||
memcpy( &traceTriangles[ num ], tt, sizeof( *traceTriangles ) );
|
||||
@@ -302,28 +301,25 @@ static int AddItemToTraceNode( traceNode_t *node, int num ){
|
||||
|
||||
static int SetupTraceNodes_r( int bspNodeNum ){
|
||||
int i, nodeNum, bspLeafNum, newNode;
|
||||
bspPlane_t *plane;
|
||||
bspNode_t *bspNode;
|
||||
|
||||
|
||||
/* get bsp node and plane */
|
||||
bspNode = &bspNodes[ bspNodeNum ];
|
||||
plane = &bspPlanes[ bspNode->planeNum ];
|
||||
const bspNode_t& bspNode = bspNodes[ bspNodeNum ];
|
||||
const bspPlane_t& plane = bspPlanes[ bspNode.planeNum ];
|
||||
|
||||
/* allocate a new trace node */
|
||||
nodeNum = AllocTraceNode();
|
||||
|
||||
/* setup trace node */
|
||||
traceNodes[ nodeNum ].type = PlaneTypeForNormal( plane->normal );
|
||||
VectorCopy( plane->normal, traceNodes[ nodeNum ].plane );
|
||||
traceNodes[ nodeNum ].plane[ 3 ] = plane->dist;
|
||||
traceNodes[ nodeNum ].type = PlaneTypeForNormal( plane.normal() );
|
||||
traceNodes[ nodeNum ].plane = plane;
|
||||
|
||||
/* setup children */
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
/* leafnode */
|
||||
if ( bspNode->children[ i ] < 0 ) {
|
||||
bspLeafNum = -bspNode->children[ i ] - 1;
|
||||
if ( bspNode.children[ i ] < 0 ) {
|
||||
bspLeafNum = -bspNode.children[ i ] - 1;
|
||||
|
||||
/* new code */
|
||||
newNode = AllocTraceNode();
|
||||
@@ -338,7 +334,7 @@ static int SetupTraceNodes_r( int bspNodeNum ){
|
||||
/* normal node */
|
||||
else
|
||||
{
|
||||
newNode = SetupTraceNodes_r( bspNode->children[ i ] );
|
||||
newNode = SetupTraceNodes_r( bspNode.children[ i ] );
|
||||
traceNodes[ nodeNum ].children[ i ] = newNode;
|
||||
}
|
||||
|
||||
@@ -362,9 +358,10 @@ static int SetupTraceNodes_r( int bspNodeNum ){
|
||||
|
||||
#define TW_ON_EPSILON 0.25f
|
||||
|
||||
void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, traceWinding_t *back ){
|
||||
void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t *front, traceWinding_t *back ){
|
||||
int i, j, k;
|
||||
int sides[ MAX_TW_VERTS ], counts[ 3 ] = { 0, 0, 0 };
|
||||
EPlaneSide sides[ MAX_TW_VERTS ];
|
||||
int counts[ 3 ] = { 0, 0, 0 };
|
||||
float dists[ MAX_TW_VERTS ];
|
||||
float frac;
|
||||
traceVert_t *a, *b, mid;
|
||||
@@ -377,26 +374,26 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front,
|
||||
/* classify points */
|
||||
for ( i = 0; i < tw->numVerts; i++ )
|
||||
{
|
||||
dists[ i ] = DotProduct( tw->v[ i ].xyz, plane ) - plane[ 3 ];
|
||||
dists[ i ] = plane3_distance_to_point( plane, tw->v[ i ].xyz );
|
||||
if ( dists[ i ] < -TW_ON_EPSILON ) {
|
||||
sides[ i ] = SIDE_BACK;
|
||||
sides[ i ] = eSideBack;
|
||||
}
|
||||
else if ( dists[ i ] > TW_ON_EPSILON ) {
|
||||
sides[ i ] = SIDE_FRONT;
|
||||
sides[ i ] = eSideFront;
|
||||
}
|
||||
else{
|
||||
sides[ i ] = SIDE_ON;
|
||||
sides[ i ] = eSideOn;
|
||||
}
|
||||
counts[ sides[ i ] ]++;
|
||||
}
|
||||
|
||||
/* entirely on front? */
|
||||
if ( counts[ SIDE_BACK ] == 0 ) {
|
||||
if ( counts[ eSideBack ] == 0 ) {
|
||||
memcpy( front, tw, sizeof( *front ) );
|
||||
}
|
||||
|
||||
/* entirely on back? */
|
||||
else if ( counts[ SIDE_FRONT ] == 0 ) {
|
||||
else if ( counts[ eSideFront ] == 0 ) {
|
||||
memcpy( back, tw, sizeof( *back ) );
|
||||
}
|
||||
|
||||
@@ -422,21 +419,21 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front,
|
||||
/* handle points on the splitting plane */
|
||||
switch ( sides[ i ] )
|
||||
{
|
||||
case SIDE_FRONT:
|
||||
case eSideFront:
|
||||
if ( front->numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
front->v[ front->numVerts++ ] = *a;
|
||||
break;
|
||||
|
||||
case SIDE_BACK:
|
||||
case eSideBack:
|
||||
if ( back->numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
back->v[ back->numVerts++ ] = *a;
|
||||
break;
|
||||
|
||||
case SIDE_ON:
|
||||
case eSideOn:
|
||||
if ( front->numVerts >= MAX_TW_VERTS || back->numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
@@ -446,7 +443,7 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front,
|
||||
}
|
||||
|
||||
/* check next point to see if we need to split the edge */
|
||||
if ( sides[ j ] == SIDE_ON || sides[ j ] == sides[ i ] ) {
|
||||
if ( sides[ j ] == eSideOn || sides[ j ] == sides[ i ] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -460,19 +457,18 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front,
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
/* minimize fp precision errors */
|
||||
if ( plane[ k ] == 1.0f ) {
|
||||
mid.xyz[ k ] = plane[ 3 ];
|
||||
if ( plane.normal()[ k ] == 1.0f ) {
|
||||
mid.xyz[ k ] = plane.dist();
|
||||
}
|
||||
else if ( plane[ k ] == -1.0f ) {
|
||||
mid.xyz[ k ] = -plane[ 3 ];
|
||||
else if ( plane.normal()[ k ] == -1.0f ) {
|
||||
mid.xyz[ k ] = -plane.dist();
|
||||
}
|
||||
else{
|
||||
mid.xyz[ k ] = a->xyz[ k ] + frac * ( b->xyz[ k ] - a->xyz[ k ] );
|
||||
}
|
||||
}
|
||||
/* set texture coordinates */
|
||||
mid.st[ 0 ] = a->st[ 0 ] + frac * ( b->st[ 0 ] - a->st[ 0 ] );
|
||||
mid.st[ 1 ] = a->st[ 1 ] + frac * ( b->st[ 1 ] - a->st[ 1 ] );
|
||||
mid.st = a->st + ( b->st - a->st ) * frac;
|
||||
|
||||
/* copy midpoint to front and back polygons */
|
||||
front->v[ front->numVerts++ ] = mid;
|
||||
@@ -490,7 +486,7 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front,
|
||||
|
||||
static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
int num;
|
||||
vec4_t plane1, plane2, reverse;
|
||||
Plane3f plane1, plane2, reverse;
|
||||
traceNode_t *node;
|
||||
traceWinding_t front, back;
|
||||
|
||||
@@ -518,23 +514,22 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
}
|
||||
|
||||
/* get node plane */
|
||||
Vector4Copy( node->plane, plane1 );
|
||||
plane1 = node->plane;
|
||||
|
||||
/* get winding plane */
|
||||
Vector4Copy( tw->plane, plane2 );
|
||||
plane2 = tw->plane;
|
||||
|
||||
/* invert surface plane */
|
||||
VectorSubtract( vec3_origin, plane2, reverse );
|
||||
reverse[ 3 ] = -plane2[ 3 ];
|
||||
reverse = plane3_flipped( plane2 );
|
||||
|
||||
/* front only */
|
||||
if ( DotProduct( plane1, plane2 ) > 0.999f && fabs( plane1[ 3 ] - plane2[ 3 ] ) < 0.001f ) {
|
||||
if ( vector3_dot( plane1.normal(), plane2.normal() ) > 0.999f && fabs( plane1.dist() - plane2.dist() ) < 0.001f ) {
|
||||
FilterTraceWindingIntoNodes_r( tw, node->children[ 0 ] );
|
||||
return;
|
||||
}
|
||||
|
||||
/* back only */
|
||||
if ( DotProduct( plane1, reverse ) > 0.999f && fabs( plane1[ 3 ] - reverse[ 3 ] ) < 0.001f ) {
|
||||
if ( vector3_dot( plane1.normal(), reverse.normal() ) > 0.999f && fabs( plane1.dist() - reverse.dist() ) < 0.001f ) {
|
||||
FilterTraceWindingIntoNodes_r( tw, node->children[ 1 ] );
|
||||
return;
|
||||
}
|
||||
@@ -568,9 +563,7 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
|
||||
static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
int i, j, count, num, frontNum, backNum, type;
|
||||
vec3_t size;
|
||||
float dist;
|
||||
double average[ 3 ];
|
||||
traceNode_t *node, *frontNode, *backNode;
|
||||
traceWinding_t *tw, front, back;
|
||||
|
||||
@@ -602,8 +595,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
}
|
||||
|
||||
/* bound the node */
|
||||
ClearBounds( node->mins, node->maxs );
|
||||
VectorClear( average );
|
||||
node->minmax.clear();
|
||||
DoubleVector3 average( 0, 0, 0 );
|
||||
count = 0;
|
||||
for ( i = 0; i < node->numItems; i++ )
|
||||
{
|
||||
@@ -613,10 +606,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
/* walk its verts */
|
||||
for ( j = 0; j < tw->numVerts; j++ )
|
||||
{
|
||||
AddPointToBounds( tw->v[ j ].xyz, node->mins, node->maxs );
|
||||
average[ 0 ] += tw->v[ j ].xyz[ 0 ];
|
||||
average[ 1 ] += tw->v[ j ].xyz[ 1 ];
|
||||
average[ 2 ] += tw->v[ j ].xyz[ 2 ];
|
||||
node->minmax.extend( tw->v[ j ].xyz );
|
||||
average += tw->v[ j ].xyz;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -630,15 +621,15 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
}
|
||||
|
||||
/* the largest dimension of the bounding box will be the split axis */
|
||||
VectorSubtract( node->maxs, node->mins, size );
|
||||
const Vector3 size = node->minmax.maxs - node->minmax.mins;
|
||||
if ( size[ 0 ] >= size[ 1 ] && size[ 0 ] >= size[ 2 ] ) {
|
||||
type = PLANE_X;
|
||||
type = ePlaneX;
|
||||
}
|
||||
else if ( size[ 1 ] >= size[ 0 ] && size[ 1 ] >= size[ 2 ] ) {
|
||||
type = PLANE_Y;
|
||||
type = ePlaneY;
|
||||
}
|
||||
else{
|
||||
type = PLANE_Z;
|
||||
type = ePlaneZ;
|
||||
}
|
||||
|
||||
/* don't split small nodes */
|
||||
@@ -657,8 +648,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
dist = floor( average[ type ] / count );
|
||||
|
||||
/* dummy check it */
|
||||
if ( dist <= node->mins[ type ] || dist >= node->maxs[ type ] ) {
|
||||
dist = floor( 0.5f * ( node->mins[ type ] + node->maxs[ type ] ) );
|
||||
if ( dist <= node->minmax.mins[ type ] || dist >= node->minmax.maxs[ type ] ) {
|
||||
dist = floor( 0.5f * ( node->minmax.mins[ type ] + node->minmax.maxs[ type ] ) );
|
||||
}
|
||||
|
||||
/* allocate child nodes */
|
||||
@@ -672,8 +663,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
|
||||
/* attach children */
|
||||
node->type = type;
|
||||
node->plane[ type ] = 1.0f;
|
||||
node->plane[ 3 ] = dist;
|
||||
node->plane.normal()[ type ] = 1.0f;
|
||||
node->plane.dist() = dist;
|
||||
node->children[ 0 ] = frontNum;
|
||||
node->children[ 1 ] = backNum;
|
||||
|
||||
@@ -802,8 +793,8 @@ static int TriangulateTraceNode_r( int nodeNum ){
|
||||
tt.v[ 2 ] = tw->v[ j + 1 ];
|
||||
|
||||
/* find vectors for two edges sharing the first vert */
|
||||
VectorSubtract( tt.v[ 1 ].xyz, tt.v[ 0 ].xyz, tt.edge1 );
|
||||
VectorSubtract( tt.v[ 2 ].xyz, tt.v[ 0 ].xyz, tt.edge2 );
|
||||
tt.edge1 = tt.v[ 1 ].xyz - tt.v[ 0 ].xyz;
|
||||
tt.edge2 = tt.v[ 2 ].xyz - tt.v[ 0 ].xyz;
|
||||
|
||||
/* add it to the node */
|
||||
num = AddTraceTriangle( &tt );
|
||||
@@ -831,7 +822,7 @@ static int TriangulateTraceNode_r( int nodeNum ){
|
||||
filters a bsp model's surfaces into the raytracing tree
|
||||
*/
|
||||
|
||||
static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){
|
||||
static void PopulateWithBSPModel( bspModel_t *model, const Matrix4& transform ){
|
||||
int i, j, x, y, pw[ 5 ], r, nodeNum;
|
||||
bspDrawSurface_t *ds;
|
||||
surfaceInfo_t *info;
|
||||
@@ -843,7 +834,7 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( model == NULL || transform == NULL ) {
|
||||
if ( model == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -943,27 +934,27 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){
|
||||
r = ( x + y ) & 1;
|
||||
|
||||
/* make first triangle */
|
||||
VectorCopy( verts[ pw[ r + 0 ] ].xyz, tw.v[ 0 ].xyz );
|
||||
Vector2Copy( verts[ pw[ r + 0 ] ].st, tw.v[ 0 ].st );
|
||||
VectorCopy( verts[ pw[ r + 1 ] ].xyz, tw.v[ 1 ].xyz );
|
||||
Vector2Copy( verts[ pw[ r + 1 ] ].st, tw.v[ 1 ].st );
|
||||
VectorCopy( verts[ pw[ r + 2 ] ].xyz, tw.v[ 2 ].xyz );
|
||||
Vector2Copy( verts[ pw[ r + 2 ] ].st, tw.v[ 2 ].st );
|
||||
m4x4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
m4x4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
m4x4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
tw.v[ 0 ].xyz = verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = verts[ pw[ r + 1 ] ].xyz;
|
||||
tw.v[ 1 ].st = verts[ pw[ r + 1 ] ].st;
|
||||
tw.v[ 2 ].xyz = verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 2 ].st = verts[ pw[ r + 2 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
|
||||
/* make second triangle */
|
||||
VectorCopy( verts[ pw[ r + 0 ] ].xyz, tw.v[ 0 ].xyz );
|
||||
Vector2Copy( verts[ pw[ r + 0 ] ].st, tw.v[ 0 ].st );
|
||||
VectorCopy( verts[ pw[ r + 2 ] ].xyz, tw.v[ 1 ].xyz );
|
||||
Vector2Copy( verts[ pw[ r + 2 ] ].st, tw.v[ 1 ].st );
|
||||
VectorCopy( verts[ pw[ r + 3 ] ].xyz, tw.v[ 2 ].xyz );
|
||||
Vector2Copy( verts[ pw[ r + 3 ] ].st, tw.v[ 2 ].st );
|
||||
m4x4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
m4x4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
m4x4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
tw.v[ 0 ].xyz = verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 1 ].st = verts[ pw[ r + 2 ] ].st;
|
||||
tw.v[ 2 ].xyz = verts[ pw[ r + 3 ] ].xyz;
|
||||
tw.v[ 2 ].st = verts[ pw[ r + 3 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
}
|
||||
}
|
||||
@@ -982,15 +973,15 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){
|
||||
/* walk the triangle list */
|
||||
for ( j = 0; j < ds->numIndexes; j += 3 )
|
||||
{
|
||||
VectorCopy( verts[ indexes[ j ] ].xyz, tw.v[ 0 ].xyz );
|
||||
Vector2Copy( verts[ indexes[ j ] ].st, tw.v[ 0 ].st );
|
||||
VectorCopy( verts[ indexes[ j + 1 ] ].xyz, tw.v[ 1 ].xyz );
|
||||
Vector2Copy( verts[ indexes[ j + 1 ] ].st, tw.v[ 1 ].st );
|
||||
VectorCopy( verts[ indexes[ j + 2 ] ].xyz, tw.v[ 2 ].xyz );
|
||||
Vector2Copy( verts[ indexes[ j + 2 ] ].st, tw.v[ 2 ].st );
|
||||
m4x4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
m4x4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
m4x4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
tw.v[ 0 ].xyz = verts[ indexes[ j ] ].xyz;
|
||||
tw.v[ 0 ].st = verts[ indexes[ j ] ].st;
|
||||
tw.v[ 1 ].xyz = verts[ indexes[ j + 1 ] ].xyz;
|
||||
tw.v[ 1 ].st = verts[ indexes[ j + 1 ] ].st;
|
||||
tw.v[ 2 ].xyz = verts[ indexes[ j + 2 ] ].xyz;
|
||||
tw.v[ 2 ].st = verts[ indexes[ j + 2 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
}
|
||||
break;
|
||||
@@ -1009,18 +1000,17 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){
|
||||
filters a picomodel's surfaces into the raytracing tree
|
||||
*/
|
||||
|
||||
static void PopulateWithPicoModel( int castShadows, picoModel_t *model, m4x4_t transform ){
|
||||
static void PopulateWithPicoModel( int castShadows, picoModel_t *model, const Matrix4& transform ){
|
||||
int i, j, k, numSurfaces, numIndexes;
|
||||
picoSurface_t *surface;
|
||||
picoShader_t *shader;
|
||||
picoVec_t *xyz, *st;
|
||||
picoIndex_t *indexes;
|
||||
traceInfo_t ti;
|
||||
traceWinding_t tw;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( model == NULL || transform == NULL ) {
|
||||
if ( model == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1080,11 +1070,9 @@ static void PopulateWithPicoModel( int castShadows, picoModel_t *model, m4x4_t t
|
||||
{
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
xyz = PicoGetSurfaceXYZ( surface, indexes[ k ] );
|
||||
st = PicoGetSurfaceST( surface, 0, indexes[ k ] );
|
||||
VectorCopy( xyz, tw.v[ k ].xyz );
|
||||
Vector2Copy( st, tw.v[ k ].st );
|
||||
m4x4_transform_point( transform, tw.v[ k ].xyz );
|
||||
tw.v[ k ].xyz = vector3_from_array( PicoGetSurfaceXYZ( surface, indexes[ k ] ) );
|
||||
tw.v[ k ].st = vector2_from_array( PicoGetSurfaceST( surface, 0, indexes[ k ] ) );
|
||||
matrix4_transform_point( transform, tw.v[ k ].xyz );
|
||||
}
|
||||
FilterTraceWindingIntoNodes_r( &tw, headNodeNum );
|
||||
}
|
||||
@@ -1105,8 +1093,7 @@ static void PopulateTraceNodes( void ){
|
||||
|
||||
|
||||
/* add worldspawn triangles */
|
||||
m4x4_t transform;
|
||||
m4x4_identity( transform );
|
||||
Matrix4 transform( g_matrix4_identity );
|
||||
PopulateWithBSPModel( &bspModels[ 0 ], transform );
|
||||
|
||||
/* walk each entity list */
|
||||
@@ -1125,24 +1112,24 @@ static void PopulateTraceNodes( void ){
|
||||
}
|
||||
|
||||
/* get entity origin */
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
e->vectorForKey( "origin", origin );
|
||||
|
||||
/* get scale */
|
||||
vec3_t scale = { 1.f, 1.f, 1.f };
|
||||
Vector3 scale = { 1.f, 1.f, 1.f };
|
||||
if( !e->read_keyvalue( scale, "modelscale_vec" ) )
|
||||
if( e->read_keyvalue( scale[0], "modelscale" ) )
|
||||
scale[1] = scale[2] = scale[0];
|
||||
|
||||
/* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */
|
||||
vec3_t angles = { 0.f, 0.f, 0.f };
|
||||
Vector3 angles = { 0.f, 0.f, 0.f };
|
||||
if ( !e->read_keyvalue( value, "angles" ) ||
|
||||
3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) )
|
||||
e->read_keyvalue( angles[ 2 ], "angle" );
|
||||
|
||||
/* set transform matrix (thanks spog) */
|
||||
m4x4_identity( transform );
|
||||
m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin );
|
||||
transform = g_matrix4_identity;
|
||||
matrix4_transform_by_euler_xyz_degrees( transform, origin, angles, scale );
|
||||
|
||||
/* hack: Stable-1_2 and trunk have differing row/column major matrix order
|
||||
this transpose is necessary with Stable-1_2
|
||||
@@ -1320,7 +1307,7 @@ void SetupTraceNodes( void ){
|
||||
|
||||
bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){
|
||||
int i;
|
||||
float tvec[ 3 ], pvec[ 3 ], qvec[ 3 ];
|
||||
Vector3 tvec, pvec, qvec;
|
||||
float det, invDet, depth;
|
||||
float u, v, w, s, t;
|
||||
int is, it;
|
||||
@@ -1366,10 +1353,10 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){
|
||||
}
|
||||
|
||||
/* begin calculating determinant - also used to calculate u parameter */
|
||||
CrossProduct( trace->direction, tt->edge2, pvec );
|
||||
pvec = vector3_cross( trace->direction, tt->edge2 );
|
||||
|
||||
/* if determinant is near zero, trace lies in plane of triangle */
|
||||
det = DotProduct( tt->edge1, pvec );
|
||||
det = vector3_dot( tt->edge1, pvec );
|
||||
|
||||
/* the non-culling branch */
|
||||
if ( fabs( det ) < COPLANAR_EPSILON ) {
|
||||
@@ -1378,25 +1365,25 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){
|
||||
invDet = 1.0f / det;
|
||||
|
||||
/* calculate distance from first vertex to ray origin */
|
||||
VectorSubtract( trace->origin, tt->v[ 0 ].xyz, tvec );
|
||||
tvec = trace->origin - tt->v[ 0 ].xyz;
|
||||
|
||||
/* calculate u parameter and test bounds */
|
||||
u = DotProduct( tvec, pvec ) * invDet;
|
||||
u = vector3_dot( tvec, pvec ) * invDet;
|
||||
if ( u < -BARY_EPSILON || u > ( 1.0f + BARY_EPSILON ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* prepare to test v parameter */
|
||||
CrossProduct( tvec, tt->edge1, qvec );
|
||||
qvec = vector3_cross( tvec, tt->edge1 );
|
||||
|
||||
/* calculate v parameter and test bounds */
|
||||
v = DotProduct( trace->direction, qvec ) * invDet;
|
||||
v = vector3_dot( trace->direction, qvec ) * invDet;
|
||||
if ( v < -BARY_EPSILON || ( u + v ) > ( 1.0f + BARY_EPSILON ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate t (depth) */
|
||||
depth = DotProduct( tt->edge2, qvec ) * invDet;
|
||||
depth = vector3_dot( tt->edge2, qvec ) * invDet;
|
||||
if ( depth <= trace->inhibitRadius || depth >= trace->distance ) {
|
||||
return false;
|
||||
}
|
||||
@@ -1423,8 +1410,8 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){
|
||||
/* most surfaces are completely opaque */
|
||||
if ( !( si->compileFlags & ( C_ALPHASHADOW | C_LIGHTFILTER ) ) ||
|
||||
si->lightImage == NULL || si->lightImage->pixels == NULL ) {
|
||||
VectorMA( trace->origin, depth, trace->direction, trace->hit );
|
||||
VectorClear( trace->color );
|
||||
trace->hit = trace->origin + trace->direction * depth;
|
||||
trace->color.set( 0 );
|
||||
trace->opaque = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1483,8 +1470,8 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){
|
||||
|
||||
/* check filter for opaque */
|
||||
if ( trace->color[ 0 ] <= 0.001f && trace->color[ 1 ] <= 0.001f && trace->color[ 2 ] <= 0.001f ) {
|
||||
VectorClear( trace->color );
|
||||
VectorMA( trace->origin, depth, trace->direction, trace->hit );
|
||||
trace->color.set( 0 );
|
||||
trace->hit = trace->origin + trace->direction * depth;
|
||||
trace->opaque = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1517,8 +1504,8 @@ bool TraceWinding( traceWinding_t *tw, trace_t *trace ){
|
||||
tt.v[ 2 ] = tw->v[ i + 1 ];
|
||||
|
||||
/* find vectors for two edges sharing the first vert */
|
||||
VectorSubtract( tt.v[ 1 ].xyz, tt.v[ 0 ].xyz, tt.edge1 );
|
||||
VectorSubtract( tt.v[ 2 ].xyz, tt.v[ 0 ].xyz, tt.edge2 );
|
||||
tt.edge1 = tt.v[ 1 ].xyz - tt.v[ 0 ].xyz;
|
||||
tt.edge2 = tt.v[ 2 ].xyz - tt.v[ 0 ].xyz;
|
||||
|
||||
/* trace it */
|
||||
if ( TraceTriangle( &traceInfos[ tt.infoNum ], &tt, trace ) ) {
|
||||
@@ -1543,26 +1530,25 @@ bool TraceWinding( traceWinding_t *tw, trace_t *trace ){
|
||||
#define TRACELINE_R_HALF_ITERATIVE 1
|
||||
|
||||
#if TRACELINE_R_HALF_ITERATIVE
|
||||
static bool TraceLine_r( int nodeNum, const vec3_t start, const vec3_t end, trace_t *trace )
|
||||
static bool TraceLine_r( int nodeNum, const Vector3& start, const Vector3& end, trace_t *trace )
|
||||
#else
|
||||
static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, trace_t *trace )
|
||||
static bool TraceLine_r( int nodeNum, const Vector3& origin, const Vector3& end, trace_t *trace )
|
||||
#endif
|
||||
{
|
||||
traceNode_t *node;
|
||||
int side;
|
||||
float front, back, frac;
|
||||
vec3_t mid;
|
||||
Vector3 mid;
|
||||
|
||||
#if TRACELINE_R_HALF_ITERATIVE
|
||||
vec3_t origin;
|
||||
VectorCopy( start, origin );
|
||||
Vector3 origin( start );
|
||||
|
||||
while ( 1 )
|
||||
#endif
|
||||
{
|
||||
/* bogus node number means solid, end tracing unless testing all */
|
||||
if ( nodeNum < 0 ) {
|
||||
VectorCopy( origin, trace->hit );
|
||||
trace->hit = origin;
|
||||
trace->passSolid = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1572,7 +1558,7 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra
|
||||
|
||||
/* solid? */
|
||||
if ( node->type == TRACE_LEAF_SOLID ) {
|
||||
VectorCopy( origin, trace->hit );
|
||||
trace->hit = origin;
|
||||
trace->passSolid = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1594,24 +1580,24 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra
|
||||
/* classify beginning and end points */
|
||||
switch ( node->type )
|
||||
{
|
||||
case PLANE_X:
|
||||
front = origin[ 0 ] - node->plane[ 3 ];
|
||||
back = end[ 0 ] - node->plane[ 3 ];
|
||||
case ePlaneX:
|
||||
front = origin[ 0 ] - node->plane.dist();
|
||||
back = end[ 0 ] - node->plane.dist();
|
||||
break;
|
||||
|
||||
case PLANE_Y:
|
||||
front = origin[ 1 ] - node->plane[ 3 ];
|
||||
back = end[ 1 ] - node->plane[ 3 ];
|
||||
case ePlaneY:
|
||||
front = origin[ 1 ] - node->plane.dist();
|
||||
back = end[ 1 ] - node->plane.dist();
|
||||
break;
|
||||
|
||||
case PLANE_Z:
|
||||
front = origin[ 2 ] - node->plane[ 3 ];
|
||||
back = end[ 2 ] - node->plane[ 3 ];
|
||||
case ePlaneZ:
|
||||
front = origin[ 2 ] - node->plane.dist();
|
||||
back = end[ 2 ] - node->plane.dist();
|
||||
break;
|
||||
|
||||
default:
|
||||
front = DotProduct( origin, node->plane ) - node->plane[ 3 ];
|
||||
back = DotProduct( end, node->plane ) - node->plane[ 3 ];
|
||||
front = plane3_distance_to_point( node->plane, origin );
|
||||
back = plane3_distance_to_point( node->plane, end );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1640,14 +1626,12 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra
|
||||
|
||||
/* calculate intercept point */
|
||||
frac = front / ( front - back );
|
||||
mid[ 0 ] = origin[ 0 ] + ( end[ 0 ] - origin[ 0 ] ) * frac;
|
||||
mid[ 1 ] = origin[ 1 ] + ( end[ 1 ] - origin[ 1 ] ) * frac;
|
||||
mid[ 2 ] = origin[ 2 ] + ( end[ 2 ] - origin[ 2 ] ) * frac;
|
||||
mid = origin + ( end - origin ) * frac;
|
||||
|
||||
/* fixme: check inhibit radius, then solid nodes and ignore */
|
||||
|
||||
/* set trace hit here */
|
||||
//% VectorCopy( mid, trace->hit );
|
||||
//% trace->hit = mid;
|
||||
|
||||
/* trace first side */
|
||||
if ( TraceLine_r( node->children[ side ], origin, mid, trace ) ) {
|
||||
@@ -1657,7 +1641,7 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra
|
||||
/* trace other side */
|
||||
#if TRACELINE_R_HALF_ITERATIVE
|
||||
nodeNum = node->children[ !side ];
|
||||
VectorCopy( mid, origin );
|
||||
origin = mid;
|
||||
#else
|
||||
return TraceLine_r( node->children[ !side ], mid, end, trace );
|
||||
#endif
|
||||
@@ -1737,8 +1721,9 @@ void TraceLine( trace_t *trace ){
|
||||
*/
|
||||
|
||||
float SetupTrace( trace_t *trace ){
|
||||
VectorSubtract( trace->end, trace->origin, trace->displacement );
|
||||
trace->distance = VectorFastNormalize( trace->displacement, trace->direction );
|
||||
VectorCopy( trace->origin, trace->hit );
|
||||
trace->displacement = trace->end - trace->origin;
|
||||
trace->direction = trace->displacement;
|
||||
trace->distance = VectorFastNormalize( trace->direction );
|
||||
trace->hit = trace->origin;
|
||||
return trace->distance;
|
||||
}
|
||||
|
||||
+539
-808
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+130
-194
@@ -54,23 +54,20 @@ int c_structural;
|
||||
ydnar: replaced with variable epsilon for djbob
|
||||
*/
|
||||
|
||||
bool PlaneEqual( plane_t *p, vec3_t normal, vec_t dist ){
|
||||
float ne, de;
|
||||
|
||||
|
||||
bool PlaneEqual( const plane_t *p, const Plane3f& plane ){
|
||||
/* get local copies */
|
||||
ne = normalEpsilon;
|
||||
de = distanceEpsilon;
|
||||
const float ne = normalEpsilon;
|
||||
const float de = distanceEpsilon;
|
||||
|
||||
/* compare */
|
||||
// We check equality of each component since we're using '<', not '<='
|
||||
// (the epsilons may be zero). We want to use '<' instead of '<=' to be
|
||||
// consistent with the true meaning of "epsilon", and also because other
|
||||
// parts of the code uses this inequality.
|
||||
if ( ( p->dist == dist || fabs( p->dist - dist ) < de ) &&
|
||||
( p->normal[0] == normal[0] || fabs( p->normal[0] - normal[0] ) < ne ) &&
|
||||
( p->normal[1] == normal[1] || fabs( p->normal[1] - normal[1] ) < ne ) &&
|
||||
( p->normal[2] == normal[2] || fabs( p->normal[2] - normal[2] ) < ne ) ) {
|
||||
if ( ( p->dist() == plane.dist() || fabs( p->dist() - plane.dist() ) < de ) &&
|
||||
( p->normal()[0] == plane.normal()[0] || fabs( p->normal()[0] - plane.normal()[0] ) < ne ) &&
|
||||
( p->normal()[1] == plane.normal()[1] || fabs( p->normal()[1] - plane.normal()[1] ) < ne ) &&
|
||||
( p->normal()[2] == plane.normal()[2] || fabs( p->normal()[2] - plane.normal()[2] ) < ne ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,7 +85,7 @@ void AddPlaneToHash( plane_t *p ){
|
||||
int hash;
|
||||
|
||||
|
||||
hash = ( PLANE_HASHES - 1 ) & (int) fabs( p->dist );
|
||||
hash = ( PLANE_HASHES - 1 ) & (int) fabs( p->dist() );
|
||||
|
||||
p->hash_chain = planehash[hash];
|
||||
planehash[hash] = p - mapplanes + 1;
|
||||
@@ -99,10 +96,9 @@ void AddPlaneToHash( plane_t *p ){
|
||||
CreateNewFloatPlane
|
||||
================
|
||||
*/
|
||||
int CreateNewFloatPlane( vec3_t normal, vec_t dist ){
|
||||
plane_t *p, temp;
|
||||
int CreateNewFloatPlane( const Plane3f& plane ){
|
||||
|
||||
if ( VectorLength( normal ) < 0.5 ) {
|
||||
if ( vector3_length( plane.normal() ) < 0.5 ) {
|
||||
Sys_Printf( "FloatPlane: bad normal\n" );
|
||||
return -1;
|
||||
}
|
||||
@@ -110,23 +106,18 @@ int CreateNewFloatPlane( vec3_t normal, vec_t dist ){
|
||||
// create a new plane
|
||||
AUTOEXPAND_BY_REALLOC( mapplanes, nummapplanes + 1, allocatedmapplanes, 1024 );
|
||||
|
||||
p = &mapplanes[nummapplanes];
|
||||
VectorCopy( normal, p->normal );
|
||||
p->dist = dist;
|
||||
p->type = ( p + 1 )->type = PlaneTypeForNormal( p->normal );
|
||||
|
||||
VectorSubtract( vec3_origin, normal, ( p + 1 )->normal );
|
||||
( p + 1 )->dist = -dist;
|
||||
plane_t *p = &mapplanes[nummapplanes];
|
||||
p->plane = plane;
|
||||
( p + 1 )->plane = plane3_flipped( plane );
|
||||
p->type = ( p + 1 )->type = PlaneTypeForNormal( p->normal() );
|
||||
|
||||
nummapplanes += 2;
|
||||
|
||||
// always put axial planes facing positive first
|
||||
if ( p->type < 3 ) {
|
||||
if ( p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0 ) {
|
||||
if ( p->type < ePlaneNonAxial ) {
|
||||
if ( p->normal()[0] < 0 || p->normal()[1] < 0 || p->normal()[2] < 0 ) {
|
||||
// flip order
|
||||
temp = *p;
|
||||
*p = *( p + 1 );
|
||||
*( p + 1 ) = temp;
|
||||
std::swap( *p, *( p + 1 ) );
|
||||
|
||||
AddPlaneToHash( p );
|
||||
AddPlaneToHash( p + 1 );
|
||||
@@ -147,7 +138,7 @@ int CreateNewFloatPlane( vec3_t normal, vec_t dist ){
|
||||
Returns true if and only if the normal was adjusted.
|
||||
*/
|
||||
|
||||
bool SnapNormal( vec3_t normal ){
|
||||
bool SnapNormal( Vector3& normal ){
|
||||
#if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX
|
||||
int i;
|
||||
bool adjusted = false;
|
||||
@@ -163,15 +154,15 @@ bool SnapNormal( vec3_t normal ){
|
||||
//they cause precision errors
|
||||
|
||||
|
||||
if ( ( normal[0] != 0.0 || normal[1] != 0.0 ) && fabs(normal[0]) < 0.00025 && fabs(normal[1]) < 0.00025){
|
||||
if ( ( normal[0] != 0.0 || normal[1] != 0.0 ) && fabs( normal[0] ) < 0.00025 && fabs( normal[1] ) < 0.00025){
|
||||
normal[0] = normal[1] = 0.0;
|
||||
adjusted = true;
|
||||
}
|
||||
else if ( ( normal[0] != 0.0 || normal[2] != 0.0 ) && fabs(normal[0]) < 0.00025 && fabs(normal[2]) < 0.00025){
|
||||
else if ( ( normal[0] != 0.0 || normal[2] != 0.0 ) && fabs( normal[0] ) < 0.00025 && fabs( normal[2] ) < 0.00025){
|
||||
normal[0] = normal[2] = 0.0;
|
||||
adjusted = true;
|
||||
}
|
||||
else if ( ( normal[2] != 0.0 || normal[1] != 0.0 ) && fabs(normal[2]) < 0.00025 && fabs(normal[1]) < 0.00025){
|
||||
else if ( ( normal[2] != 0.0 || normal[1] != 0.0 ) && fabs( normal[2] ) < 0.00025 && fabs( normal[1] ) < 0.00025){
|
||||
normal[2] = normal[1] = 0.0;
|
||||
adjusted = true;
|
||||
}
|
||||
@@ -206,7 +197,7 @@ bool SnapNormal( vec3_t normal ){
|
||||
}
|
||||
|
||||
if ( adjusted ) {
|
||||
VectorNormalize( normal, normal );
|
||||
VectorNormalize( normal );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -249,12 +240,12 @@ bool SnapNormal( vec3_t normal ){
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( fabs( normal[ i ] - 1 ) < normalEpsilon ) {
|
||||
VectorClear( normal );
|
||||
normal.set( 0 );
|
||||
normal[ i ] = 1;
|
||||
return true;
|
||||
}
|
||||
if ( fabs( normal[ i ] - -1 ) < normalEpsilon ) {
|
||||
VectorClear( normal );
|
||||
normal.set( 0 );
|
||||
normal[ i ] = -1;
|
||||
return true;
|
||||
}
|
||||
@@ -270,7 +261,7 @@ bool SnapNormal( vec3_t normal ){
|
||||
snaps a plane to normal/distance epsilons
|
||||
*/
|
||||
|
||||
void SnapPlane( vec3_t normal, vec_t *dist ){
|
||||
void SnapPlane( Plane3f& plane ){
|
||||
// SnapPlane disabled by LordHavoc because it often messes up collision
|
||||
// brushes made from triangles of embedded models, and it has little effect
|
||||
// on anything else (axial planes are usually derived from snapped points)
|
||||
@@ -278,7 +269,7 @@ void SnapPlane( vec3_t normal, vec_t *dist ){
|
||||
SnapPlane reenabled by namespace because of multiple reports of
|
||||
q3map2-crashes which were triggered by this patch.
|
||||
*/
|
||||
SnapNormal( normal );
|
||||
SnapNormal( plane.normal() );
|
||||
|
||||
// TODO: Rambetter has some serious comments here as well. First off,
|
||||
// in the case where a normal is non-axial, there is nothing special
|
||||
@@ -301,8 +292,8 @@ void SnapPlane( vec3_t normal, vec_t *dist ){
|
||||
// solve so that we can better engineer it (I'm not saying that SnapPlane()
|
||||
// should be removed altogether). Fix all this snapping code at some point!
|
||||
|
||||
if ( fabs( *dist - Q_rint( *dist ) ) < distanceEpsilon ) {
|
||||
*dist = Q_rint( *dist );
|
||||
if ( fabs( plane.dist() - std::rint( plane.dist() ) ) < distanceEpsilon ) {
|
||||
plane.dist() = std::rint( plane.dist() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,30 +301,26 @@ void SnapPlane( vec3_t normal, vec_t *dist ){
|
||||
SnapPlaneImproved()
|
||||
snaps a plane to normal/distance epsilons, improved code
|
||||
*/
|
||||
void SnapPlaneImproved( vec3_t normal, vec_t *dist, int numPoints, const vec3_t *points ){
|
||||
int i;
|
||||
vec3_t center;
|
||||
vec_t distNearestInt;
|
||||
|
||||
if ( SnapNormal( normal ) ) {
|
||||
void SnapPlaneImproved( Plane3f& plane, int numPoints, const Vector3 *points ){
|
||||
if ( SnapNormal( plane.normal() ) ) {
|
||||
if ( numPoints > 0 ) {
|
||||
// Adjust the dist so that the provided points don't drift away.
|
||||
VectorClear( center );
|
||||
for ( i = 0; i < numPoints; i++ )
|
||||
Vector3 center( 0, 0, 0 );
|
||||
for ( int i = 0; i < numPoints; i++ )
|
||||
{
|
||||
VectorAdd( center, points[i], center );
|
||||
center += points[i];
|
||||
}
|
||||
for ( i = 0; i < 3; i++ ) { center[i] = center[i] / numPoints; }
|
||||
*dist = DotProduct( normal, center );
|
||||
center /= numPoints;
|
||||
plane.dist() = vector3_dot( plane.normal(), center );
|
||||
}
|
||||
}
|
||||
|
||||
if ( VectorIsOnAxis( normal ) ) {
|
||||
if ( VectorIsOnAxis( plane.normal() ) ) {
|
||||
// Only snap distance if the normal is an axis. Otherwise there
|
||||
// is nothing "natural" about snapping the distance to an integer.
|
||||
distNearestInt = Q_rint( *dist );
|
||||
if ( -distanceEpsilon < *dist - distNearestInt && *dist - distNearestInt < distanceEpsilon ) {
|
||||
*dist = distNearestInt;
|
||||
const float distNearestInt = std::rint( plane.dist() );
|
||||
if ( -distanceEpsilon < plane.dist() - distNearestInt && plane.dist() - distNearestInt < distanceEpsilon ) {
|
||||
plane.dist() = distNearestInt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,25 +333,22 @@ void SnapPlaneImproved( vec3_t normal, vec_t *dist, int numPoints, const vec3_t
|
||||
must be within an epsilon distance of the plane
|
||||
*/
|
||||
|
||||
int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) // NOTE: this has a side effect on the normal. Good or bad?
|
||||
int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points ) // NOTE: this has a side effect on the normal. Good or bad?
|
||||
|
||||
#ifdef USE_HASHING
|
||||
|
||||
{
|
||||
int i, j, hash, h;
|
||||
int pidx;
|
||||
plane_t *p;
|
||||
vec_t d;
|
||||
vec3_t normal;
|
||||
Plane3f plane( inplane );
|
||||
|
||||
VectorCopy( innormal, normal );
|
||||
#if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
|
||||
SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points );
|
||||
SnapPlaneImproved( plane, numPoints, points );
|
||||
#else
|
||||
SnapPlane( normal, &dist );
|
||||
SnapPlane( plane );
|
||||
#endif
|
||||
/* hash the plane */
|
||||
hash = ( PLANE_HASHES - 1 ) & (int) fabs( dist );
|
||||
hash = ( PLANE_HASHES - 1 ) & (int) fabs( plane.dist() );
|
||||
|
||||
/* search the border bins as well */
|
||||
for ( i = -1; i <= 1; i++ )
|
||||
@@ -372,10 +356,10 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
|
||||
h = ( hash + i ) & ( PLANE_HASHES - 1 );
|
||||
for ( pidx = planehash[ h ] - 1; pidx != -1; pidx = mapplanes[pidx].hash_chain - 1 )
|
||||
{
|
||||
p = &mapplanes[pidx];
|
||||
plane_t *p = &mapplanes[pidx];
|
||||
|
||||
/* do standard plane compare */
|
||||
if ( !PlaneEqual( p, normal, dist ) ) {
|
||||
if ( !PlaneEqual( p, plane ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -390,8 +374,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
|
||||
// very small when world coordinates extend to 2^16. Making the
|
||||
// dot product here in 64 bit land will not really help the situation
|
||||
// because the error will already be carried in dist.
|
||||
d = DotProduct( points[ j ], p->normal ) - p->dist;
|
||||
d = fabs( d );
|
||||
const double d = fabs( plane3_distance_to_point( p->plane, points[ j ] ) );
|
||||
if ( d != 0.0 && d >= distanceEpsilon ) {
|
||||
break; // Point is too far from plane.
|
||||
}
|
||||
@@ -405,25 +388,24 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
|
||||
}
|
||||
|
||||
/* none found, so create a new one */
|
||||
return CreateNewFloatPlane( normal, dist );
|
||||
return CreateNewFloatPlane( plane );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
plane_t *p;
|
||||
vec3_t normal;
|
||||
Plane3f plane( innormal, dist );
|
||||
|
||||
VectorCopy( innormal, normal );
|
||||
#if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
|
||||
SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points );
|
||||
SnapPlaneImproved( plane, numPoints, points );
|
||||
#else
|
||||
SnapPlane( normal, &dist );
|
||||
SnapPlane( plane );
|
||||
#endif
|
||||
for ( i = 0, p = mapplanes; i < nummapplanes; i++, p++ )
|
||||
{
|
||||
if ( !PlaneEqual( p, normal, dist ) ) {
|
||||
if ( !PlaneEqual( p, plane ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -433,8 +415,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
|
||||
/* ydnar: test supplied points against this plane */
|
||||
for ( j = 0; j < numPoints; j++ )
|
||||
{
|
||||
d = DotProduct( points[ j ], p->normal ) - p->dist;
|
||||
if ( fabs( d ) > distanceEpsilon ) {
|
||||
if ( fabs( plane3_distance_to_point( p->plane, points[ j ] ) ) > distanceEpsilon ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -448,7 +429,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
|
||||
// is unmaintained because nobody sets USE_HASHING to off.
|
||||
}
|
||||
|
||||
return CreateNewFloatPlane( normal, dist );
|
||||
return CreateNewFloatPlane( plane );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -460,44 +441,18 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
|
||||
takes 3 points and finds the plane they lie in
|
||||
*/
|
||||
|
||||
int MapPlaneFromPoints( vec3_t *p ){
|
||||
int MapPlaneFromPoints( Vector3 p[3] ){
|
||||
#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
|
||||
vec3_accu_t paccu[3];
|
||||
vec3_accu_t t1, t2, normalAccu;
|
||||
vec3_t normal;
|
||||
vec_t dist;
|
||||
|
||||
VectorCopyRegularToAccu( p[0], paccu[0] );
|
||||
VectorCopyRegularToAccu( p[1], paccu[1] );
|
||||
VectorCopyRegularToAccu( p[2], paccu[2] );
|
||||
|
||||
VectorSubtractAccu( paccu[0], paccu[1], t1 );
|
||||
VectorSubtractAccu( paccu[2], paccu[1], t2 );
|
||||
CrossProductAccu( t1, t2, normalAccu );
|
||||
VectorNormalizeAccu( normalAccu, normalAccu );
|
||||
Plane3 plane;
|
||||
PlaneFromPoints( plane, DoubleVector3( p[0] ), DoubleVector3( p[1] ), DoubleVector3( p[2] ) );
|
||||
// TODO: A 32 bit float for the plane distance isn't enough resolution
|
||||
// if the plane is 2^16 units away from the origin (the "epsilon" approaches
|
||||
// 0.01 in that case).
|
||||
dist = (vec_t) DotProductAccu( paccu[0], normalAccu );
|
||||
VectorCopyAccuToRegular( normalAccu, normal );
|
||||
|
||||
return FindFloatPlane( normal, dist, 3, p );
|
||||
return FindFloatPlane( Plane3f( plane.normal(), plane.dist() ), 3, p );
|
||||
#else
|
||||
vec3_t t1, t2, normal;
|
||||
vec_t dist;
|
||||
|
||||
|
||||
/* calc plane normal */
|
||||
VectorSubtract( p[ 0 ], p[ 1 ], t1 );
|
||||
VectorSubtract( p[ 2 ], p[ 1 ], t2 );
|
||||
CrossProduct( t1, t2, normal );
|
||||
VectorNormalize( normal, normal );
|
||||
|
||||
/* calc plane distance */
|
||||
dist = DotProduct( p[ 0 ], normal );
|
||||
|
||||
/* store the plane */
|
||||
return FindFloatPlane( normal, dist, 3, p );
|
||||
Plane3f plane;
|
||||
PlaneFromPoints( plane, p );
|
||||
return FindFloatPlane( plane, 3, p );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -628,9 +583,8 @@ void AddBrushBevels( void ){
|
||||
side_t sidetemp;
|
||||
side_t *s, *s2;
|
||||
winding_t *w, *w2;
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
vec3_t vec, vec2;
|
||||
Plane3f plane;
|
||||
Vector3 vec, vec2;
|
||||
float d, minBack;
|
||||
int surfaceFlagsMask = game->brushBevelsSurfaceFlagsMask;
|
||||
|
||||
@@ -646,18 +600,18 @@ void AddBrushBevels( void ){
|
||||
/* ydnar: testing disabling of mre code */
|
||||
#if 0
|
||||
if ( dir > 0 ) {
|
||||
if ( mapplanes[s->planenum].normal[axis] >= 0.9999f ) {
|
||||
if ( mapplanes[s->planenum].normal()[axis] >= 0.9999f ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( mapplanes[s->planenum].normal[axis] <= -0.9999f ) {
|
||||
if ( mapplanes[s->planenum].normal()[axis] <= -0.9999f ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( ( dir > 0 && mapplanes[ s->planenum ].normal[ axis ] == 1.0f ) ||
|
||||
( dir < 0 && mapplanes[ s->planenum ].normal[ axis ] == -1.0f ) ) {
|
||||
if ( ( dir > 0 && mapplanes[ s->planenum ].normal()[ axis ] == 1.0f ) ||
|
||||
( dir < 0 && mapplanes[ s->planenum ].normal()[ axis ] == -1.0f ) ) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -670,30 +624,30 @@ void AddBrushBevels( void ){
|
||||
}
|
||||
memset( s, 0, sizeof( *s ) );
|
||||
buildBrush->numsides++;
|
||||
VectorClear( normal );
|
||||
normal[axis] = dir;
|
||||
plane.normal().set( 0 );
|
||||
plane.normal()[axis] = dir;
|
||||
|
||||
if ( dir == 1 ) {
|
||||
/* ydnar: adding bevel plane snapping for fewer bsp planes */
|
||||
if ( bevelSnap > 0 ) {
|
||||
dist = floor( buildBrush->maxs[ axis ] / bevelSnap ) * bevelSnap;
|
||||
plane.dist() = floor( buildBrush->minmax.maxs[ axis ] / bevelSnap ) * bevelSnap;
|
||||
}
|
||||
else{
|
||||
dist = buildBrush->maxs[ axis ];
|
||||
plane.dist() = buildBrush->minmax.maxs[ axis ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ydnar: adding bevel plane snapping for fewer bsp planes */
|
||||
if ( bevelSnap > 0 ) {
|
||||
dist = -ceil( buildBrush->mins[ axis ] / bevelSnap ) * bevelSnap;
|
||||
plane.dist() = -ceil( buildBrush->minmax.mins[ axis ] / bevelSnap ) * bevelSnap;
|
||||
}
|
||||
else{
|
||||
dist = -buildBrush->mins[ axis ];
|
||||
plane.dist() = -buildBrush->minmax.mins[ axis ];
|
||||
}
|
||||
}
|
||||
|
||||
s->planenum = FindFloatPlane( normal, dist, 0, NULL );
|
||||
s->planenum = FindFloatPlane( plane, 0, NULL );
|
||||
s->contentFlags = buildBrush->sides[ 0 ].contentFlags;
|
||||
/* handle bevel surfaceflags for topmost one only: assuming that only walkable ones are meaningful */
|
||||
if( axis == 2 && dir == 1 ){
|
||||
@@ -704,7 +658,7 @@ void AddBrushBevels( void ){
|
||||
continue;
|
||||
}
|
||||
for ( k = 0; k < w->numpoints; k++ ) {
|
||||
if ( fabs( dist - w->p[k][axis] ) < .1f ) {
|
||||
if ( fabs( plane.dist() - w->p[k][axis] ) < .1f ) {
|
||||
s->surfaceFlags |= ( s2->surfaceFlags & surfaceFlagsMask );
|
||||
break;
|
||||
}
|
||||
@@ -740,8 +694,8 @@ void AddBrushBevels( void ){
|
||||
}
|
||||
for ( j = 0; j < w->numpoints; j++ ) {
|
||||
k = ( j + 1 ) % w->numpoints;
|
||||
VectorSubtract( w->p[j], w->p[k], vec );
|
||||
if ( VectorNormalize( vec, vec ) < 0.5f ) {
|
||||
vec = w->p[j] - w->p[k];
|
||||
if ( VectorNormalize( vec ) < 0.5f ) {
|
||||
continue;
|
||||
}
|
||||
SnapNormal( vec );
|
||||
@@ -761,20 +715,20 @@ void AddBrushBevels( void ){
|
||||
for ( axis = 0; axis < 3; axis++ ) {
|
||||
for ( dir = -1; dir <= 1; dir += 2 ) {
|
||||
// construct a plane
|
||||
VectorClear( vec2 );
|
||||
vec2.set( 0 );
|
||||
vec2[axis] = dir;
|
||||
CrossProduct( vec, vec2, normal );
|
||||
if ( VectorNormalize( normal, normal ) < 0.5f ) {
|
||||
plane.normal() = vector3_cross( vec, vec2 );
|
||||
if ( VectorNormalize( plane.normal() ) < 0.5f ) {
|
||||
continue;
|
||||
}
|
||||
dist = DotProduct( w->p[j], normal );
|
||||
plane.dist() = vector3_dot( w->p[j], plane.normal() );
|
||||
|
||||
// if all the points on all the sides are
|
||||
// behind this plane, it is a proper edge bevel
|
||||
for ( k = 0; k < buildBrush->numsides; k++ ) {
|
||||
|
||||
// if this plane has allready been used, skip it
|
||||
if ( PlaneEqual( &mapplanes[buildBrush->sides[k].planenum], normal, dist ) ) {
|
||||
if ( PlaneEqual( &mapplanes[buildBrush->sides[k].planenum], plane ) ) {
|
||||
if( buildBrush->sides[k].bevel ){ /* handle bevel surfaceflags */
|
||||
buildBrush->sides[k].surfaceFlags |= ( s->surfaceFlags & surfaceFlagsMask );
|
||||
}
|
||||
@@ -787,7 +741,7 @@ void AddBrushBevels( void ){
|
||||
}
|
||||
minBack = 0.0f;
|
||||
for ( l = 0; l < w2->numpoints; l++ ) {
|
||||
d = DotProduct( w2->p[l], normal ) - dist;
|
||||
d = plane3_distance_to_point( plane, w2->p[l] );
|
||||
if ( d > 0.1f ) {
|
||||
break; // point in front
|
||||
}
|
||||
@@ -822,7 +776,7 @@ void AddBrushBevels( void ){
|
||||
buildBrush->numsides++;
|
||||
memset( s2, 0, sizeof( *s2 ) );
|
||||
|
||||
s2->planenum = FindFloatPlane( normal, dist, 1, &w->p[ j ] );
|
||||
s2->planenum = FindFloatPlane( plane, 1, &w->p[ j ] );
|
||||
s2->contentFlags = buildBrush->sides[0].contentFlags;
|
||||
s2->surfaceFlags = ( s->surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */
|
||||
s2->bevel = true;
|
||||
@@ -841,16 +795,14 @@ void AddBrushBevels( void ){
|
||||
and links it to the current entity
|
||||
*/
|
||||
|
||||
static void MergeOrigin( entity_t *ent, vec3_t origin ){
|
||||
vec3_t adjustment;
|
||||
static void MergeOrigin( entity_t *ent, const Vector3& origin ){
|
||||
char string[128];
|
||||
|
||||
/* we have not parsed the brush completely yet... */
|
||||
ent->vectorForKey( "origin", ent->origin );
|
||||
|
||||
VectorMA( origin, -1, ent->originbrush_origin, adjustment );
|
||||
VectorAdd( adjustment, ent->origin, ent->origin );
|
||||
VectorCopy( origin, ent->originbrush_origin );
|
||||
ent->origin += origin - ent->originbrush_origin;
|
||||
ent->originbrush_origin = origin;
|
||||
|
||||
sprintf( string, "%f %f %f", ent->origin[0], ent->origin[1], ent->origin[2] );
|
||||
ent->setKeyValue( "origin", string );
|
||||
@@ -868,8 +820,6 @@ brush_t *FinishBrush( bool noCollapseGroups ){
|
||||
/* origin brushes are removed, but they set the rotation origin for the rest of the brushes in the entity.
|
||||
after the entire entity is parsed, the planenums and texinfos will be adjusted for the origin brush */
|
||||
if ( buildBrush->compileFlags & C_ORIGIN ) {
|
||||
vec3_t origin;
|
||||
|
||||
Sys_Printf( "Entity %i (%s), Brush %i: origin brush detected\n",
|
||||
mapEnt->mapEntityNum, mapEnt->classname(), entitySourceBrushes );
|
||||
|
||||
@@ -879,10 +829,7 @@ brush_t *FinishBrush( bool noCollapseGroups ){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VectorAdd( buildBrush->mins, buildBrush->maxs, origin );
|
||||
VectorScale( origin, 0.5, origin );
|
||||
|
||||
MergeOrigin( &entities.back(), origin );
|
||||
MergeOrigin( &entities.back(), buildBrush->minmax.origin() );
|
||||
|
||||
/* don't keep this brush */
|
||||
return NULL;
|
||||
@@ -946,7 +893,7 @@ brush_t *FinishBrush( bool noCollapseGroups ){
|
||||
(must be identical in radiant!)
|
||||
*/
|
||||
|
||||
vec3_t baseaxis[18] =
|
||||
Vector3 baseaxis[18] =
|
||||
{
|
||||
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
|
||||
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
|
||||
@@ -956,25 +903,21 @@ vec3_t baseaxis[18] =
|
||||
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
|
||||
};
|
||||
|
||||
void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ){
|
||||
int bestaxis;
|
||||
vec_t dot,best;
|
||||
int i;
|
||||
void TextureAxisFromPlane( const plane_t *pln, Vector3& xv, Vector3& yv ){
|
||||
float best = 0;
|
||||
int bestaxis = 0;
|
||||
|
||||
best = 0;
|
||||
bestaxis = 0;
|
||||
|
||||
for ( i = 0 ; i < 6 ; i++ )
|
||||
for ( int i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
dot = DotProduct( pln->normal, baseaxis[i * 3] );
|
||||
const float dot = vector3_dot( pln->normal(), baseaxis[i * 3] );
|
||||
if ( dot > best + 0.0001f ) { /* ydnar: bug 637 fix, suggested by jmonroe */
|
||||
best = dot;
|
||||
bestaxis = i;
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy( baseaxis[bestaxis * 3 + 1], xv );
|
||||
VectorCopy( baseaxis[bestaxis * 3 + 2], yv );
|
||||
xv = baseaxis[bestaxis * 3 + 1];
|
||||
yv = baseaxis[bestaxis * 3 + 2];
|
||||
}
|
||||
|
||||
|
||||
@@ -984,12 +927,12 @@ void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ){
|
||||
creates world-to-texture mapping vecs for crappy quake plane arrangements
|
||||
*/
|
||||
|
||||
void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t scale[ 2 ], vec_t mappingVecs[ 2 ][ 4 ] ){
|
||||
vec3_t vecs[2];
|
||||
void QuakeTextureVecs( const plane_t *plane, float shift[ 2 ], float rotate, float scale[ 2 ], Vector4 mappingVecs[ 2 ] ){
|
||||
Vector3 vecs[2];
|
||||
int sv, tv;
|
||||
vec_t ang, sinv, cosv;
|
||||
vec_t ns, nt;
|
||||
int i, j;
|
||||
float ang, sinv, cosv;
|
||||
float ns, nt;
|
||||
int i;
|
||||
|
||||
|
||||
TextureAxisFromPlane( plane, vecs[0], vecs[1] );
|
||||
@@ -1016,7 +959,7 @@ void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t sca
|
||||
}
|
||||
else
|
||||
{
|
||||
ang = rotate / 180 * Q_PI;
|
||||
ang = degrees_to_radians( rotate );
|
||||
sinv = sin( ang );
|
||||
cosv = cos( ang );
|
||||
}
|
||||
@@ -1049,8 +992,7 @@ void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t sca
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 2 ; i++ )
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
mappingVecs[i][j] = vecs[i][j] / scale[i];
|
||||
mappingVecs[i].vec3() = vecs[i] / scale[i];
|
||||
|
||||
mappingVecs[0][3] = shift[0];
|
||||
mappingVecs[1][3] = shift[1];
|
||||
@@ -1074,12 +1016,12 @@ void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t sca
|
||||
|
||||
static void ParseRawBrush( bool onlyLights ){
|
||||
side_t *side;
|
||||
vec3_t planePoints[ 3 ];
|
||||
Vector3 planePoints[ 3 ];
|
||||
int planenum;
|
||||
shaderInfo_t *si;
|
||||
vec_t shift[ 2 ];
|
||||
vec_t rotate = 0;
|
||||
vec_t scale[ 2 ];
|
||||
float shift[ 2 ];
|
||||
float rotate = 0;
|
||||
float scale[ 2 ];
|
||||
int flags;
|
||||
|
||||
|
||||
@@ -1128,13 +1070,13 @@ static void ParseRawBrush( bool onlyLights ){
|
||||
buildBrush->numsides++;
|
||||
|
||||
/* read the three point plane definition */
|
||||
Parse1DMatrix( 3, planePoints[ 0 ] );
|
||||
Parse1DMatrix( 3, planePoints[ 1 ] );
|
||||
Parse1DMatrix( 3, planePoints[ 2 ] );
|
||||
Parse1DMatrix( 3, planePoints[ 0 ].data() );
|
||||
Parse1DMatrix( 3, planePoints[ 1 ].data() );
|
||||
Parse1DMatrix( 3, planePoints[ 2 ].data() );
|
||||
|
||||
/* bp: read the texture matrix */
|
||||
if ( g_brushType == EBrushType::Bp ) {
|
||||
Parse2DMatrix( 2, 3, (float*) side->texMat );
|
||||
Parse2DMatrix( 2, 3, side->texMat->data() );
|
||||
}
|
||||
|
||||
/* read shader name */
|
||||
@@ -1187,8 +1129,7 @@ static void ParseRawBrush( bool onlyLights ){
|
||||
if ( !scale[0] ) scale[0] = 1.f;
|
||||
if ( !scale[1] ) scale[1] = 1.f;
|
||||
for ( axis = 0; axis < 2; ++axis )
|
||||
for ( comp = 0; comp < 3; ++comp )
|
||||
side->vecs[axis][comp] /= scale[axis];
|
||||
side->vecs[axis].vec3() /= scale[axis];
|
||||
}
|
||||
|
||||
/* set default flags and values */
|
||||
@@ -1373,9 +1314,9 @@ void MoveBrushesToWorld( entity_t *ent ){
|
||||
parseMesh_t *pm;
|
||||
|
||||
/* we need to undo the common/origin adjustment, and instead shift them by the entity key origin */
|
||||
VectorScale( ent->origin, -1, ent->originbrush_origin );
|
||||
ent->originbrush_origin = -ent->origin;
|
||||
AdjustBrushesForOrigin( ent );
|
||||
VectorClear( ent->originbrush_origin );
|
||||
ent->originbrush_origin.set( 0 );
|
||||
|
||||
/* move brushes */
|
||||
for ( b = ent->brushes; b != NULL; b = next )
|
||||
@@ -1431,7 +1372,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){
|
||||
|
||||
int i;
|
||||
side_t *s;
|
||||
vec_t newdist;
|
||||
float newdist;
|
||||
brush_t *b;
|
||||
parseMesh_t *p;
|
||||
|
||||
@@ -1445,10 +1386,10 @@ void AdjustBrushesForOrigin( entity_t *ent ){
|
||||
s = &b->sides[ i ];
|
||||
|
||||
/* offset side plane */
|
||||
newdist = mapplanes[ s->planenum ].dist - DotProduct( mapplanes[ s->planenum ].normal, ent->originbrush_origin );
|
||||
newdist = -plane3_distance_to_point( mapplanes[ s->planenum ].plane, ent->originbrush_origin );
|
||||
|
||||
/* find a new plane */
|
||||
s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal, newdist, 0, NULL );
|
||||
s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal(), newdist, 0, NULL );
|
||||
}
|
||||
|
||||
/* rebuild brush windings (ydnar: just offsetting the winding above should be fine) */
|
||||
@@ -1459,7 +1400,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){
|
||||
for ( p = ent->patches; p != NULL; p = p->next )
|
||||
{
|
||||
for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
VectorSubtract( p->mesh.verts[ i ].xyz, ent->originbrush_origin, p->mesh.verts[ i ].xyz );
|
||||
p->mesh.verts[ i ].xyz -= ent->originbrush_origin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1474,36 +1415,32 @@ void SetEntityBounds( entity_t *e ){
|
||||
int i;
|
||||
brush_t *b;
|
||||
parseMesh_t *p;
|
||||
vec3_t mins, maxs;
|
||||
MinMax minmax;
|
||||
|
||||
|
||||
/* walk the entity's brushes/patches and determine bounds */
|
||||
ClearBounds( mins, maxs );
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
{
|
||||
AddPointToBounds( b->mins, mins, maxs );
|
||||
AddPointToBounds( b->maxs, mins, maxs );
|
||||
minmax.extend( b->minmax );
|
||||
}
|
||||
for ( p = e->patches; p; p = p->next )
|
||||
{
|
||||
for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
AddPointToBounds( p->mesh.verts[ i ].xyz, mins, maxs );
|
||||
minmax.extend( p->mesh.verts[ i ].xyz );
|
||||
}
|
||||
|
||||
/* try to find explicit min/max key */
|
||||
e->read_keyvalue( mins, "min" );
|
||||
e->read_keyvalue( maxs, "max" );
|
||||
e->read_keyvalue( minmax.mins, "min" );
|
||||
e->read_keyvalue( minmax.maxs, "max" );
|
||||
|
||||
/* store the bounds */
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
{
|
||||
VectorCopy( mins, b->eMins );
|
||||
VectorCopy( maxs, b->eMaxs );
|
||||
b->eMinmax = minmax;
|
||||
}
|
||||
for ( p = e->patches; p; p = p->next )
|
||||
{
|
||||
VectorCopy( mins, p->eMins );
|
||||
VectorCopy( maxs, p->eMaxs );
|
||||
p->eMinmax = minmax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1897,11 +1834,10 @@ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){
|
||||
else
|
||||
{
|
||||
/* set map bounds */
|
||||
ClearBounds( mapMins, mapMaxs );
|
||||
g_mapMinmax.clear();
|
||||
for ( b = entities[ 0 ].brushes; b; b = b->next )
|
||||
{
|
||||
AddPointToBounds( b->mins, mapMins, mapMaxs );
|
||||
AddPointToBounds( b->maxs, mapMins, mapMaxs );
|
||||
g_mapMinmax.extend( b->minmax );
|
||||
}
|
||||
|
||||
/* get brush counts */
|
||||
@@ -1920,8 +1856,8 @@ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){
|
||||
Sys_FPrintf( SYS_VRB, "%9d planes\n", nummapplanes );
|
||||
Sys_Printf( "%9d areaportals\n", c_areaportals );
|
||||
Sys_Printf( "Size: %5.0f, %5.0f, %5.0f to %5.0f, %5.0f, %5.0f\n",
|
||||
mapMins[ 0 ], mapMins[ 1 ], mapMins[ 2 ],
|
||||
mapMaxs[ 0 ], mapMaxs[ 1 ], mapMaxs[ 2 ] );
|
||||
g_mapMinmax.mins[0], g_mapMinmax.mins[1], g_mapMinmax.mins[2],
|
||||
g_mapMinmax.maxs[0], g_mapMinmax.maxs[1], g_mapMinmax.maxs[2] );
|
||||
|
||||
/* write bogus map */
|
||||
if ( fakemap ) {
|
||||
|
||||
+78
-148
@@ -38,35 +38,24 @@
|
||||
returns an 50/50 interpolated vert
|
||||
*/
|
||||
|
||||
void LerpDrawVert( bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *out ){
|
||||
int k;
|
||||
void LerpDrawVert( const bspDrawVert_t *a, const bspDrawVert_t *b, bspDrawVert_t *out ){
|
||||
|
||||
out->xyz = vector3_mid( a->xyz, b->xyz );
|
||||
out->st = vector2_mid( a->st, b->st );
|
||||
|
||||
out->xyz[ 0 ] = 0.5 * ( a->xyz[ 0 ] + b->xyz[ 0 ] );
|
||||
out->xyz[ 1 ] = 0.5 * ( a->xyz[ 1 ] + b->xyz[ 1 ] );
|
||||
out->xyz[ 2 ] = 0.5 * ( a->xyz[ 2 ] + b->xyz[ 2 ] );
|
||||
|
||||
out->st[ 0 ] = 0.5 * ( a->st[ 0 ] + b->st[ 0 ] );
|
||||
out->st[ 1 ] = 0.5 * ( a->st[ 1 ] + b->st[ 1 ] );
|
||||
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
for ( int k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
out->lightmap[ k ][ 0 ] = 0.5f * ( a->lightmap[ k ][ 0 ] + b->lightmap[ k ][ 0 ] );
|
||||
out->lightmap[ k ][ 1 ] = 0.5f * ( a->lightmap[ k ][ 1 ] + b->lightmap[ k ][ 1 ] );
|
||||
out->color[ k ][ 0 ] = ( a->color[ k ][ 0 ] + b->color[ k ][ 0 ] ) >> 1;
|
||||
out->color[ k ][ 1 ] = ( a->color[ k ][ 1 ] + b->color[ k ][ 1 ] ) >> 1;
|
||||
out->color[ k ][ 2 ] = ( a->color[ k ][ 2 ] + b->color[ k ][ 2 ] ) >> 1;
|
||||
out->color[ k ][ 3 ] = ( a->color[ k ][ 3 ] + b->color[ k ][ 3 ] ) >> 1;
|
||||
out->lightmap[ k ] = vector2_mid( a->lightmap[ k ], b->lightmap[ k ] );
|
||||
for( int i = 0; i < 4; ++i )
|
||||
out->color[ k ][ i ] = ( a->color[ k ][ i ] + b->color[ k ][ i ] ) >> 1;
|
||||
}
|
||||
|
||||
/* ydnar: added normal interpolation */
|
||||
out->normal[ 0 ] = 0.5f * ( a->normal[ 0 ] + b->normal[ 0 ] );
|
||||
out->normal[ 1 ] = 0.5f * ( a->normal[ 1 ] + b->normal[ 1 ] );
|
||||
out->normal[ 2 ] = 0.5f * ( a->normal[ 2 ] + b->normal[ 2 ] );
|
||||
out->normal = vector3_mid( a->normal, b->normal );
|
||||
|
||||
/* if the interpolant created a bogus normal, just copy the normal from a */
|
||||
if ( VectorNormalize( out->normal, out->normal ) == 0 ) {
|
||||
VectorCopy( a->normal, out->normal );
|
||||
if ( VectorNormalize( out->normal ) == 0 ) {
|
||||
out->normal = a->normal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,33 +67,23 @@ void LerpDrawVert( bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *out ){
|
||||
*/
|
||||
|
||||
void LerpDrawVertAmount( bspDrawVert_t *a, bspDrawVert_t *b, float amount, bspDrawVert_t *out ){
|
||||
int k;
|
||||
|
||||
out->xyz = a->xyz + ( b->xyz - a->xyz ) * amount;
|
||||
|
||||
out->xyz[ 0 ] = a->xyz[ 0 ] + amount * ( b->xyz[ 0 ] - a->xyz[ 0 ] );
|
||||
out->xyz[ 1 ] = a->xyz[ 1 ] + amount * ( b->xyz[ 1 ] - a->xyz[ 1 ] );
|
||||
out->xyz[ 2 ] = a->xyz[ 2 ] + amount * ( b->xyz[ 2 ] - a->xyz[ 2 ] );
|
||||
out->st = a->st + ( b->st - a->st ) * amount;
|
||||
|
||||
out->st[ 0 ] = a->st[ 0 ] + amount * ( b->st[ 0 ] - a->st[ 0 ] );
|
||||
out->st[ 1 ] = a->st[ 1 ] + amount * ( b->st[ 1 ] - a->st[ 1 ] );
|
||||
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
for ( int k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
out->lightmap[ k ][ 0 ] = a->lightmap[ k ][ 0 ] + amount * ( b->lightmap[ k ][ 0 ] - a->lightmap[ k ][ 0 ] );
|
||||
out->lightmap[ k ][ 1 ] = a->lightmap[ k ][ 1 ] + amount * ( b->lightmap[ k ][ 1 ] - a->lightmap[ k ][ 1 ] );
|
||||
out->color[ k ][ 0 ] = a->color[ k ][ 0 ] + amount * ( b->color[ k ][ 0 ] - a->color[ k ][ 0 ] );
|
||||
out->color[ k ][ 1 ] = a->color[ k ][ 1 ] + amount * ( b->color[ k ][ 1 ] - a->color[ k ][ 1 ] );
|
||||
out->color[ k ][ 2 ] = a->color[ k ][ 2 ] + amount * ( b->color[ k ][ 2 ] - a->color[ k ][ 2 ] );
|
||||
out->color[ k ][ 3 ] = a->color[ k ][ 3 ] + amount * ( b->color[ k ][ 3 ] - a->color[ k ][ 3 ] );
|
||||
out->lightmap[ k ] = a->lightmap[ k ] + ( b->lightmap[ k ] - a->lightmap[ k ] ) * amount;
|
||||
for( int i = 0; i < 4; ++i )
|
||||
out->color[ k ][ i ] = a->color[ k ][ i ] + amount * ( b->color[ k ][ i ] - a->color[ k ][ i ] );
|
||||
}
|
||||
|
||||
out->normal[ 0 ] = a->normal[ 0 ] + amount * ( b->normal[ 0 ] - a->normal[ 0 ] );
|
||||
out->normal[ 1 ] = a->normal[ 1 ] + amount * ( b->normal[ 1 ] - a->normal[ 1 ] );
|
||||
out->normal[ 2 ] = a->normal[ 2 ] + amount * ( b->normal[ 2 ] - a->normal[ 2 ] );
|
||||
out->normal = a->normal + ( b->normal - a->normal ) * amount;
|
||||
|
||||
/* if the interpolant created a bogus normal, just copy the normal from a */
|
||||
if ( VectorNormalize( out->normal, out->normal ) == 0 ) {
|
||||
VectorCopy( a->normal, out->normal );
|
||||
if ( VectorNormalize( out->normal ) == 0 ) {
|
||||
out->normal = a->normal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,17 +170,12 @@ void InvertMesh( mesh_t *in ) {
|
||||
*/
|
||||
void MakeMeshNormals( mesh_t in ){
|
||||
int i, j, k, dist;
|
||||
vec3_t normal;
|
||||
vec3_t sum;
|
||||
int count;
|
||||
vec3_t base;
|
||||
vec3_t delta;
|
||||
int x, y;
|
||||
bspDrawVert_t *dv;
|
||||
vec3_t around[8], temp;
|
||||
Vector3 around[8];
|
||||
bool good[8];
|
||||
bool wrapWidth, wrapHeight;
|
||||
float len;
|
||||
int neighbors[8][2] =
|
||||
{
|
||||
{0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
|
||||
@@ -210,10 +184,7 @@ void MakeMeshNormals( mesh_t in ){
|
||||
|
||||
wrapWidth = false;
|
||||
for ( i = 0 ; i < in.height ; i++ ) {
|
||||
VectorSubtract( in.verts[i * in.width].xyz,
|
||||
in.verts[i * in.width + in.width - 1].xyz, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > 1.0 ) {
|
||||
if ( vector3_length( in.verts[i * in.width].xyz - in.verts[i * in.width + in.width - 1].xyz ) > 1.0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -223,10 +194,7 @@ void MakeMeshNormals( mesh_t in ){
|
||||
|
||||
wrapHeight = false;
|
||||
for ( i = 0 ; i < in.width ; i++ ) {
|
||||
VectorSubtract( in.verts[i].xyz,
|
||||
in.verts[i + ( in.height - 1 ) * in.width].xyz, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > 1.0 ) {
|
||||
if ( vector3_length( in.verts[i].xyz - in.verts[i + ( in.height - 1 ) * in.width].xyz ) > 1.0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -239,9 +207,9 @@ void MakeMeshNormals( mesh_t in ){
|
||||
for ( j = 0 ; j < in.height ; j++ ) {
|
||||
count = 0;
|
||||
dv = &in.verts[j * in.width + i];
|
||||
VectorCopy( dv->xyz, base );
|
||||
const Vector3 base( dv->xyz );
|
||||
for ( k = 0 ; k < 8 ; k++ ) {
|
||||
VectorClear( around[k] );
|
||||
around[k].set( 0 );
|
||||
good[k] = false;
|
||||
|
||||
for ( dist = 1 ; dist <= 3 ; dist++ ) {
|
||||
@@ -267,35 +235,35 @@ void MakeMeshNormals( mesh_t in ){
|
||||
if ( x < 0 || x >= in.width || y < 0 || y >= in.height ) {
|
||||
break; // edge of patch
|
||||
}
|
||||
VectorSubtract( in.verts[y * in.width + x].xyz, base, temp );
|
||||
if ( VectorNormalize( temp, temp ) == 0 ) {
|
||||
Vector3 temp = in.verts[y * in.width + x].xyz - base;
|
||||
if ( VectorNormalize( temp ) == 0 ) {
|
||||
continue; // degenerate edge, get more dist
|
||||
}
|
||||
else {
|
||||
good[k] = true;
|
||||
VectorCopy( temp, around[k] );
|
||||
around[k] = temp;
|
||||
break; // good edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( sum );
|
||||
Vector3 sum( 0, 0, 0 );
|
||||
for ( k = 0 ; k < 8 ; k++ ) {
|
||||
if ( !good[k] || !good[( k + 1 ) & 7] ) {
|
||||
continue; // didn't get two points
|
||||
}
|
||||
CrossProduct( around[( k + 1 ) & 7], around[k], normal );
|
||||
if ( VectorNormalize( normal, normal ) == 0 ) {
|
||||
Vector3 normal = vector3_cross( around[( k + 1 ) & 7], around[k] );
|
||||
if ( VectorNormalize( normal ) == 0 ) {
|
||||
continue;
|
||||
}
|
||||
VectorAdd( normal, sum, sum );
|
||||
sum += normal;
|
||||
count++;
|
||||
}
|
||||
if ( count == 0 ) {
|
||||
//Sys_Printf("bad normal\n");
|
||||
count = 1;
|
||||
}
|
||||
VectorNormalize( sum, dv->normal );
|
||||
dv->normal = VectorNormalized( sum );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,55 +275,40 @@ void MakeMeshNormals( mesh_t in ){
|
||||
*/
|
||||
|
||||
void PutMeshOnCurve( mesh_t in ) {
|
||||
int i, j, l, m;
|
||||
float prev, next;
|
||||
int i, j, m;
|
||||
|
||||
|
||||
// put all the aproximating points on the curve
|
||||
for ( i = 0 ; i < in.width ; i++ ) {
|
||||
for ( j = 1 ; j < in.height ; j += 2 ) {
|
||||
for ( l = 0 ; l < 3 ; l++ ) {
|
||||
prev = ( in.verts[j * in.width + i].xyz[l] + in.verts[( j + 1 ) * in.width + i].xyz[l] ) * 0.5;
|
||||
next = ( in.verts[j * in.width + i].xyz[l] + in.verts[( j - 1 ) * in.width + i].xyz[l] ) * 0.5;
|
||||
in.verts[j * in.width + i].xyz[l] = ( prev + next ) * 0.5;
|
||||
|
||||
/* ydnar: interpolating st coords */
|
||||
if ( l < 2 ) {
|
||||
prev = ( in.verts[j * in.width + i].st[l] + in.verts[( j + 1 ) * in.width + i].st[l] ) * 0.5;
|
||||
next = ( in.verts[j * in.width + i].st[l] + in.verts[( j - 1 ) * in.width + i].st[l] ) * 0.5;
|
||||
in.verts[j * in.width + i].st[l] = ( prev + next ) * 0.5;
|
||||
|
||||
for ( m = 0; m < MAX_LIGHTMAPS; m++ )
|
||||
{
|
||||
prev = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[( j + 1 ) * in.width + i].lightmap[ m ][l] ) * 0.5;
|
||||
next = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[( j - 1 ) * in.width + i].lightmap[ m ][l] ) * 0.5;
|
||||
in.verts[j * in.width + i].lightmap[ m ][l] = ( prev + next ) * 0.5;
|
||||
}
|
||||
}
|
||||
const int idx = j * in.width + i;
|
||||
const int idprev = ( j + 1 ) * in.width + i;
|
||||
const int idnext = ( j - 1 ) * in.width + i;
|
||||
in.verts[idx].xyz = vector3_mid( vector3_mid( in.verts[idx].xyz, in.verts[idprev].xyz ),
|
||||
vector3_mid( in.verts[idx].xyz, in.verts[idnext].xyz ) );
|
||||
/* ydnar: interpolating st coords */
|
||||
in.verts[idx].st = vector2_mid( vector2_mid( in.verts[idx].st, in.verts[idprev].st ),
|
||||
vector2_mid( in.verts[idx].st, in.verts[idnext].st ) );
|
||||
for ( m = 0; m < MAX_LIGHTMAPS; m++ )
|
||||
{
|
||||
in.verts[idx].lightmap[ m ] = vector2_mid( vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idprev].lightmap[ m ] ),
|
||||
vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idnext].lightmap[ m ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0 ; j < in.height ; j++ ) {
|
||||
for ( i = 1 ; i < in.width ; i += 2 ) {
|
||||
for ( l = 0 ; l < 3 ; l++ ) {
|
||||
prev = ( in.verts[j * in.width + i].xyz[l] + in.verts[j * in.width + i + 1].xyz[l] ) * 0.5;
|
||||
next = ( in.verts[j * in.width + i].xyz[l] + in.verts[j * in.width + i - 1].xyz[l] ) * 0.5;
|
||||
in.verts[j * in.width + i].xyz[l] = ( prev + next ) * 0.5;
|
||||
|
||||
/* ydnar: interpolating st coords */
|
||||
if ( l < 2 ) {
|
||||
prev = ( in.verts[j * in.width + i].st[l] + in.verts[j * in.width + i + 1].st[l] ) * 0.5;
|
||||
next = ( in.verts[j * in.width + i].st[l] + in.verts[j * in.width + i - 1].st[l] ) * 0.5;
|
||||
in.verts[j * in.width + i].st[l] = ( prev + next ) * 0.5;
|
||||
|
||||
for ( m = 0; m < MAX_LIGHTMAPS; m++ )
|
||||
{
|
||||
prev = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[j * in.width + i + 1].lightmap[ m ][l] ) * 0.5;
|
||||
next = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[j * in.width + i - 1].lightmap[ m ][l] ) * 0.5;
|
||||
in.verts[j * in.width + i].lightmap[ m ][l] = ( prev + next ) * 0.5;
|
||||
}
|
||||
}
|
||||
const int idx = j * in.width + i;
|
||||
in.verts[idx].xyz = vector3_mid( vector3_mid( in.verts[idx].xyz, in.verts[idx + 1].xyz ),
|
||||
vector3_mid( in.verts[idx].xyz, in.verts[idx - 1].xyz ) );
|
||||
/* ydnar: interpolating st coords */
|
||||
in.verts[idx].st = vector2_mid( vector2_mid( in.verts[idx].st, in.verts[idx + 1].st ),
|
||||
vector2_mid( in.verts[idx].st, in.verts[idx - 1].st ) );
|
||||
for ( m = 0; m < MAX_LIGHTMAPS; m++ )
|
||||
{
|
||||
in.verts[idx].lightmap[ m ] = vector2_mid( vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idx + 1].lightmap[ m ] ),
|
||||
vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idx - 1].lightmap[ m ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,11 +322,9 @@ void PutMeshOnCurve( mesh_t in ) {
|
||||
=================
|
||||
*/
|
||||
mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){
|
||||
int i, j, k, l;
|
||||
int i, j, k;
|
||||
bspDrawVert_t prev, next, mid;
|
||||
vec3_t prevxyz, nextxyz, midxyz;
|
||||
vec3_t delta;
|
||||
float len;
|
||||
Vector3 prevxyz, nextxyz, midxyz;
|
||||
mesh_t out;
|
||||
|
||||
bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
|
||||
@@ -392,23 +343,18 @@ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){
|
||||
for ( j = 0 ; j + 2 < out.width ; j += 2 ) {
|
||||
// check subdivided midpoints against control points
|
||||
for ( i = 0 ; i < out.height ; i++ ) {
|
||||
for ( l = 0 ; l < 3 ; l++ ) {
|
||||
prevxyz[l] = expand[i][j + 1].xyz[l] - expand[i][j].xyz[l];
|
||||
nextxyz[l] = expand[i][j + 2].xyz[l] - expand[i][j + 1].xyz[l];
|
||||
midxyz[l] = ( expand[i][j].xyz[l] + expand[i][j + 1].xyz[l] * 2
|
||||
+ expand[i][j + 2].xyz[l] ) * 0.25;
|
||||
}
|
||||
prevxyz = expand[i][j + 1].xyz - expand[i][j].xyz;
|
||||
nextxyz = expand[i][j + 2].xyz - expand[i][j + 1].xyz;
|
||||
midxyz = ( expand[i][j].xyz + expand[i][j + 1].xyz * 2 + expand[i][j + 2].xyz ) * 0.25;
|
||||
|
||||
// if the span length is too long, force a subdivision
|
||||
if ( VectorLength( prevxyz ) > minLength
|
||||
|| VectorLength( nextxyz ) > minLength ) {
|
||||
if ( vector3_length( prevxyz ) > minLength
|
||||
|| vector3_length( nextxyz ) > minLength ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// see if this midpoint is off far enough to subdivide
|
||||
VectorSubtract( expand[i][j + 1].xyz, midxyz, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > maxError ) {
|
||||
if ( vector3_length( expand[i][j + 1].xyz - midxyz ) > maxError ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -446,22 +392,17 @@ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){
|
||||
for ( j = 0 ; j + 2 < out.height ; j += 2 ) {
|
||||
// check subdivided midpoints against control points
|
||||
for ( i = 0 ; i < out.width ; i++ ) {
|
||||
for ( l = 0 ; l < 3 ; l++ ) {
|
||||
prevxyz[l] = expand[j + 1][i].xyz[l] - expand[j][i].xyz[l];
|
||||
nextxyz[l] = expand[j + 2][i].xyz[l] - expand[j + 1][i].xyz[l];
|
||||
midxyz[l] = ( expand[j][i].xyz[l] + expand[j + 1][i].xyz[l] * 2
|
||||
+ expand[j + 2][i].xyz[l] ) * 0.25;
|
||||
}
|
||||
prevxyz = expand[j + 1][i].xyz - expand[j][i].xyz;
|
||||
nextxyz = expand[j + 2][i].xyz - expand[j + 1][i].xyz;
|
||||
midxyz = ( expand[j][i].xyz + expand[j + 1][i].xyz * 2 + expand[j + 2][i].xyz ) * 0.25;
|
||||
|
||||
// if the span length is too long, force a subdivision
|
||||
if ( VectorLength( prevxyz ) > minLength
|
||||
|| VectorLength( nextxyz ) > minLength ) {
|
||||
if ( vector3_length( prevxyz ) > minLength
|
||||
|| vector3_length( nextxyz ) > minLength ) {
|
||||
break;
|
||||
}
|
||||
// see if this midpoint is off far enough to subdivide
|
||||
VectorSubtract( expand[j + 1][i].xyz, midxyz, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > maxError ) {
|
||||
if ( vector3_length( expand[j + 1][i].xyz - midxyz ) > maxError ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -626,14 +567,11 @@ mesh_t *SubdivideMesh2( mesh_t in, int iterations ){
|
||||
ProjectPointOntoVector
|
||||
================
|
||||
*/
|
||||
void ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj ){
|
||||
vec3_t pVec, vec;
|
||||
|
||||
VectorSubtract( point, vStart, pVec );
|
||||
VectorSubtract( vEnd, vStart, vec );
|
||||
VectorNormalize( vec, vec );
|
||||
Vector3 ProjectPointOntoVector( const Vector3& point, const Vector3& vStart, const Vector3& vEnd ){
|
||||
const Vector3 pVec = point - vStart;
|
||||
const Vector3 vec = VectorNormalized( vEnd - vStart );
|
||||
// project onto the directional vector for this segment
|
||||
VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
|
||||
return ( vStart + vec * vector3_dot( pVec, vec ) );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -644,7 +582,6 @@ void ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vP
|
||||
mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
|
||||
int i, j, k;
|
||||
float len, maxLength;
|
||||
vec3_t proj, dir;
|
||||
mesh_t out;
|
||||
|
||||
bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
|
||||
@@ -662,9 +599,7 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
|
||||
for ( j = 1 ; j < out.width - 1; j++ ) {
|
||||
maxLength = 0;
|
||||
for ( i = 0 ; i < out.height ; i++ ) {
|
||||
ProjectPointOntoVector( expand[i][j].xyz, expand[i][j - 1].xyz, expand[i][j + 1].xyz, proj );
|
||||
VectorSubtract( expand[i][j].xyz, proj, dir );
|
||||
len = VectorLength( dir );
|
||||
len = vector3_length( expand[i][j].xyz - ProjectPointOntoVector( expand[i][j].xyz, expand[i][j - 1].xyz, expand[i][j + 1].xyz ) );
|
||||
if ( len > maxLength ) {
|
||||
maxLength = len;
|
||||
}
|
||||
@@ -682,9 +617,7 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
|
||||
for ( j = 1 ; j < out.height - 1; j++ ) {
|
||||
maxLength = 0;
|
||||
for ( i = 0 ; i < out.width ; i++ ) {
|
||||
ProjectPointOntoVector( expand[j][i].xyz, expand[j - 1][i].xyz, expand[j + 1][i].xyz, proj );
|
||||
VectorSubtract( expand[j][i].xyz, proj, dir );
|
||||
len = VectorLength( dir );
|
||||
len = vector3_length( expand[j][i].xyz - ProjectPointOntoVector( expand[j][i].xyz, expand[j - 1][i].xyz, expand[j + 1][i].xyz ) );
|
||||
if ( len > maxLength ) {
|
||||
maxLength = len;
|
||||
}
|
||||
@@ -717,7 +650,6 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
|
||||
*/
|
||||
mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *widthtable, int *heighttable ){
|
||||
int i, j, k, w, h, maxsubdivisions, subdivisions;
|
||||
vec3_t dir;
|
||||
float length, maxLength, amount;
|
||||
mesh_t out;
|
||||
bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
|
||||
@@ -742,8 +674,7 @@ mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *width
|
||||
for ( w = 0, j = 0 ; w < in->width - 1; w++, j += subdivisions + 1 ) {
|
||||
maxLength = 0;
|
||||
for ( i = 0 ; i < out.height ; i++ ) {
|
||||
VectorSubtract( expand[i][j + 1].xyz, expand[i][j].xyz, dir );
|
||||
length = VectorLength( dir );
|
||||
length = vector3_length( expand[i][j + 1].xyz - expand[i][j].xyz );
|
||||
if ( length > maxLength ) {
|
||||
maxLength = length;
|
||||
}
|
||||
@@ -778,9 +709,8 @@ mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *width
|
||||
for ( h = 0, j = 0 ; h < in->height - 1; h++, j += subdivisions + 1 ) {
|
||||
maxLength = 0;
|
||||
for ( i = 0 ; i < out.width ; i++ ) {
|
||||
VectorSubtract( expand[j + 1][i].xyz, expand[j][i].xyz, dir );
|
||||
length = VectorLength( dir );
|
||||
if ( length > maxLength ) {
|
||||
length = vector3_length( expand[j + 1][i].xyz - expand[j][i].xyz );
|
||||
if ( length > maxLength ) {
|
||||
maxLength = length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,29 +45,29 @@ struct minimap_t
|
||||
float boost, brightness, contrast;
|
||||
float *data1f;
|
||||
float *sharpendata1f;
|
||||
vec3_t mins, size;
|
||||
Vector3 mins, size;
|
||||
};
|
||||
|
||||
static minimap_t minimap;
|
||||
|
||||
bool BrushIntersectionWithLine( bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out ){
|
||||
bool BrushIntersectionWithLine( bspBrush_t *brush, const Vector3& start, const Vector3& dir, float *t_in, float *t_out ){
|
||||
int i;
|
||||
bool in = false, out = false;
|
||||
bspBrushSide_t *sides = &bspBrushSides[brush->firstSide];
|
||||
|
||||
for ( i = 0; i < brush->numSides; ++i )
|
||||
{
|
||||
bspPlane_t *p = &bspPlanes[sides[i].planeNum];
|
||||
float sn = DotProduct( start, p->normal );
|
||||
float dn = DotProduct( dir, p->normal );
|
||||
const bspPlane_t& p = bspPlanes[sides[i].planeNum];
|
||||
float sn = vector3_dot( start, p.normal() );
|
||||
float dn = vector3_dot( dir, p.normal() );
|
||||
if ( dn == 0 ) {
|
||||
if ( sn > p->dist ) {
|
||||
if ( sn > p.dist() ) {
|
||||
return false; // outside!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float t = ( p->dist - sn ) / dn;
|
||||
float t = ( p.dist() - sn ) / dn;
|
||||
if ( dn < 0 ) {
|
||||
if ( !in || t > *t_in ) {
|
||||
*t_in = t;
|
||||
@@ -95,7 +95,6 @@ bool BrushIntersectionWithLine( bspBrush_t *brush, vec3_t start, vec3_t dir, flo
|
||||
}
|
||||
|
||||
static float MiniMapSample( float x, float y ){
|
||||
vec3_t org, dir;
|
||||
int i, bi;
|
||||
float t0, t1;
|
||||
float samp;
|
||||
@@ -103,12 +102,8 @@ static float MiniMapSample( float x, float y ){
|
||||
bspBrushSide_t *s;
|
||||
int cnt;
|
||||
|
||||
org[0] = x;
|
||||
org[1] = y;
|
||||
org[2] = 0;
|
||||
dir[0] = 0;
|
||||
dir[1] = 0;
|
||||
dir[2] = 1;
|
||||
const Vector3 org( x, y, 0 );
|
||||
const Vector3 dir( g_vector3_axis_z );
|
||||
|
||||
cnt = 0;
|
||||
samp = 0;
|
||||
@@ -120,16 +115,16 @@ static float MiniMapSample( float x, float y ){
|
||||
|
||||
// sort out mins/maxs of the brush
|
||||
s = &bspBrushSides[b->firstSide];
|
||||
if ( x < -bspPlanes[s[0].planeNum].dist ) {
|
||||
if ( x < -bspPlanes[s[0].planeNum].dist() ) {
|
||||
continue;
|
||||
}
|
||||
if ( x > +bspPlanes[s[1].planeNum].dist ) {
|
||||
if ( x > +bspPlanes[s[1].planeNum].dist() ) {
|
||||
continue;
|
||||
}
|
||||
if ( y < -bspPlanes[s[2].planeNum].dist ) {
|
||||
if ( y < -bspPlanes[s[2].planeNum].dist() ) {
|
||||
continue;
|
||||
}
|
||||
if ( y > +bspPlanes[s[3].planeNum].dist ) {
|
||||
if ( y > +bspPlanes[s[3].planeNum].dist() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -281,16 +276,16 @@ static void MiniMapBrightnessContrast( int y ){
|
||||
}
|
||||
}
|
||||
|
||||
void MiniMapMakeMinsMaxs( vec3_t mins_in, vec3_t maxs_in, float border, bool keepaspect ){
|
||||
vec3_t mins, maxs, extend;
|
||||
VectorCopy( mins_in, mins );
|
||||
VectorCopy( maxs_in, maxs );
|
||||
void MiniMapMakeMinsMaxs( const Vector3& mins_in, const Vector3& maxs_in, float border, bool keepaspect ){
|
||||
Vector3 mins = mins_in;
|
||||
Vector3 maxs = maxs_in;
|
||||
Vector3 extend;
|
||||
|
||||
// line compatible to nexuiz mapinfo
|
||||
Sys_Printf( "size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] );
|
||||
|
||||
if ( keepaspect ) {
|
||||
VectorSubtract( maxs, mins, extend );
|
||||
extend = maxs - mins;
|
||||
if ( extend[1] > extend[0] ) {
|
||||
mins[0] -= ( extend[1] - extend[0] ) * 0.5;
|
||||
maxs[0] += ( extend[1] - extend[0] ) * 0.5;
|
||||
@@ -305,14 +300,13 @@ void MiniMapMakeMinsMaxs( vec3_t mins_in, vec3_t maxs_in, float border, bool kee
|
||||
/* border: amount of black area around the image */
|
||||
/* input: border, 1-2*border, border but we need border/(1-2*border) */
|
||||
|
||||
VectorSubtract( maxs, mins, extend );
|
||||
VectorScale( extend, border / ( 1 - 2 * border ), extend );
|
||||
extend = ( maxs - mins ) * ( border / ( 1 - 2 * border ) );
|
||||
|
||||
VectorSubtract( mins, extend, mins );
|
||||
VectorAdd( maxs, extend, maxs );
|
||||
mins -= extend;
|
||||
maxs += extend;
|
||||
|
||||
VectorCopy( mins, minimap.mins );
|
||||
VectorSubtract( maxs, mins, minimap.size );
|
||||
minimap.mins = mins;
|
||||
minimap.size = maxs - mins;
|
||||
|
||||
// line compatible to nexuiz mapinfo
|
||||
Sys_Printf( "size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] );
|
||||
@@ -468,7 +462,6 @@ int MiniMapBSPMain( int argc, char **argv ){
|
||||
int x, y;
|
||||
int i;
|
||||
EMiniMapMode mode;
|
||||
vec3_t mins, maxs;
|
||||
bool keepaspect;
|
||||
|
||||
/* arg checking */
|
||||
@@ -486,10 +479,10 @@ int MiniMapBSPMain( int argc, char **argv ){
|
||||
LoadBSPFile( source );
|
||||
|
||||
minimap.model = &bspModels[0];
|
||||
VectorCopy( minimap.model->mins, mins );
|
||||
VectorCopy( minimap.model->maxs, maxs );
|
||||
Vector3 mins = minimap.model->minmax.mins;
|
||||
Vector3 maxs = minimap.model->minmax.maxs;
|
||||
|
||||
*minimapFilename = 0;
|
||||
strClear( minimapFilename );
|
||||
minimapSharpen = game->miniMapSharpen;
|
||||
minimap.width = minimap.height = game->miniMapSize;
|
||||
border = game->miniMapBorder;
|
||||
@@ -598,7 +591,7 @@ int MiniMapBSPMain( int argc, char **argv ){
|
||||
|
||||
MiniMapMakeMinsMaxs( mins, maxs, border, keepaspect );
|
||||
|
||||
if ( !*minimapFilename ) {
|
||||
if ( strEmpty( minimapFilename ) ) {
|
||||
ExtractFileBase( source, basename );
|
||||
ExtractFilePath( source, path );
|
||||
sprintf( relativeMinimapFilename, game->miniMapNameFormat, basename );
|
||||
|
||||
+198
-264
@@ -205,9 +205,9 @@ picoModel_t *LoadModel( const char *name, int frame ){
|
||||
adds a picomodel into the bsp
|
||||
*/
|
||||
|
||||
void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){
|
||||
void InsertModel( const char *name, int skin, int frame, const Matrix4& transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){
|
||||
int i, j, s, k, numSurfaces;
|
||||
m4x4_t identity, nTransform;
|
||||
const Matrix4 nTransform( matrix4_for_normal_transform( transform ) );
|
||||
picoModel_t *model;
|
||||
picoSurface_t *surface;
|
||||
shaderInfo_t *si;
|
||||
@@ -291,24 +291,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
free( skinfilecontent );
|
||||
}
|
||||
|
||||
/* handle null matrix */
|
||||
if ( transform == NULL ) {
|
||||
m4x4_identity( identity );
|
||||
transform = identity;
|
||||
}
|
||||
|
||||
/* hack: Stable-1_2 and trunk have differing row/column major matrix order
|
||||
this transpose is necessary with Stable-1_2
|
||||
uncomment the following line with old m4x4_t (non 1.3/spog_branch) code */
|
||||
//% m4x4_transpose( transform );
|
||||
|
||||
/* create transform matrix for normals */
|
||||
memcpy( nTransform, transform, sizeof( m4x4_t ) );
|
||||
if ( m4x4_invert( nTransform ) ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Can't invert model transform matrix, using transpose instead\n" );
|
||||
}
|
||||
m4x4_transpose( nTransform );
|
||||
|
||||
/* fix bogus lightmap scale */
|
||||
if ( lightmapScale <= 0.0f ) {
|
||||
lightmapScale = 1.0f;
|
||||
@@ -442,24 +429,23 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
/* xyz and normal */
|
||||
xyz = PicoGetSurfaceXYZ( surface, i );
|
||||
VectorCopy( xyz, dv->xyz );
|
||||
m4x4_transform_point( transform, dv->xyz );
|
||||
matrix4_transform_point( transform, dv->xyz );
|
||||
|
||||
normal = PicoGetSurfaceNormal( surface, i );
|
||||
VectorCopy( normal, dv->normal );
|
||||
m4x4_transform_normal( nTransform, dv->normal );
|
||||
VectorNormalize( dv->normal, dv->normal );
|
||||
matrix4_transform_direction( nTransform, dv->normal );
|
||||
VectorNormalize( dv->normal );
|
||||
|
||||
/* ydnar: tek-fu celshading support for flat shaded shit */
|
||||
if ( flat ) {
|
||||
dv->st[ 0 ] = si->stFlat[ 0 ];
|
||||
dv->st[ 1 ] = si->stFlat[ 1 ];
|
||||
dv->st = si->stFlat;
|
||||
}
|
||||
|
||||
/* ydnar: gs mods: added support for explicit shader texcoord generation */
|
||||
else if ( si->tcGen ) {
|
||||
/* project the texture */
|
||||
dv->st[ 0 ] = DotProduct( si->vecs[ 0 ], dv->xyz );
|
||||
dv->st[ 1 ] = DotProduct( si->vecs[ 1 ], dv->xyz );
|
||||
dv->st[ 0 ] = vector3_dot( si->vecs[ 0 ], dv->xyz );
|
||||
dv->st[ 1 ] = vector3_dot( si->vecs[ 1 ], dv->xyz );
|
||||
}
|
||||
|
||||
/* normal texture coordinates */
|
||||
@@ -477,17 +463,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
dv->lightmap[ j ][ 0 ] = 0.0f;
|
||||
dv->lightmap[ j ][ 1 ] = 0.0f;
|
||||
if ( spawnFlags & 32 ) { // spawnflag 32: model color -> alpha hack
|
||||
dv->color[ j ][ 0 ] = 255.0f;
|
||||
dv->color[ j ][ 1 ] = 255.0f;
|
||||
dv->color[ j ][ 2 ] = 255.0f;
|
||||
dv->color[ j ][ 3 ] = RGBTOGRAY( color );
|
||||
dv->color[ j ] = { 255, 255, 255, RGBTOGRAY( color ) };
|
||||
}
|
||||
else
|
||||
{
|
||||
dv->color[ j ][ 0 ] = color[ 0 ];
|
||||
dv->color[ j ][ 1 ] = color[ 1 ];
|
||||
dv->color[ j ][ 2 ] = color[ 2 ];
|
||||
dv->color[ j ][ 3 ] = color[ 3 ];
|
||||
dv->color[ j ] = { color[0], color[1], color[2], color[3] };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,12 +502,12 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
( spf == 5632 ) || //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+AXIAL_BACKPLANE
|
||||
( spf == 3072 ) || //EXTRUDE_UPWARDS+MAX_EXTRUDE
|
||||
( spf == 5120 ) ){ //EXTRUDE_UPWARDS+AXIAL_BACKPLANE
|
||||
vec3_t points[ 4 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3];
|
||||
vec4_t plane, reverse, p[3];
|
||||
Vector3 points[ 4 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3];
|
||||
Plane3f plane, reverse, p[3];
|
||||
double normalEpsilon_save;
|
||||
bool snpd;
|
||||
vec3_t min = { 999999, 999999, 999999 }, max = { -999999, -999999, -999999 };
|
||||
vec3_t avgDirection = { 0, 0, 0 };
|
||||
MinMax minmax;
|
||||
Vector3 avgDirection( 0, 0, 0 );
|
||||
int axis;
|
||||
#define nonax_clip_dbg 0
|
||||
|
||||
@@ -549,41 +529,27 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
dv = &ds->verts[ ds->indexes[ i + j ] ];
|
||||
VectorCopy( dv->xyz, points[ j ] );
|
||||
points[ j ] = dv->xyz;
|
||||
}
|
||||
if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ){
|
||||
if ( spawnFlags & 16 ) VectorAdd( avgDirection, plane, avgDirection ); //calculate average mesh facing direction
|
||||
if ( PlaneFromPoints( plane, points ) ){
|
||||
if ( spawnFlags & 16 )
|
||||
avgDirection += plane.normal(); //calculate average mesh facing direction
|
||||
|
||||
//get min/max
|
||||
for ( k = 2; k > -1; k-- ){
|
||||
if ( plane[k] > 0 ){
|
||||
for ( j = 0; j < 3; j++ ){ if ( points[j][k] < min[k] ) min[k] = points[j][k]; }
|
||||
}
|
||||
else if ( plane[k] < 0 ){
|
||||
for ( j = 0; j < 3; j++ ){ if ( points[j][k] > max[k] ) max[k] = points[j][k]; }
|
||||
}
|
||||
//if EXTRUDE_DOWNWARDS or EXTRUDE_UPWARDS
|
||||
if ( ( spawnFlags & 512 ) || ( spawnFlags & 1024 ) ){
|
||||
break;
|
||||
}
|
||||
for ( j = 0; j < 3; ++j ){
|
||||
minmax.extend( points[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
//unify avg direction
|
||||
if ( spawnFlags & 16 ){
|
||||
for ( j = 0; j < 3; j++ ){
|
||||
if ( fabs(avgDirection[j]) > fabs(avgDirection[(j+1)%3]) ){
|
||||
avgDirection[(j+1)%3] = 0.0;
|
||||
axis = j;
|
||||
}
|
||||
else {
|
||||
avgDirection[j] = 0.0;
|
||||
}
|
||||
if ( vector3_length( avgDirection ) != 0 ){
|
||||
axis = vector3_max_abs_component_index( avgDirection );
|
||||
}
|
||||
if ( VectorNormalize( avgDirection, avgDirection ) == 0 ){
|
||||
else{
|
||||
axis = 2;
|
||||
VectorSet( avgDirection, 0, 0, 1 );
|
||||
}
|
||||
avgDirection = avgDirection[axis] >= 0? g_vector3_axes[axis] : -g_vector3_axes[axis];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -600,11 +566,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
dv = &ds->verts[ ds->indexes[ i + j ] ];
|
||||
|
||||
/* copy xyz */
|
||||
VectorCopy( dv->xyz, points[ j ] );
|
||||
points[ j ] = dv->xyz;
|
||||
}
|
||||
|
||||
/* make plane for triangle */
|
||||
if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ) {
|
||||
if ( PlaneFromPoints( plane, points ) ) {
|
||||
|
||||
/* build a brush */
|
||||
buildBrush = AllocBrush( 48 );
|
||||
@@ -621,11 +587,10 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
snpd = false;
|
||||
for ( j=0; j<3; j++ )
|
||||
{
|
||||
if ( fabs(plane[j]) < 0.00025 && fabs(plane[(j+1)%3]) < 0.00025 && ( plane[j] != 0.0 || plane[(j+1)%3] != 0.0 ) ){
|
||||
VectorAdd( points[ 0 ], points[ 1 ], cnt );
|
||||
VectorAdd( cnt, points[ 2 ], cnt );
|
||||
VectorScale( cnt, 0.3333333333333f, cnt );
|
||||
points[0][(j+2)%3]=points[1][(j+2)%3]=points[2][(j+2)%3]=cnt[(j+2)%3];
|
||||
if ( fabs( plane.normal()[j] ) < 0.00025 && fabs( plane.normal()[(j+1)%3] ) < 0.00025
|
||||
&& ( plane.normal()[j] != 0.0 || plane.normal()[(j+1)%3] != 0.0 ) ){
|
||||
cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
points[0][(j+2)%3] = points[1][(j+2)%3] = points[2][(j+2)%3] = cnt[(j+2)%3];
|
||||
snpd = true;
|
||||
break;
|
||||
}
|
||||
@@ -634,8 +599,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
//snap pairs of points to prevent bad side planes
|
||||
for ( j=0; j<3; j++ )
|
||||
{
|
||||
VectorSubtract( points[j], points[(j+1)%3], nrm );
|
||||
VectorNormalize( nrm, nrm );
|
||||
nrm = VectorNormalized( points[j] - points[(j+1)%3] );
|
||||
for ( k=0; k<3; k++ )
|
||||
{
|
||||
if ( nrm[k] != 0.0 && fabs(nrm[k]) < 0.00025 ){
|
||||
@@ -648,19 +612,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
}
|
||||
|
||||
if ( snpd ) {
|
||||
PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] );
|
||||
PlaneFromPoints( plane, points );
|
||||
snpd = false;
|
||||
}
|
||||
|
||||
//vector-is-close-to-be-on-axis check again, happens after previous code sometimes
|
||||
for ( j=0; j<3; j++ )
|
||||
{
|
||||
if ( fabs(plane[j]) < 0.00025 && fabs(plane[(j+1)%3]) < 0.00025 && ( plane[j] != 0.0 || plane[(j+1)%3] != 0.0 ) ){
|
||||
VectorAdd( points[ 0 ], points[ 1 ], cnt );
|
||||
VectorAdd( cnt, points[ 2 ], cnt );
|
||||
VectorScale( cnt, 0.3333333333333f, cnt );
|
||||
points[0][(j+2)%3]=points[1][(j+2)%3]=points[2][(j+2)%3]=cnt[(j+2)%3];
|
||||
PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] );
|
||||
if ( fabs( plane.normal()[j] ) < 0.00025 && fabs( plane.normal()[(j+1)%3] ) < 0.00025
|
||||
&& ( plane.normal()[j] != 0.0 || plane.normal()[(j+1)%3] != 0.0 ) ){
|
||||
cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
points[0][(j+2)%3] = points[1][(j+2)%3] = points[2][(j+2)%3] = cnt[(j+2)%3];
|
||||
PlaneFromPoints( plane, points );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -668,25 +631,23 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
//snap single snappable normal components
|
||||
for ( j=0; j<3; j++ )
|
||||
{
|
||||
if ( plane[j] != 0.0 && fabs(plane[j]) < 0.00005 ){
|
||||
plane[j]=0.0;
|
||||
if ( plane.normal()[j] != 0.0 && fabs( plane.normal()[j] ) < 0.00005 ){
|
||||
plane.normal()[j]=0.0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
|
||||
//adjust plane dist
|
||||
if ( snpd ) {
|
||||
VectorAdd( points[ 0 ], points[ 1 ], cnt );
|
||||
VectorAdd( cnt, points[ 2 ], cnt );
|
||||
VectorScale( cnt, 0.3333333333333f, cnt );
|
||||
VectorNormalize( plane, plane );
|
||||
plane[3] = DotProduct( plane, cnt );
|
||||
cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
VectorNormalize( plane.normal() );
|
||||
plane.dist() = vector3_dot( plane.normal(), cnt );
|
||||
|
||||
//project points to resulting plane to keep intersections precision
|
||||
for ( j=0; j<3; j++ )
|
||||
{
|
||||
//Sys_Printf( "b4 %i (%6.7f %6.7f %6.7f)\n", j, points[j][0], points[j][1], points[j][2] );
|
||||
VectorMA( points[j], plane[3] - DotProduct( plane, points[j]), plane, points[j] );
|
||||
points[j] = plane3_project_point( plane, points[j] );
|
||||
//Sys_Printf( "sn %i (%6.7f %6.7f %6.7f)\n", j, points[j][0], points[j][1], points[j][2] );
|
||||
}
|
||||
//Sys_Printf( "sn pln (%6.7f %6.7f %6.7f %6.7f)\n", plane[0], plane[1], plane[2], plane[3] );
|
||||
@@ -696,15 +657,15 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
|
||||
/* sanity check */
|
||||
{
|
||||
vec3_t d1, d2, normaL;
|
||||
VectorSubtract( points[1], points[0], d1 );
|
||||
VectorSubtract( points[2], points[0], d2 );
|
||||
CrossProduct( d2, d1, normaL );
|
||||
const Vector3 d1 = points[1] - points[0];
|
||||
const Vector3 d2 = points[2] - points[0];
|
||||
const Vector3 normaL = vector3_cross( d2, d1 );
|
||||
/* https://en.wikipedia.org/wiki/Cross_product#Geometric_meaning
|
||||
cross( a, b ).length = a.length b.length sin( angle ) */
|
||||
const double lengthsSquared = ( d1[0] * d1[0] + d1[1] * d1[1] + d1[2] * d1[2] ) * ( d2[0] * d2[0] + d2[1] * d2[1] + d2[2] * d2[2] );
|
||||
if ( lengthsSquared == 0 || fabs( ( normaL[0] * normaL[0] + normaL[1] * normaL[1] + normaL[2] * normaL[2] ) / lengthsSquared ) < 1e-8 ) {
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped: points on line\n", points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
const double lengthsSquared = vector3_length_squared( d1 ) * vector3_length_squared( d2 );
|
||||
if ( lengthsSquared == 0 || fabs( vector3_length_squared( normaL ) / lengthsSquared ) < 1e-8 ) {
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped: points on line\n",
|
||||
points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -714,13 +675,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
|
||||
for ( j=0; j<3; j++ )
|
||||
{
|
||||
if ( fabs(plane[j]) < 0.05 && fabs(plane[(j+1)%3]) < 0.05 ){ //no way, close to lay on two axises
|
||||
if ( fabs( plane.normal()[j] ) < 0.05 && fabs( plane.normal()[(j+1)%3] ) < 0.05 ){ //no way, close to lay on two axes
|
||||
goto default_CLIPMODEL;
|
||||
}
|
||||
}
|
||||
|
||||
// best axial normal
|
||||
VectorCopy( plane, bestNormal );
|
||||
bestNormal = plane.normal();
|
||||
for ( j = 0; j < 3; j++ ){
|
||||
if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){
|
||||
bestNormal[(j+1)%3] = 0.0;
|
||||
@@ -730,7 +691,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
bestNormal[j] = 0.0;
|
||||
}
|
||||
}
|
||||
VectorNormalize( bestNormal, bestNormal );
|
||||
VectorNormalize( bestNormal );
|
||||
|
||||
|
||||
float bestdist, currdist, bestangle, currangle, mindist = 999999;
|
||||
@@ -738,13 +699,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
for ( j = 0; j < 3; j++ ){//planes
|
||||
bestdist = 999999;
|
||||
bestangle = 1;
|
||||
for ( k = 0; k < 3; k++ ){//axises
|
||||
VectorSubtract( points[ (j+1)%3 ], points[ j ], nrm );
|
||||
for ( k = 0; k < 3; k++ ){//axes
|
||||
nrm = points[(j+1)%3] - points[j];
|
||||
if ( k == axis ){
|
||||
CrossProduct( bestNormal, nrm, reverse );
|
||||
reverse.normal() = vector3_cross( bestNormal, nrm );
|
||||
}
|
||||
else{
|
||||
VectorClear( Vnorm[0] );
|
||||
Vnorm[0].set( 0 );
|
||||
if ( (k+1)%3 == axis ){
|
||||
if ( nrm[ (k+2)%3 ] == 0 ) continue;
|
||||
Vnorm[0][ (k+2)%3 ] = nrm[ (k+2)%3 ];
|
||||
@@ -753,20 +714,19 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
if ( nrm[ (k+1)%3 ] == 0 ) continue;
|
||||
Vnorm[0][ (k+1)%3 ] = nrm[ (k+1)%3 ];
|
||||
}
|
||||
CrossProduct( bestNormal, Vnorm[0], Enorm[0] );
|
||||
CrossProduct( Enorm[0], nrm, reverse );
|
||||
Enorm[0] = vector3_cross( bestNormal, Vnorm[0] );
|
||||
reverse.normal() = vector3_cross( Enorm[0], nrm );
|
||||
}
|
||||
VectorNormalize( reverse, reverse );
|
||||
reverse[3] = DotProduct( points[ j ], reverse );
|
||||
VectorNormalize( reverse.normal() );
|
||||
reverse.dist() = vector3_dot( points[ j ], reverse.normal() );
|
||||
//check facing, thickness
|
||||
currdist = reverse[3] - DotProduct( reverse, points[ (j+2)%3 ] );
|
||||
currangle = DotProduct( reverse, plane );
|
||||
currdist = reverse.dist() - vector3_dot( reverse.normal(), points[ (j+2)%3 ] );
|
||||
currangle = vector3_dot( reverse.normal(), plane.normal() );
|
||||
if ( ( ( currdist > 0.1 ) && ( currdist < bestdist ) && ( currangle < 0 ) ) ||
|
||||
( ( currangle >= 0 ) && ( currangle <= bestangle ) ) ){
|
||||
bestangle = currangle;
|
||||
if ( currangle < 0 ) bestdist = currdist;
|
||||
VectorCopy( reverse, p[j] );
|
||||
p[j][3] = reverse[3];
|
||||
p[j] = reverse;
|
||||
}
|
||||
}
|
||||
//if ( bestdist == 999999 && bestangle == 1 ) Sys_Printf("default_CLIPMODEL\n");
|
||||
@@ -800,12 +760,12 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
}
|
||||
|
||||
|
||||
@@ -824,22 +784,21 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
( spf == 5120 ) ){ //EXTRUDE_UPWARDS+AXIAL_BACKPLANE
|
||||
|
||||
if ( spawnFlags & 16 ){ //autodirection
|
||||
VectorCopy( avgDirection, bestNormal );
|
||||
bestNormal = avgDirection;
|
||||
}
|
||||
else{
|
||||
axis = 2;
|
||||
if ( ( spawnFlags & 1536 ) == 1536 ){ //up+down
|
||||
VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) );
|
||||
bestNormal = plane.normal()[2] >= 0? g_vector3_axis_z : -g_vector3_axis_z;
|
||||
}
|
||||
else if ( spawnFlags & 512 ){ //down
|
||||
VectorSet( bestNormal, 0, 0, 1 );
|
||||
|
||||
bestNormal = g_vector3_axis_z;
|
||||
}
|
||||
else if ( spawnFlags & 1024 ){ //up
|
||||
VectorSet( bestNormal, 0, 0, -1 );
|
||||
bestNormal = -g_vector3_axis_z;
|
||||
}
|
||||
else{ // best axial normal
|
||||
VectorCopy( plane, bestNormal );
|
||||
bestNormal = plane.normal();
|
||||
for ( j = 0; j < 3; j++ ){
|
||||
if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){
|
||||
bestNormal[(j+1)%3] = 0.0;
|
||||
@@ -849,11 +808,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
bestNormal[j] = 0.0;
|
||||
}
|
||||
}
|
||||
VectorNormalize( bestNormal, bestNormal );
|
||||
VectorNormalize( bestNormal );
|
||||
}
|
||||
}
|
||||
|
||||
if ( DotProduct( plane, bestNormal ) < 0.05 ){
|
||||
if ( vector3_dot( plane.normal(), bestNormal ) < 0.05 ){
|
||||
goto default_CLIPMODEL;
|
||||
}
|
||||
|
||||
@@ -861,69 +820,65 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
VectorSubtract( points[(j+1)%3], points[ j ], nrm );
|
||||
CrossProduct( bestNormal, nrm, p[ j ] );
|
||||
VectorNormalize( p[ j ], p[ j ] );
|
||||
p[j][3] = DotProduct( points[j], p[j] );
|
||||
p[j].normal() = VectorNormalized( vector3_cross( bestNormal, points[(j+1)%3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
if ( spawnFlags & 2048 ){ //max extrude
|
||||
VectorScale( bestNormal, -1.0f, reverse );
|
||||
reverse.normal() = -bestNormal;
|
||||
if ( bestNormal[axis] > 0 ){
|
||||
reverse[3] = -min[axis] + clipDepth;
|
||||
reverse.dist() = -minmax.mins[axis] + clipDepth;
|
||||
}
|
||||
else{
|
||||
reverse[3] = max[axis] + clipDepth;
|
||||
reverse.dist() = minmax.maxs[axis] + clipDepth;
|
||||
}
|
||||
}
|
||||
else if ( spawnFlags & 4096 ){ //axial backplane
|
||||
VectorScale( bestNormal, -1.0f, reverse );
|
||||
reverse[3] = points[0][axis];
|
||||
reverse.normal() = -bestNormal;
|
||||
reverse.dist() = points[0][axis];
|
||||
if ( bestNormal[axis] > 0 ){
|
||||
for ( j = 1; j < 3; j++ ){
|
||||
if ( points[j][axis] < reverse[3] ){
|
||||
reverse[3] = points[j][axis];
|
||||
if ( points[j][axis] < reverse.dist() ){
|
||||
reverse.dist() = points[j][axis];
|
||||
}
|
||||
}
|
||||
reverse[3] = -reverse[3] + clipDepth;
|
||||
reverse.dist() = -reverse.dist() + clipDepth;
|
||||
}
|
||||
else{
|
||||
for ( j = 1; j < 3; j++ ){
|
||||
if ( points[j][axis] > reverse[3] ){
|
||||
reverse[3] = points[j][axis];
|
||||
if ( points[j][axis] > reverse.dist() ){
|
||||
reverse.dist() = points[j][axis];
|
||||
}
|
||||
}
|
||||
reverse[3] += clipDepth;
|
||||
reverse.dist() += clipDepth;
|
||||
}
|
||||
if (limDepth != 0.0){
|
||||
VectorCopy( points[0], cnt );
|
||||
if ( limDepth != 0.0 ){
|
||||
cnt = points[0];
|
||||
if ( bestNormal[axis] > 0 ){
|
||||
for ( j = 1; j < 3; j++ ){
|
||||
if ( points[j][axis] > cnt[axis] ){
|
||||
VectorCopy( points[j], cnt );
|
||||
cnt = points[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( j = 1; j < 3; j++ ){
|
||||
if ( points[j][axis] < cnt[axis] ){
|
||||
VectorCopy( points[j], cnt );
|
||||
cnt = points[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
VectorMA( cnt, reverse[3] - DotProduct( reverse, cnt ), reverse, cnt );
|
||||
if ( ( plane[3] - DotProduct( plane, cnt ) ) > limDepth ){
|
||||
VectorScale( plane, -1.0f, reverse );
|
||||
reverse[ 3 ] = -plane[ 3 ];
|
||||
reverse[3] += clipDepth;
|
||||
cnt = plane3_project_point( reverse, cnt );
|
||||
if ( -plane3_distance_to_point( plane, cnt ) > limDepth ){
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{ //normal backplane
|
||||
VectorScale( plane, -1.0f, reverse );
|
||||
reverse[ 3 ] = -plane[ 3 ];
|
||||
reverse[3] += clipDepth;
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
}
|
||||
#if nonax_clip_dbg
|
||||
for ( j = 0; j < 3; j++ )
|
||||
@@ -949,13 +904,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
@@ -964,36 +919,31 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
//45 degrees normals for side planes
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
VectorSubtract( points[(j+1)%3], points[ j ], nrm );
|
||||
CrossProduct( plane, nrm, Enorm[ j ] );
|
||||
VectorNormalize( Enorm[ j ], Enorm[ j ] );
|
||||
VectorAdd( plane, Enorm[ j ], Enorm[ j ] );
|
||||
VectorNormalize( Enorm[ j ], Enorm[ j ] );
|
||||
nrm = points[(j+1)%3] - points[ j ];
|
||||
Enorm[ j ] = VectorNormalized( vector3_cross( plane.normal(), nrm ) );
|
||||
Enorm[ j ] += plane.normal();
|
||||
VectorNormalize( Enorm[ j ] );
|
||||
/* make side planes */
|
||||
CrossProduct( Enorm[ j ], nrm, p[ j ] );
|
||||
VectorNormalize( p[ j ], p[ j ] );
|
||||
p[j][3] = DotProduct( points[j], p[j] );
|
||||
p[j].normal() = VectorNormalized( vector3_cross( Enorm[ j ], nrm ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
//snap nearly axial side planes
|
||||
snpd = false;
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
|
||||
p[j][k] = 0.0;
|
||||
if ( fabs( p[j].normal()[k] ) < 0.00025 && p[j].normal()[k] != 0.0 ){
|
||||
p[j].normal()[k] = 0.0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
if ( snpd ){
|
||||
VectorNormalize( p[j], p[j] );
|
||||
VectorAdd( points[j], points[(j+1)%3], cnt );
|
||||
VectorScale( cnt, 0.5f, cnt );
|
||||
p[j][3] = DotProduct( cnt, p[j] );
|
||||
VectorNormalize( p[j].normal() );
|
||||
p[j].dist() = vector3_dot( ( points[j] + points[(j+1)%3] ) / 2.0, p[j].normal() );
|
||||
}
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
VectorScale( plane, -1.0f, reverse );
|
||||
reverse[ 3 ] = -plane[ 3 ];
|
||||
reverse[3] += clipDepth;
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
@@ -1008,13 +958,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
@@ -1026,21 +976,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
/* get vertex */
|
||||
dv = &ds->verts[ ds->indexes[ i + j ] ];
|
||||
/* copy normal */
|
||||
VectorCopy( dv->normal, Vnorm[ j ] );
|
||||
Vnorm[ j ] = dv->normal;
|
||||
}
|
||||
|
||||
//avg normals for side planes
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
VectorAdd( Vnorm[ j ], Vnorm[ (j+1)%3 ], Enorm[ j ] );
|
||||
VectorNormalize( Enorm[ j ], Enorm[ j ] );
|
||||
Enorm[ j ] = VectorNormalized( Vnorm[ j ] + Vnorm[ (j+1)%3 ] );
|
||||
//check fuer bad ones
|
||||
VectorSubtract( points[(j+1)%3], points[ j ], cnt );
|
||||
CrossProduct( plane, cnt, nrm );
|
||||
VectorNormalize( nrm, nrm );
|
||||
nrm = VectorNormalized( vector3_cross( plane.normal(), points[(j+1)%3] - points[ j ] ) );
|
||||
//check for negative or outside direction
|
||||
if ( DotProduct( Enorm[ j ], plane ) > 0.1 ){
|
||||
if ( ( DotProduct( Enorm[ j ], nrm ) > -0.2 ) || ( spawnFlags & 256 ) ){
|
||||
if ( vector3_dot( Enorm[ j ], plane.normal() ) > 0.1 ){
|
||||
if ( ( vector3_dot( Enorm[ j ], nrm ) > -0.2 ) || ( spawnFlags & 256 ) ){
|
||||
//ok++;
|
||||
continue;
|
||||
}
|
||||
@@ -1048,41 +995,36 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
//notok++;
|
||||
//Sys_Printf( "faulty Enormal %i/%i\n", notok, ok );
|
||||
//use 45 normal
|
||||
VectorAdd( plane, nrm, Enorm[ j ] );
|
||||
VectorNormalize( Enorm[ j ], Enorm[ j ] );
|
||||
Enorm[ j ] = plane.normal() + nrm;
|
||||
VectorNormalize( Enorm[ j ] );
|
||||
}
|
||||
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
VectorSubtract( points[(j+1)%3], points[ j ], nrm );
|
||||
CrossProduct( Enorm[ j ], nrm, p[ j ] );
|
||||
VectorNormalize( p[ j ], p[ j ] );
|
||||
p[j][3] = DotProduct( points[j], p[j] );
|
||||
p[j].normal() = VectorNormalized( vector3_cross( Enorm[ j ], points[(j+1)%3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
//snap nearly axial side planes
|
||||
snpd = false;
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
|
||||
if ( fabs( p[j].normal()[k] ) < 0.00025 && p[j].normal()[k] != 0.0 ){
|
||||
//Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
|
||||
p[j][k] = 0.0;
|
||||
p[j].normal()[k] = 0.0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
if ( snpd ){
|
||||
VectorNormalize( p[j], p[j] );
|
||||
VectorNormalize( p[j].normal() );
|
||||
//Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
|
||||
VectorAdd( points[j], points[(j+1)%3], cnt );
|
||||
VectorScale( cnt, 0.5f, cnt );
|
||||
p[j][3] = DotProduct( cnt, p[j] );
|
||||
p[j].dist() = vector3_dot( ( points[j] + points[(j+1)%3] ) / 2.0, p[j].normal() );
|
||||
//Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
|
||||
}
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
VectorScale( plane, -1.0f, reverse );
|
||||
reverse[ 3 ] = -plane[ 3 ];
|
||||
reverse[3] += clipDepth;
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
@@ -1097,13 +1039,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
@@ -1112,34 +1054,30 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
VectorSubtract( points[(j+1)%3], points[ j ], nrm );
|
||||
CrossProduct( plane, nrm, p[ j ] );
|
||||
VectorNormalize( p[ j ], p[ j ] );
|
||||
p[j][3] = DotProduct( points[j], p[j] );
|
||||
p[j].normal() = VectorNormalized( vector3_cross( plane.normal(), points[(j+1)%3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
//snap nearly axial side planes
|
||||
snpd = false;
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
|
||||
if ( fabs( p[j].normal()[k] ) < 0.00025 && p[j].normal()[k] != 0.0 ){
|
||||
//Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
|
||||
p[j][k] = 0.0;
|
||||
p[j].normal()[k] = 0.0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
if ( snpd ){
|
||||
VectorNormalize( p[j], p[j] );
|
||||
VectorNormalize( p[j].normal() );
|
||||
//Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
|
||||
VectorAdd( points[j], points[(j+1)%3], cnt );
|
||||
VectorScale( cnt, 0.5f, cnt );
|
||||
p[j][3] = DotProduct( cnt, p[j] );
|
||||
cnt = ( points[j] + points[(j+1)%3] ) / 2.0;
|
||||
p[j].dist() = vector3_dot( cnt, p[j].normal() );
|
||||
//Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
|
||||
}
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
VectorScale( plane, -1.0f, reverse );
|
||||
reverse[ 3 ] = -plane[ 3 ];
|
||||
reverse[3] += clipDepth;
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
#if nonax_clip_dbg
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
@@ -1165,25 +1103,23 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
else if ( spf == 256 ){ //PYRAMIDAL_CLIP
|
||||
|
||||
/* calculate center */
|
||||
VectorAdd( points[ 0 ], points[ 1 ], cnt );
|
||||
VectorAdd( cnt, points[ 2 ], cnt );
|
||||
VectorScale( cnt, 0.3333333333333f, cnt );
|
||||
cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
|
||||
/* make back pyramid point */
|
||||
VectorMA( cnt, -clipDepth, plane, cnt );
|
||||
cnt -= plane.normal() * clipDepth;
|
||||
|
||||
/* make 3 more planes */
|
||||
if( PlaneFromPoints( p[0], points[ 2 ], points[ 1 ], cnt ) &&
|
||||
@@ -1191,16 +1127,16 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
PlaneFromPoints( p[2], points[ 0 ], points[ 2 ], cnt ) ) {
|
||||
|
||||
//check for dangerous planes
|
||||
while( (( p[0][0] != 0.0 || p[0][1] != 0.0 ) && fabs(p[0][0]) < 0.00025 && fabs(p[0][1]) < 0.00025) ||
|
||||
(( p[0][0] != 0.0 || p[0][2] != 0.0 ) && fabs(p[0][0]) < 0.00025 && fabs(p[0][2]) < 0.00025) ||
|
||||
(( p[0][2] != 0.0 || p[0][1] != 0.0 ) && fabs(p[0][2]) < 0.00025 && fabs(p[0][1]) < 0.00025) ||
|
||||
(( p[1][0] != 0.0 || p[1][1] != 0.0 ) && fabs(p[1][0]) < 0.00025 && fabs(p[1][1]) < 0.00025) ||
|
||||
(( p[1][0] != 0.0 || p[1][2] != 0.0 ) && fabs(p[1][0]) < 0.00025 && fabs(p[1][2]) < 0.00025) ||
|
||||
(( p[1][2] != 0.0 || p[1][1] != 0.0 ) && fabs(p[1][2]) < 0.00025 && fabs(p[1][1]) < 0.00025) ||
|
||||
(( p[2][0] != 0.0 || p[2][1] != 0.0 ) && fabs(p[2][0]) < 0.00025 && fabs(p[2][1]) < 0.00025) ||
|
||||
(( p[2][0] != 0.0 || p[2][2] != 0.0 ) && fabs(p[2][0]) < 0.00025 && fabs(p[2][2]) < 0.00025) ||
|
||||
(( p[2][2] != 0.0 || p[2][1] != 0.0 ) && fabs(p[2][2]) < 0.00025 && fabs(p[2][1]) < 0.00025) ) {
|
||||
VectorMA( cnt, -0.1f, plane, cnt );
|
||||
while( (( p[0].a != 0.0 || p[0].b != 0.0 ) && fabs( p[0].a ) < 0.00025 && fabs( p[0].b ) < 0.00025) ||
|
||||
(( p[0].a != 0.0 || p[0].c != 0.0 ) && fabs( p[0].a ) < 0.00025 && fabs( p[0].c ) < 0.00025) ||
|
||||
(( p[0].c != 0.0 || p[0].b != 0.0 ) && fabs( p[0].c ) < 0.00025 && fabs( p[0].b ) < 0.00025) ||
|
||||
(( p[1].a != 0.0 || p[1].b != 0.0 ) && fabs( p[1].a ) < 0.00025 && fabs( p[1].b ) < 0.00025) ||
|
||||
(( p[1].a != 0.0 || p[1].c != 0.0 ) && fabs( p[1].a ) < 0.00025 && fabs( p[1].c ) < 0.00025) ||
|
||||
(( p[1].c != 0.0 || p[1].b != 0.0 ) && fabs( p[1].c ) < 0.00025 && fabs( p[1].b ) < 0.00025) ||
|
||||
(( p[2].a != 0.0 || p[2].b != 0.0 ) && fabs( p[2].a ) < 0.00025 && fabs( p[2].b ) < 0.00025) ||
|
||||
(( p[2].a != 0.0 || p[2].c != 0.0 ) && fabs( p[2].a ) < 0.00025 && fabs( p[2].c ) < 0.00025) ||
|
||||
(( p[2].c != 0.0 || p[2].b != 0.0 ) && fabs( p[2].c ) < 0.00025 && fabs( p[2].b ) < 0.00025) ) {
|
||||
cnt -= plane.normal() * 0.1f;
|
||||
// Sys_Printf( "shifting pyramid point\n" );
|
||||
PlaneFromPoints( p[0], points[ 2 ], points[ 1 ], cnt );
|
||||
PlaneFromPoints( p[1], points[ 1 ], points[ 0 ], cnt );
|
||||
@@ -1230,16 +1166,17 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n", points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n",
|
||||
points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
free( buildBrush );
|
||||
continue;
|
||||
}
|
||||
@@ -1250,7 +1187,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
|
||||
default_CLIPMODEL:
|
||||
// axial normal
|
||||
VectorCopy( plane, bestNormal );
|
||||
bestNormal = plane.normal();
|
||||
for ( j = 0; j < 3; j++ ){
|
||||
if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){
|
||||
bestNormal[(j+1)%3] = 0.0;
|
||||
@@ -1259,21 +1196,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
bestNormal[j] = 0.0;
|
||||
}
|
||||
}
|
||||
VectorNormalize( bestNormal, bestNormal );
|
||||
VectorNormalize( bestNormal );
|
||||
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
VectorSubtract( points[(j+1)%3], points[ j ], nrm );
|
||||
CrossProduct( bestNormal, nrm, p[ j ] );
|
||||
VectorNormalize( p[ j ], p[ j ] );
|
||||
p[j][3] = DotProduct( points[j], p[j] );
|
||||
p[j].normal() = VectorNormalized( vector3_cross( bestNormal, points[(j+1)%3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
VectorScale( plane, -1.0f, reverse );
|
||||
reverse[ 3 ] = -plane[ 3 ];
|
||||
reverse[3] += DotProduct( bestNormal, plane ) * clipDepth;
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += vector3_dot( bestNormal, plane.normal() ) * clipDepth;
|
||||
#if nonax_clip_dbg
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
@@ -1298,13 +1232,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
VectorCopy( points[0], points[3] ); // for cyclic usage
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
@@ -1317,7 +1251,8 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const
|
||||
entities[ mapEntityNum ].numBrushes++;
|
||||
}
|
||||
else{
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n", points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n",
|
||||
points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
free( buildBrush );
|
||||
}
|
||||
}
|
||||
@@ -1395,27 +1330,26 @@ void AddTriangleModels( entity_t *eparent ){
|
||||
const int spawnFlags = e->intForKey( "spawnflags" );
|
||||
|
||||
/* get origin */
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
e->vectorForKey( "origin", origin );
|
||||
VectorSubtract( origin, eparent->origin, origin ); /* offset by parent */
|
||||
origin -= eparent->origin; /* offset by parent */
|
||||
|
||||
/* get scale */
|
||||
vec3_t scale = { 1.f, 1.f, 1.f };
|
||||
Vector3 scale( 1, 1, 1 );
|
||||
if( !e->read_keyvalue( scale, "modelscale_vec" ) )
|
||||
if( e->read_keyvalue( scale[0], "modelscale" ) )
|
||||
scale[1] = scale[2] = scale[0];
|
||||
|
||||
/* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */
|
||||
const char *value;
|
||||
vec3_t angles = { 0.f, 0.f, 0.f };
|
||||
Vector3 angles( 0, 0, 0 );
|
||||
if ( !e->read_keyvalue( value, "angles" ) ||
|
||||
3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) )
|
||||
e->read_keyvalue( angles[ 2 ], "angle" );
|
||||
|
||||
/* set transform matrix (thanks spog) */
|
||||
m4x4_t transform;
|
||||
m4x4_identity( transform );
|
||||
m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin );
|
||||
Matrix4 transform( g_matrix4_identity );
|
||||
matrix4_transform_by_euler_xyz_degrees( transform, origin, angles, scale );
|
||||
|
||||
/* get shader remappings */
|
||||
std::list<remap_t> remaps;
|
||||
|
||||
@@ -40,51 +40,49 @@
|
||||
|
||||
#define APPROX_SUBDIVISION 8
|
||||
|
||||
static void ExpandLongestCurve( float *longestCurve, vec3_t a, vec3_t b, vec3_t c ){
|
||||
static void ExpandLongestCurve( float *longestCurve, const Vector3& a, const Vector3& b, const Vector3& c ){
|
||||
int i;
|
||||
float t, len;
|
||||
vec3_t ab, bc, ac, pt, last, delta;
|
||||
Vector3 ab, bc, ac, pt, last, delta;
|
||||
|
||||
|
||||
/* calc vectors */
|
||||
VectorSubtract( b, a, ab );
|
||||
if ( VectorNormalize( ab, ab ) < 0.125f ) {
|
||||
ab = b - a;
|
||||
if ( VectorNormalize( ab ) < 0.125f ) {
|
||||
return;
|
||||
}
|
||||
VectorSubtract( c, b, bc );
|
||||
if ( VectorNormalize( bc, bc ) < 0.125f ) {
|
||||
bc = c - b;
|
||||
if ( VectorNormalize( bc ) < 0.125f ) {
|
||||
return;
|
||||
}
|
||||
VectorSubtract( c, a, ac );
|
||||
if ( VectorNormalize( ac, ac ) < 0.125f ) {
|
||||
ac = c - a;
|
||||
if ( VectorNormalize( ac ) < 0.125f ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if all 3 vectors are the same direction, then this edge is linear, so we ignore it */
|
||||
if ( DotProduct( ab, bc ) > 0.99f && DotProduct( ab, ac ) > 0.99f ) {
|
||||
if ( vector3_dot( ab, bc ) > 0.99f && vector3_dot( ab, ac ) > 0.99f ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* recalculate vectors */
|
||||
VectorSubtract( b, a, ab );
|
||||
VectorSubtract( c, b, bc );
|
||||
ab = b - a;
|
||||
bc = c - b;
|
||||
|
||||
/* determine length */
|
||||
VectorCopy( a, last );
|
||||
last = a;
|
||||
for ( i = 0, len = 0.0f, t = 0.0f; i < APPROX_SUBDIVISION; i++, t += ( 1.0f / APPROX_SUBDIVISION ) )
|
||||
{
|
||||
/* calculate delta */
|
||||
delta[ 0 ] = ( ( 1.0f - t ) * ab[ 0 ] ) + ( t * bc[ 0 ] );
|
||||
delta[ 1 ] = ( ( 1.0f - t ) * ab[ 1 ] ) + ( t * bc[ 1 ] );
|
||||
delta[ 2 ] = ( ( 1.0f - t ) * ab[ 2 ] ) + ( t * bc[ 2 ] );
|
||||
delta = ab * ( 1.0f - t ) + bc * t;
|
||||
|
||||
/* add to first point and calculate pt-pt delta */
|
||||
VectorAdd( a, delta, pt );
|
||||
VectorSubtract( pt, last, delta );
|
||||
pt = a + delta;
|
||||
delta = pt - last;
|
||||
|
||||
/* add it to length and store last point */
|
||||
len += VectorLength( delta );
|
||||
VectorCopy( pt, last );
|
||||
len += vector3_length( delta );
|
||||
last = pt;
|
||||
}
|
||||
|
||||
/* longer? */
|
||||
@@ -100,19 +98,18 @@ static void ExpandLongestCurve( float *longestCurve, vec3_t a, vec3_t b, vec3_t
|
||||
determines how many iterations a quadratic curve needs to be subdivided with to fit the specified error
|
||||
*/
|
||||
|
||||
static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec3_t b, vec3_t c ){
|
||||
static void ExpandMaxIterations( int *maxIterations, int maxError, const Vector3& a, const Vector3& b, const Vector3& c ){
|
||||
int i, j;
|
||||
vec3_t prev, next, mid, delta, delta2;
|
||||
float len, len2;
|
||||
Vector3 prev, next, mid;
|
||||
int numPoints, iterations;
|
||||
vec3_t points[ MAX_EXPANDED_AXIS ];
|
||||
Vector3 points[ MAX_EXPANDED_AXIS ];
|
||||
|
||||
|
||||
/* initial setup */
|
||||
numPoints = 3;
|
||||
VectorCopy( a, points[ 0 ] );
|
||||
VectorCopy( b, points[ 1 ] );
|
||||
VectorCopy( c, points[ 2 ] );
|
||||
points[ 0 ] = a;
|
||||
points[ 1 ] = b;
|
||||
points[ 2 ] = c;
|
||||
|
||||
/* subdivide */
|
||||
for ( i = 0; i + 2 < numPoints; i += 2 )
|
||||
@@ -123,17 +120,12 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec
|
||||
}
|
||||
|
||||
/* calculate new curve deltas */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
prev[ j ] = points[ i + 1 ][ j ] - points[ i ][ j ];
|
||||
next[ j ] = points[ i + 2 ][ j ] - points[ i + 1 ][ j ];
|
||||
mid[ j ] = ( points[ i ][ j ] + points[ i + 1 ][ j ] * 2.0f + points[ i + 2 ][ j ] ) * 0.25f;
|
||||
}
|
||||
prev = points[ i + 1 ] - points[ i ];
|
||||
next = points[ i + 2 ] - points[ i + 1 ];
|
||||
mid = ( points[ i ] + points[ i + 1 ] * 2.0f + points[ i + 2 ] ) * 0.25f;
|
||||
|
||||
/* see if this midpoint is off far enough to subdivide */
|
||||
VectorSubtract( points[ i + 1 ], mid, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len < maxError ) {
|
||||
if ( vector3_length( points[ i + 1 ] - mid ) < maxError ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -141,21 +133,18 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec
|
||||
numPoints += 2;
|
||||
|
||||
/* create new points */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
prev[ j ] = 0.5f * ( points[ i ][ j ] + points[ i + 1 ][ j ] );
|
||||
next[ j ] = 0.5f * ( points[ i + 1 ][ j ] + points[ i + 2 ][ j ] );
|
||||
mid[ j ] = 0.5f * ( prev[ j ] + next[ j ] );
|
||||
}
|
||||
prev = ( points[ i ] + points[ i + 1 ] ) * 0.5f;
|
||||
next = ( points[ i + 1 ] + points[ i + 2 ] ) * 0.5f;
|
||||
mid = ( prev + next ) * 0.5f;
|
||||
|
||||
/* push points out */
|
||||
for ( j = numPoints - 1; j > i + 3; j-- )
|
||||
VectorCopy( points[ j - 2 ], points[ j ] );
|
||||
points[ j ] = points[ j - 2 ];
|
||||
|
||||
/* insert new points */
|
||||
VectorCopy( prev, points[ i + 1 ] );
|
||||
VectorCopy( mid, points[ i + 2 ] );
|
||||
VectorCopy( next, points[ i + 3 ] );
|
||||
points[ i + 1 ] = prev;
|
||||
points[ i + 2 ] = mid;
|
||||
points[ i + 3 ] = next;
|
||||
|
||||
/* back up and recheck this set again, it may need more subdivision */
|
||||
i -= 2;
|
||||
@@ -164,27 +153,24 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec
|
||||
/* put the line on the curve */
|
||||
for ( i = 1; i < numPoints; i += 2 )
|
||||
{
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
prev[ j ] = 0.5f * ( points[ i ][ j ] + points[ i + 1 ][ j ] );
|
||||
next[ j ] = 0.5f * ( points[ i ][ j ] + points[ i - 1 ][ j ] );
|
||||
points[ i ][ j ] = 0.5f * ( prev[ j ] + next[ j ] );
|
||||
}
|
||||
prev = ( points[ i ] + points[ i + 1 ] ) * 0.5f;
|
||||
next = ( points[ i ] + points[ i - 1 ] ) * 0.5f;
|
||||
points[ i ] = ( prev + next ) * 0.5f;
|
||||
}
|
||||
|
||||
/* eliminate linear sections */
|
||||
for ( i = 0; i + 2 < numPoints; i++ )
|
||||
{
|
||||
/* create vectors */
|
||||
VectorSubtract( points[ i + 1 ], points[ i ], delta );
|
||||
len = VectorNormalize( delta, delta );
|
||||
VectorSubtract( points[ i + 2 ], points[ i + 1 ], delta2 );
|
||||
len2 = VectorNormalize( delta2, delta2 );
|
||||
Vector3 delta = points[ i + 1 ] - points[ i ];
|
||||
const float len = VectorNormalize( delta );
|
||||
Vector3 delta2 = points[ i + 2 ] - points[ i + 1 ];
|
||||
const float len2 = VectorNormalize( delta2 );
|
||||
|
||||
/* if either edge is degenerate, then eliminate it */
|
||||
if ( len < 0.0625f || len2 < 0.0625f || DotProduct( delta, delta2 ) >= 1.0f ) {
|
||||
if ( len < 0.0625f || len2 < 0.0625f || vector3_dot( delta, delta2 ) >= 1.0f ) {
|
||||
for ( j = i + 1; j + 1 < numPoints; j++ )
|
||||
VectorCopy( points[ j + 1 ], points[ j ] );
|
||||
points[ j ] = points[ j + 1 ];
|
||||
numPoints--;
|
||||
continue;
|
||||
}
|
||||
@@ -213,12 +199,11 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec
|
||||
*/
|
||||
|
||||
void ParsePatch( bool onlyLights ){
|
||||
vec_t info[ 5 ];
|
||||
float info[ 5 ];
|
||||
int i, j, k;
|
||||
parseMesh_t *pm;
|
||||
mesh_t m;
|
||||
bspDrawVert_t *verts;
|
||||
vec4_t delta, delta2, delta3;
|
||||
bool degenerate;
|
||||
float longestCurve;
|
||||
int maxIterations;
|
||||
@@ -244,15 +229,12 @@ void ParsePatch( bool onlyLights ){
|
||||
MatchToken( "(" );
|
||||
for ( i = 0; i < m.height ; i++ )
|
||||
{
|
||||
Parse1DMatrix( 5, verts[ i * m.width + j ].xyz );
|
||||
Parse1DMatrix( 5, verts[ i * m.width + j ].xyz.data() );
|
||||
|
||||
/* ydnar: fix colors */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
verts[ i * m.width + j ].color[ k ][ 0 ] = 255;
|
||||
verts[ i * m.width + j ].color[ k ][ 1 ] = 255;
|
||||
verts[ i * m.width + j ].color[ k ][ 2 ] = 255;
|
||||
verts[ i * m.width + j ].color[ k ][ 3 ] = 255;
|
||||
verts[ i * m.width + j ].color[ k ].set( 255 );
|
||||
}
|
||||
}
|
||||
MatchToken( ")" );
|
||||
@@ -280,15 +262,14 @@ void ParsePatch( bool onlyLights ){
|
||||
|
||||
/* ydnar: delete and warn about degenerate patches */
|
||||
j = ( m.width * m.height );
|
||||
VectorClear( delta );
|
||||
delta[ 3 ] = 0;
|
||||
Vector4 delta( 0, 0, 0, 0 );
|
||||
degenerate = true;
|
||||
|
||||
/* find first valid vector */
|
||||
for ( i = 1; i < j && delta[ 3 ] == 0; i++ )
|
||||
{
|
||||
VectorSubtract( m.verts[ 0 ].xyz, m.verts[ i ].xyz, delta );
|
||||
delta[ 3 ] = VectorNormalize( delta, delta );
|
||||
delta.vec3() = m.verts[ 0 ].xyz - m.verts[ i ].xyz;
|
||||
delta[ 3 ] = VectorNormalize( delta.vec3() );
|
||||
}
|
||||
|
||||
/* secondary degenerate test */
|
||||
@@ -300,16 +281,15 @@ void ParsePatch( bool onlyLights ){
|
||||
/* if all vectors match this or are zero, then this is a degenerate patch */
|
||||
for ( i = 1; i < j && degenerate; i++ )
|
||||
{
|
||||
VectorSubtract( m.verts[ 0 ].xyz, m.verts[ i ].xyz, delta2 );
|
||||
delta2[ 3 ] = VectorNormalize( delta2, delta2 );
|
||||
Vector4 delta2( m.verts[ 0 ].xyz - m.verts[ i ].xyz, 0 );
|
||||
delta2[ 3 ] = VectorNormalize( delta2.vec3() );
|
||||
if ( delta2[ 3 ] != 0 ) {
|
||||
/* create inverse vector */
|
||||
VectorCopy( delta2, delta3 );
|
||||
delta3[ 3 ] = delta2[ 3 ];
|
||||
VectorInverse( delta3 );
|
||||
Vector4 delta3( delta2 );
|
||||
vector3_negate( delta3.vec3() );
|
||||
|
||||
/* compare */
|
||||
if ( !VectorCompare( delta, delta2 ) && !VectorCompare( delta, delta3 ) ) {
|
||||
if ( !VectorCompare( delta.vec3(), delta2.vec3() ) && !VectorCompare( delta.vec3(), delta3.vec3() ) ) {
|
||||
degenerate = false;
|
||||
}
|
||||
}
|
||||
@@ -413,7 +393,7 @@ void PatchMapDrawSurfs( entity_t *e ){
|
||||
mapDrawSurface_t *ds;
|
||||
int patchCount, groupCount;
|
||||
bspDrawVert_t *v1, *v2;
|
||||
vec3_t bounds[ 2 ];
|
||||
MinMax bounds;
|
||||
byte *bordering;
|
||||
|
||||
parseMesh_t *meshes[ MAX_MAP_DRAW_SURFS ];
|
||||
@@ -491,7 +471,8 @@ void PatchMapDrawSurfs( entity_t *e ){
|
||||
GrowGroup_r( scan, i, patchCount, meshes, bordering, group );
|
||||
|
||||
/* bound them */
|
||||
ClearBounds( bounds[ 0 ], bounds[ 1 ] );
|
||||
|
||||
bounds.clear();
|
||||
for ( j = 0; j < patchCount; j++ )
|
||||
{
|
||||
if ( group[ j ] ) {
|
||||
@@ -500,7 +481,7 @@ void PatchMapDrawSurfs( entity_t *e ){
|
||||
c1 = check->mesh.width * check->mesh.height;
|
||||
v1 = check->mesh.verts;
|
||||
for ( k = 0; k < c1; k++, v1++ )
|
||||
AddPointToBounds( v1->xyz, bounds[ 0 ], bounds[ 1 ] );
|
||||
bounds.extend( v1->xyz );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,8 +491,7 @@ void PatchMapDrawSurfs( entity_t *e ){
|
||||
/* create drawsurf */
|
||||
scan->grouped = true;
|
||||
ds = DrawSurfaceForMesh( e, scan, NULL ); /* ydnar */
|
||||
VectorCopy( bounds[ 0 ], ds->bounds[ 0 ] );
|
||||
VectorCopy( bounds[ 1 ], ds->bounds[ 1 ] );
|
||||
ds->bounds = bounds;
|
||||
}
|
||||
|
||||
/* emit some statistics */
|
||||
|
||||
@@ -175,10 +175,10 @@ void PrintPortal( portal_t *p ){
|
||||
*/
|
||||
#define SIDESPACE 8
|
||||
void MakeHeadnodePortals( tree_t *tree ){
|
||||
vec3_t bounds[2];
|
||||
Vector3 bounds[2];
|
||||
int i, j, n;
|
||||
portal_t *p, *portals[6];
|
||||
plane_t bplanes[6], *pl;
|
||||
plane_t bplanes[6];
|
||||
node_t *node;
|
||||
|
||||
node = tree->headnode;
|
||||
@@ -186,8 +186,8 @@ void MakeHeadnodePortals( tree_t *tree ){
|
||||
// pad with some space so there will never be null volume leafs
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
bounds[0][i] = tree->mins[i] - SIDESPACE;
|
||||
bounds[1][i] = tree->maxs[i] + SIDESPACE;
|
||||
bounds[0][i] = tree->minmax.mins[i] - SIDESPACE;
|
||||
bounds[1][i] = tree->minmax.maxs[i] + SIDESPACE;
|
||||
if ( bounds[0][i] >= bounds[1][i] ) {
|
||||
Error( "Backwards tree volume" );
|
||||
}
|
||||
@@ -206,19 +206,19 @@ void MakeHeadnodePortals( tree_t *tree ){
|
||||
p = AllocPortal();
|
||||
portals[n] = p;
|
||||
|
||||
pl = &bplanes[n];
|
||||
plane_t *pl = &bplanes[n];
|
||||
memset( pl, 0, sizeof( *pl ) );
|
||||
if ( j ) {
|
||||
pl->normal[i] = -1;
|
||||
pl->dist = -bounds[j][i];
|
||||
pl->normal()[i] = -1;
|
||||
pl->dist() = -bounds[j][i];
|
||||
}
|
||||
else
|
||||
{
|
||||
pl->normal[i] = 1;
|
||||
pl->dist = bounds[j][i];
|
||||
pl->normal()[i] = 1;
|
||||
pl->dist() = bounds[j][i];
|
||||
}
|
||||
p->plane = *pl;
|
||||
p->winding = BaseWindingForPlane( pl->normal, pl->dist );
|
||||
p->winding = BaseWindingForPlane( pl->plane );
|
||||
AddPortalToNodes( p, node, &tree->outside_node );
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ void MakeHeadnodePortals( tree_t *tree ){
|
||||
if ( j == i ) {
|
||||
continue;
|
||||
}
|
||||
ChopWindingInPlace( &portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON );
|
||||
ChopWindingInPlace( &portals[i]->winding, bplanes[j].plane, ON_EPSILON );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,26 +249,20 @@ void MakeHeadnodePortals( tree_t *tree ){
|
||||
winding_t *BaseWindingForNode( node_t *node ){
|
||||
winding_t *w;
|
||||
node_t *n;
|
||||
plane_t *plane;
|
||||
vec3_t normal;
|
||||
vec_t dist;
|
||||
|
||||
w = BaseWindingForPlane( mapplanes[node->planenum].normal
|
||||
, mapplanes[node->planenum].dist );
|
||||
w = BaseWindingForPlane( mapplanes[node->planenum].plane );
|
||||
|
||||
// clip by all the parents
|
||||
for ( n = node->parent ; n && w ; )
|
||||
{
|
||||
plane = &mapplanes[n->planenum];
|
||||
const plane_t& plane = mapplanes[n->planenum];
|
||||
|
||||
if ( n->children[0] == node ) { // take front
|
||||
ChopWindingInPlace( &w, plane->normal, plane->dist, BASE_WINDING_EPSILON );
|
||||
ChopWindingInPlace( &w, plane.plane, BASE_WINDING_EPSILON );
|
||||
}
|
||||
else
|
||||
{ // take back
|
||||
VectorSubtract( vec3_origin, plane->normal, normal );
|
||||
dist = -plane->dist;
|
||||
ChopWindingInPlace( &w, normal, dist, BASE_WINDING_EPSILON );
|
||||
ChopWindingInPlace( &w, plane3_flipped( plane.plane ), BASE_WINDING_EPSILON );
|
||||
}
|
||||
node = n;
|
||||
n = n->parent;
|
||||
@@ -290,8 +284,6 @@ winding_t *BaseWindingForNode( node_t *node ){
|
||||
void MakeNodePortal( node_t *node ){
|
||||
portal_t *new_portal, *p;
|
||||
winding_t *w;
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
int side;
|
||||
|
||||
w = BaseWindingForNode( node );
|
||||
@@ -301,19 +293,16 @@ void MakeNodePortal( node_t *node ){
|
||||
{
|
||||
if ( p->nodes[0] == node ) {
|
||||
side = 0;
|
||||
VectorCopy( p->plane.normal, normal );
|
||||
dist = p->plane.dist;
|
||||
ChopWindingInPlace( &w, p->plane.plane, CLIP_EPSILON );
|
||||
}
|
||||
else if ( p->nodes[1] == node ) {
|
||||
side = 1;
|
||||
VectorSubtract( vec3_origin, p->plane.normal, normal );
|
||||
dist = -p->plane.dist;
|
||||
ChopWindingInPlace( &w, plane3_flipped( p->plane.plane ), CLIP_EPSILON );
|
||||
}
|
||||
else{
|
||||
Error( "CutNodePortals_r: mislinked portal" );
|
||||
}
|
||||
|
||||
ChopWindingInPlace( &w, normal, dist, CLIP_EPSILON );
|
||||
}
|
||||
|
||||
if ( !w ) {
|
||||
@@ -357,10 +346,9 @@ void SplitNodePortals( node_t *node ){
|
||||
portal_t *p, *next_portal, *new_portal;
|
||||
node_t *f, *b, *other_node;
|
||||
int side;
|
||||
plane_t *plane;
|
||||
winding_t *frontwinding, *backwinding;
|
||||
|
||||
plane = &mapplanes[node->planenum];
|
||||
const plane_t& plane = mapplanes[node->planenum];
|
||||
f = node->children[0];
|
||||
b = node->children[1];
|
||||
|
||||
@@ -384,16 +372,16 @@ void SplitNodePortals( node_t *node ){
|
||||
//
|
||||
// cut the portal into two portals, one on each side of the cut plane
|
||||
//
|
||||
ClipWindingEpsilon( p->winding, plane->normal, plane->dist,
|
||||
ClipWindingEpsilon( p->winding, plane.plane,
|
||||
SPLIT_WINDING_EPSILON, &frontwinding, &backwinding ); /* not strict, we want to always keep one of them even if coplanar */
|
||||
|
||||
if ( frontwinding && WindingIsTiny( frontwinding ) ) {
|
||||
if ( !f->tinyportals ) {
|
||||
VectorCopy( frontwinding->p[0], f->referencepoint );
|
||||
f->referencepoint = frontwinding->p[0];
|
||||
}
|
||||
f->tinyportals++;
|
||||
if ( !other_node->tinyportals ) {
|
||||
VectorCopy( frontwinding->p[0], other_node->referencepoint );
|
||||
other_node->referencepoint = frontwinding->p[0];
|
||||
}
|
||||
other_node->tinyportals++;
|
||||
|
||||
@@ -404,11 +392,11 @@ void SplitNodePortals( node_t *node ){
|
||||
|
||||
if ( backwinding && WindingIsTiny( backwinding ) ) {
|
||||
if ( !b->tinyportals ) {
|
||||
VectorCopy( backwinding->p[0], b->referencepoint );
|
||||
b->referencepoint = backwinding->p[0];
|
||||
}
|
||||
b->tinyportals++;
|
||||
if ( !other_node->tinyportals ) {
|
||||
VectorCopy( backwinding->p[0], other_node->referencepoint );
|
||||
other_node->referencepoint = backwinding->p[0];
|
||||
}
|
||||
other_node->tinyportals++;
|
||||
|
||||
@@ -475,12 +463,12 @@ void CalcNodeBounds( node_t *node ){
|
||||
int i;
|
||||
|
||||
// calc mins/maxs for both leafs and nodes
|
||||
ClearBounds( node->mins, node->maxs );
|
||||
node->minmax.clear();
|
||||
for ( p = node->portals ; p ; p = p->next[s] )
|
||||
{
|
||||
s = ( p->nodes[1] == node );
|
||||
for ( i = 0 ; i < p->winding->numpoints ; i++ )
|
||||
AddPointToBounds( p->winding->p[i], node->mins, node->maxs );
|
||||
node->minmax.extend( p->winding->p[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +481,7 @@ void MakeTreePortals_r( node_t *node ){
|
||||
int i;
|
||||
|
||||
CalcNodeBounds( node );
|
||||
if ( node->mins[0] >= node->maxs[0] ) {
|
||||
if ( node->minmax.mins[0] >= node->minmax.maxs[0] ) {
|
||||
Sys_Warning( "node without a volume\n"
|
||||
"node has %d tiny portals\n"
|
||||
"node reference point %1.2f %1.2f %1.2f\n",
|
||||
@@ -505,7 +493,7 @@ void MakeTreePortals_r( node_t *node ){
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
if ( node->mins[i] < MIN_WORLD_COORD || node->maxs[i] > MAX_WORLD_COORD ) {
|
||||
if ( node->minmax.mins[i] < MIN_WORLD_COORD || node->minmax.maxs[i] > MAX_WORLD_COORD ) {
|
||||
if ( node->portals && node->portals->winding ) {
|
||||
xml_Winding( "WARNING: Node With Unbounded Volume", node->portals->winding->p, node->portals->winding->numpoints, false );
|
||||
}
|
||||
@@ -587,19 +575,14 @@ void FloodPortals( node_t *node, bool skybox ){
|
||||
=============
|
||||
*/
|
||||
|
||||
bool PlaceOccupant( node_t *headnode, vec3_t origin, const entity_t *occupant, bool skybox ){
|
||||
vec_t d;
|
||||
bool PlaceOccupant( node_t *headnode, const Vector3& origin, const entity_t *occupant, bool skybox ){
|
||||
node_t *node;
|
||||
plane_t *plane;
|
||||
|
||||
|
||||
// find the leaf to start in
|
||||
node = headnode;
|
||||
while ( node->planenum != PLANENUM_LEAF )
|
||||
{
|
||||
plane = &mapplanes[ node->planenum ];
|
||||
d = DotProduct( origin, plane->normal ) - plane->dist;
|
||||
if ( d >= 0 ) {
|
||||
if ( plane3_distance_to_point( mapplanes[ node->planenum ].plane, origin ) >= 0 ) {
|
||||
node = node->children[ 0 ];
|
||||
}
|
||||
else{
|
||||
@@ -644,11 +627,11 @@ EFloodEntities FloodEntities( tree_t *tree ){
|
||||
const entity_t& e = entities[ i ];
|
||||
|
||||
/* get origin */
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
e.vectorForKey( "origin", origin );
|
||||
#if 0 // 0 = allow maps with only point entity@( 0, 0, 0 ); assuming that entities, containing no primitives are point ones
|
||||
/* as a special case, allow origin-less entities */
|
||||
if ( VectorCompare( origin, vec3_origin ) ) {
|
||||
if ( VectorCompare( origin, g_vector3_identity ) ) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -661,25 +644,21 @@ EFloodEntities FloodEntities( tree_t *tree ){
|
||||
if ( e.classname_is( "_skybox" ) ) {
|
||||
skybox = true;
|
||||
|
||||
/* invert origin */
|
||||
vec3_t offset;
|
||||
VectorScale( origin, -1.0f, offset );
|
||||
|
||||
/* get scale */
|
||||
vec3_t scale = { 64.0f, 64.0f, 64.0f };
|
||||
Vector3 scale( 64, 64, 64 );
|
||||
if( !e.read_keyvalue( scale, "_scale" ) )
|
||||
if( e.read_keyvalue( scale[0], "_scale" ) )
|
||||
scale[1] = scale[2] = scale[0];
|
||||
|
||||
/* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */
|
||||
vec3_t angles = { 0.f, 0.f, 0.f };
|
||||
Vector3 angles( 0, 0, 0 );
|
||||
if ( !e.read_keyvalue( value, "angles" ) ||
|
||||
3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) )
|
||||
e.read_keyvalue( angles[ 2 ], "angle" );
|
||||
|
||||
/* set transform matrix (thanks spog) */
|
||||
m4x4_identity( skyboxTransform );
|
||||
m4x4_pivoted_transform_by_vec3( skyboxTransform, offset, angles, eXYZ, scale, origin );
|
||||
skyboxTransform = g_matrix4_identity;
|
||||
matrix4_pivoted_transform_by_euler_xyz_degrees( skyboxTransform, -origin, angles, scale, origin );
|
||||
}
|
||||
else{
|
||||
skybox = false;
|
||||
|
||||
@@ -50,9 +50,9 @@ int num_visclusters; // clusters the player can be in
|
||||
int num_visportals;
|
||||
int num_solidfaces;
|
||||
|
||||
void WriteFloat( FILE *f, vec_t v ){
|
||||
if ( fabs( v - Q_rint( v ) ) < 0.001 ) {
|
||||
fprintf( f, "%i ", (int)Q_rint( v ) );
|
||||
void WriteFloat( FILE *f, float v ){
|
||||
if ( fabs( v - std::rint( v ) ) < 0.001 ) {
|
||||
fprintf( f, "%li ", std::lrint( v ) );
|
||||
}
|
||||
else{
|
||||
fprintf( f, "%f ", v );
|
||||
@@ -100,8 +100,6 @@ void WritePortalFile_r( node_t *node ){
|
||||
int i, s, flags;
|
||||
portal_t *p;
|
||||
winding_t *w;
|
||||
vec3_t normal;
|
||||
vec_t dist;
|
||||
|
||||
// decision node
|
||||
if ( node->planenum != PLANENUM_LEAF ) {
|
||||
@@ -132,9 +130,7 @@ void WritePortalFile_r( node_t *node ){
|
||||
// the changeover point between different axis. interpret the
|
||||
// plane the same way vis will, and flip the side orders if needed
|
||||
// FIXME: is this still relevent?
|
||||
WindingPlane( w, normal, &dist );
|
||||
|
||||
if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards...
|
||||
if ( vector3_dot( p->plane.normal(), WindingPlane( w ).normal() ) < 0.99 ) { // backwards...
|
||||
fprintf( pf, "%i %i %i ", w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster );
|
||||
}
|
||||
else{
|
||||
|
||||
+236
-188
@@ -69,7 +69,6 @@
|
||||
#include "version.h" /* ttimo: might want to guard that if built outside of the GtkRadiant tree */
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "md5lib.h"
|
||||
#include "ddslib.h"
|
||||
|
||||
@@ -88,20 +87,12 @@
|
||||
#include "stream/stringstream.h"
|
||||
#include "bitflags.h"
|
||||
#include <list>
|
||||
#include "qmath.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------------
|
||||
|
||||
port-related hacks
|
||||
|
||||
------------------------------------------------------------------------------- */
|
||||
|
||||
/* macro version */
|
||||
#define VectorMA( a, s, b, c ) ( ( c )[ 0 ] = ( a )[ 0 ] + ( s ) * ( b )[ 0 ], ( c )[ 1 ] = ( a )[ 1 ] + ( s ) * ( b )[ 1 ], ( c )[ 2 ] = ( a )[ 2 ] + ( s ) * ( b )[ 2 ] )
|
||||
|
||||
#include "maxworld.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------------
|
||||
@@ -241,33 +232,8 @@ enum class EBrushType
|
||||
#define CLUSTER_OCCLUDED -2
|
||||
#define CLUSTER_FLOODED -3
|
||||
|
||||
#define VERTEX_LUXEL_SIZE 3
|
||||
#define BSP_LUXEL_SIZE 3
|
||||
#define RAD_LUXEL_SIZE 3
|
||||
#define SUPER_LUXEL_SIZE 4
|
||||
#define SUPER_FLAG_SIZE 4
|
||||
#define FLAG_FORCE_SUBSAMPLING 1
|
||||
#define FLAG_ALREADY_SUBSAMPLED 2
|
||||
#define SUPER_ORIGIN_SIZE 3
|
||||
#define SUPER_NORMAL_SIZE 4
|
||||
#define SUPER_DELUXEL_SIZE 3
|
||||
#define BSP_DELUXEL_SIZE 3
|
||||
#define SUPER_FLOODLIGHT_SIZE 4
|
||||
|
||||
#define VERTEX_LUXEL( s, v ) ( vertexLuxels[ s ] + ( ( v ) * VERTEX_LUXEL_SIZE ) )
|
||||
#define RAD_VERTEX_LUXEL( s, v )( radVertexLuxels[ s ] + ( ( v ) * VERTEX_LUXEL_SIZE ) )
|
||||
#define BSP_LUXEL( s, x, y ) ( lm->bspLuxels[ s ] + ( ( ( ( y ) * lm->w ) + ( x ) ) * BSP_LUXEL_SIZE ) )
|
||||
#define RAD_LUXEL( s, x, y ) ( lm->radLuxels[ s ] + ( ( ( ( y ) * lm->w ) + ( x ) ) * RAD_LUXEL_SIZE ) )
|
||||
#define SUPER_LUXEL( s, x, y ) ( lm->superLuxels[ s ] + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_LUXEL_SIZE ) )
|
||||
#define SUPER_FLAG( x, y ) ( lm->superFlags + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_FLAG_SIZE ) )
|
||||
#define SUPER_DELUXEL( x, y ) ( lm->superDeluxels + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_DELUXEL_SIZE ) )
|
||||
#define BSP_DELUXEL( x, y ) ( lm->bspDeluxels + ( ( ( ( y ) * lm->w ) + ( x ) ) * BSP_DELUXEL_SIZE ) )
|
||||
#define SUPER_CLUSTER( x, y ) ( lm->superClusters + ( ( ( y ) * lm->sw ) + ( x ) ) )
|
||||
#define SUPER_ORIGIN( x, y ) ( lm->superOrigins + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_ORIGIN_SIZE ) )
|
||||
#define SUPER_NORMAL( x, y ) ( lm->superNormals + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_NORMAL_SIZE ) )
|
||||
#define SUPER_DIRT( x, y ) ( lm->superNormals + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_NORMAL_SIZE ) + 3 ) /* stash dirtyness in normal[ 3 ] */
|
||||
#define SUPER_FLOODLIGHT( x, y ) ( lm->superFloodLight + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_FLOODLIGHT_SIZE ) )
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------------
|
||||
@@ -308,9 +274,8 @@ enum class EBrushType
|
||||
#define LIGHTMAP_WIDTH 128
|
||||
#define LIGHTMAP_HEIGHT 128
|
||||
|
||||
#define MIN_WORLD_COORD ( -65536 )
|
||||
#define MAX_WORLD_COORD ( 65536 )
|
||||
#define WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD )
|
||||
|
||||
using Vector3b = BasicVector3<byte>;
|
||||
|
||||
|
||||
typedef void ( *bspFunc )( const char * );
|
||||
@@ -333,7 +298,7 @@ struct bspHeader_t
|
||||
|
||||
struct bspModel_t
|
||||
{
|
||||
float mins[ 3 ], maxs[ 3 ];
|
||||
MinMax minmax;
|
||||
int firstBSPSurface, numBSPSurfaces;
|
||||
int firstBSPBrush, numBSPBrushes;
|
||||
};
|
||||
@@ -349,19 +314,14 @@ struct bspShader_t
|
||||
|
||||
/* planes x^1 is always the opposite of plane x */
|
||||
|
||||
struct bspPlane_t
|
||||
{
|
||||
float normal[ 3 ];
|
||||
float dist;
|
||||
};
|
||||
using bspPlane_t = Plane3f;
|
||||
|
||||
|
||||
struct bspNode_t
|
||||
{
|
||||
int planeNum;
|
||||
int children[ 2 ]; /* negative numbers are -(leafs+1), not nodes */
|
||||
int mins[ 3 ]; /* for frustum culling */
|
||||
int maxs[ 3 ];
|
||||
MinMax___<int> minmax; /* for frustum culling */
|
||||
};
|
||||
|
||||
|
||||
@@ -370,8 +330,7 @@ struct bspLeaf_t
|
||||
int cluster; /* -1 = opaque cluster (do I still store these?) */
|
||||
int area;
|
||||
|
||||
int mins[ 3 ]; /* for frustum culling */
|
||||
int maxs[ 3 ];
|
||||
MinMax___<int> minmax; /* for frustum culling */
|
||||
|
||||
int firstBSPLeafSurface;
|
||||
int numBSPLeafSurfaces;
|
||||
@@ -407,11 +366,11 @@ struct bspFog_t
|
||||
|
||||
struct bspDrawVert_t
|
||||
{
|
||||
vec3_t xyz;
|
||||
float st[ 2 ];
|
||||
float lightmap[ MAX_LIGHTMAPS ][ 2 ]; /* RBSP */
|
||||
vec3_t normal;
|
||||
byte color[ MAX_LIGHTMAPS ][ 4 ]; /* RBSP */
|
||||
Vector3 xyz;
|
||||
Vector2 st;
|
||||
Vector2 lightmap[ MAX_LIGHTMAPS ]; /* RBSP */
|
||||
Vector3 normal;
|
||||
Color4b color[ MAX_LIGHTMAPS ]; /* RBSP */
|
||||
};
|
||||
|
||||
|
||||
@@ -428,8 +387,8 @@ enum bspSurfaceType_t
|
||||
|
||||
struct bspGridPoint_t
|
||||
{
|
||||
byte ambient[ MAX_LIGHTMAPS ][ 3 ];
|
||||
byte directed[ MAX_LIGHTMAPS ][ 3 ];
|
||||
Vector3b ambient[ MAX_LIGHTMAPS ];
|
||||
Vector3b directed[ MAX_LIGHTMAPS ];
|
||||
byte styles[ MAX_LIGHTMAPS ];
|
||||
byte latLong[ 2 ];
|
||||
};
|
||||
@@ -453,8 +412,8 @@ struct bspDrawSurface_t
|
||||
int lightmapX[ MAX_LIGHTMAPS ], lightmapY[ MAX_LIGHTMAPS ]; /* RBSP */
|
||||
int lightmapWidth, lightmapHeight;
|
||||
|
||||
vec3_t lightmapOrigin;
|
||||
vec3_t lightmapVecs[ 3 ]; /* on patches, [ 0 ] and [ 1 ] are lodbounds */
|
||||
Vector3 lightmapOrigin;
|
||||
Vector3 lightmapVecs[ 3 ]; /* on patches, [ 0 ] and [ 1 ] are lodbounds */
|
||||
|
||||
int patchWidth;
|
||||
int patchHeight;
|
||||
@@ -465,8 +424,8 @@ struct bspDrawSurface_t
|
||||
struct bspAdvertisement_t
|
||||
{
|
||||
int cellId;
|
||||
vec3_t normal;
|
||||
vec3_t rect[4];
|
||||
Vector3 normal;
|
||||
Vector3 rect[4];
|
||||
char model[ MAX_QPATH ];
|
||||
};
|
||||
|
||||
@@ -553,7 +512,7 @@ struct image_t
|
||||
struct sun_t
|
||||
{
|
||||
sun_t *next;
|
||||
vec3_t direction, color;
|
||||
Vector3 direction, color;
|
||||
float photons, deviance, filterRadius;
|
||||
int numSamples, style;
|
||||
};
|
||||
@@ -579,7 +538,7 @@ struct foliage_t
|
||||
|
||||
struct foliageInstance_t
|
||||
{
|
||||
vec3_t xyz, normal;
|
||||
Vector3 xyz, normal;
|
||||
};
|
||||
|
||||
|
||||
@@ -613,7 +572,7 @@ struct colorMod_t
|
||||
{
|
||||
colorMod_t *next;
|
||||
EColorMod type;
|
||||
vec_t data[ 16 ];
|
||||
float data[ 16 ];
|
||||
};
|
||||
|
||||
|
||||
@@ -657,7 +616,7 @@ struct shaderInfo_t
|
||||
float offset; /* ydnar: offset in units */
|
||||
float shadeAngleDegrees; /* ydnar: breaking angle for smooth shading (degrees) */
|
||||
|
||||
vec3_t mins, maxs; /* ydnar: for particle studio vertexDeform move support */
|
||||
MinMax minmax; /* ydnar: for particle studio vertexDeform move support */
|
||||
|
||||
bool legacyTerrain; /* ydnar: enable legacy terrain crutches */
|
||||
bool indexed; /* ydnar: attempt to use indexmap (terrain alphamap style) */
|
||||
@@ -667,9 +626,9 @@ struct shaderInfo_t
|
||||
bool invert; /* ydnar: reverse facing */
|
||||
bool nonplanar; /* ydnar: for nonplanar meta surface merging */
|
||||
bool tcGen; /* ydnar: has explicit texcoord generation */
|
||||
vec3_t vecs[ 2 ]; /* ydnar: explicit texture vectors for [0,1] texture space */
|
||||
Vector3 vecs[ 2 ]; /* ydnar: explicit texture vectors for [0,1] texture space */
|
||||
tcMod_t mod; /* ydnar: q3map_tcMod matrix for djbob :) */
|
||||
vec3_t lightmapAxis; /* ydnar: explicit lightmap axis projection */
|
||||
Vector3 lightmapAxis; /* ydnar: explicit lightmap axis projection */
|
||||
colorMod_t *colorMod; /* ydnar: q3map_rgb/color/alpha/Set/Mod support */
|
||||
|
||||
int furNumLayers; /* ydnar: number of fur layers */
|
||||
@@ -714,13 +673,13 @@ struct shaderInfo_t
|
||||
int skyLightIterations; /* ydnar */
|
||||
sun_t *sun; /* ydnar */
|
||||
|
||||
vec3_t color; /* normalized color */
|
||||
vec4_t averageColor;
|
||||
Vector3 color; /* normalized color */
|
||||
Color4f averageColor;
|
||||
byte lightStyle;
|
||||
|
||||
/* vortex: per-surface floodlight */
|
||||
float floodlightDirectionScale;
|
||||
vec3_t floodlightRGB;
|
||||
Vector3 floodlightRGB;
|
||||
float floodlightIntensity;
|
||||
float floodlightDistance;
|
||||
|
||||
@@ -730,9 +689,9 @@ struct shaderInfo_t
|
||||
float lmFilterRadius; /* ydnar: lightmap filtering/blurring radius for this shader (default: 0) */
|
||||
|
||||
int shaderWidth, shaderHeight; /* ydnar */
|
||||
float stFlat[ 2 ];
|
||||
Vector2 stFlat;
|
||||
|
||||
vec3_t fogDir; /* ydnar */
|
||||
Vector3 fogDir; /* ydnar */
|
||||
|
||||
char *shaderText; /* ydnar */
|
||||
bool custom;
|
||||
@@ -760,9 +719,20 @@ struct face_t
|
||||
|
||||
struct plane_t
|
||||
{
|
||||
vec3_t normal;
|
||||
vec_t dist;
|
||||
int type;
|
||||
Plane3f plane;
|
||||
Vector3& normal(){
|
||||
return plane.normal();
|
||||
}
|
||||
const Vector3& normal() const {
|
||||
return plane.normal();
|
||||
}
|
||||
float& dist(){
|
||||
return plane.dist();
|
||||
}
|
||||
const float& dist() const {
|
||||
return plane.dist();
|
||||
}
|
||||
EPlaneType type;
|
||||
int counter;
|
||||
int hash_chain;
|
||||
};
|
||||
@@ -774,8 +744,8 @@ struct side_t
|
||||
|
||||
int outputNum; /* set when the side is written to the file list */
|
||||
|
||||
float texMat[ 2 ][ 3 ]; /* brush primitive texture matrix */
|
||||
float vecs[ 2 ][ 4 ]; /* old-style texture coordinate mapping */
|
||||
Vector3 texMat[ 2 ]; /* brush primitive texture matrix */
|
||||
Vector4 vecs[ 2 ]; /* old-style texture coordinate mapping */
|
||||
|
||||
winding_t *winding;
|
||||
winding_t *visibleHull; /* convex hull of all visible fragments */
|
||||
@@ -830,7 +800,7 @@ struct brush_t
|
||||
int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */
|
||||
float lightmapScale;
|
||||
float shadeAngleDegrees; /* jal : entity based _shadeangle */
|
||||
vec3_t eMins, eMaxs;
|
||||
MinMax eMinmax;
|
||||
indexMap_t *im;
|
||||
|
||||
int contentFlags;
|
||||
@@ -840,7 +810,7 @@ struct brush_t
|
||||
|
||||
int portalareas[ 2 ];
|
||||
|
||||
vec3_t mins, maxs;
|
||||
MinMax minmax;
|
||||
int numsides;
|
||||
|
||||
side_t sides[]; /* variably sized */
|
||||
@@ -879,7 +849,7 @@ struct parseMesh_t
|
||||
/* ydnar: gs mods */
|
||||
int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */
|
||||
float lightmapScale;
|
||||
vec3_t eMins, eMaxs;
|
||||
MinMax eMinmax;
|
||||
indexMap_t *im;
|
||||
|
||||
/* grouping */
|
||||
@@ -963,8 +933,8 @@ struct mapDrawSurface_t
|
||||
int *indexes;
|
||||
|
||||
int planeNum;
|
||||
vec3_t lightmapOrigin; /* also used for flares */
|
||||
vec3_t lightmapVecs[ 3 ]; /* also used for flares */
|
||||
Vector3 lightmapOrigin; /* also used for flares */
|
||||
Vector3 lightmapVecs[ 3 ]; /* also used for flares */
|
||||
int lightStyle; /* used for flares */
|
||||
|
||||
/* ydnar: per-surface (per-entity, actually) lightmap sample size scaling */
|
||||
@@ -974,8 +944,8 @@ struct mapDrawSurface_t
|
||||
float shadeAngleDegrees;
|
||||
|
||||
/* ydnar: surface classification */
|
||||
vec3_t mins, maxs;
|
||||
vec3_t lightmapAxis;
|
||||
MinMax minmax;
|
||||
Vector3 lightmapAxis;
|
||||
int sampleSize;
|
||||
|
||||
/* ydnar: shadow group support */
|
||||
@@ -989,7 +959,7 @@ struct mapDrawSurface_t
|
||||
float longestCurve;
|
||||
int maxIterations;
|
||||
int patchWidth, patchHeight;
|
||||
vec3_t bounds[ 2 ];
|
||||
MinMax bounds;
|
||||
|
||||
/* ydnar/sd: for foliage */
|
||||
int numFoliageInstances;
|
||||
@@ -1014,8 +984,8 @@ struct metaTriangle_t
|
||||
side_t *side;
|
||||
int entityNum, surfaceNum, planeNum, fogNum, sampleSize, castShadows, recvShadows;
|
||||
float shadeAngleDegrees;
|
||||
vec4_t plane;
|
||||
vec3_t lightmapAxis;
|
||||
Plane3f plane;
|
||||
Vector3 lightmapAxis;
|
||||
int indexes[ 3 ];
|
||||
};
|
||||
|
||||
@@ -1028,13 +998,13 @@ struct epair_t
|
||||
|
||||
struct entity_t
|
||||
{
|
||||
vec3_t origin;
|
||||
Vector3 origin;
|
||||
brush_t *brushes, *lastBrush, *colorModBrushes;
|
||||
parseMesh_t *patches;
|
||||
int mapEntityNum, firstDrawSurf;
|
||||
int firstBrush, numBrushes; /* only valid during BSP compile */
|
||||
std::list<epair_t> epairs;
|
||||
vec3_t originbrush_origin;
|
||||
Vector3 originbrush_origin;
|
||||
|
||||
void setKeyValue( const char *key, const char *value );
|
||||
const char *valueForKey( const char *key ) const;
|
||||
@@ -1057,9 +1027,9 @@ struct entity_t
|
||||
read_keyvalue_( float_value, { keys ... } );
|
||||
return float_value;
|
||||
}
|
||||
void vectorForKey( const char *key, vec3_t& vec ) const {
|
||||
void vectorForKey( const char *key, Vector3& vec ) const {
|
||||
if( !read_keyvalue_( vec, { key } ) )
|
||||
VectorClear( vec );
|
||||
vec.set( 0 );
|
||||
}
|
||||
|
||||
const char *classname() const {
|
||||
@@ -1083,7 +1053,7 @@ private:
|
||||
bool read_keyvalue_( bool &bool_value, std::initializer_list<const char*>&& keys ) const;
|
||||
bool read_keyvalue_( int &int_value, std::initializer_list<const char*>&& keys ) const;
|
||||
bool read_keyvalue_( float &float_value, std::initializer_list<const char*>&& keys ) const;
|
||||
bool read_keyvalue_( float (&vector3_value)[3], std::initializer_list<const char*>&& keys ) const;
|
||||
bool read_keyvalue_( Vector3& vector3_value, std::initializer_list<const char*>&& keys ) const;
|
||||
bool read_keyvalue_( char (&string_value)[1024], std::initializer_list<const char*>&& keys ) const;
|
||||
bool read_keyvalue_( const char *&string_ptr_value, std::initializer_list<const char*>&& keys ) const;
|
||||
};
|
||||
@@ -1094,7 +1064,7 @@ struct node_t
|
||||
/* both leafs and nodes */
|
||||
int planenum; /* -1 = leaf node */
|
||||
node_t *parent;
|
||||
vec3_t mins, maxs; /* valid after portalization */
|
||||
MinMax minmax; /* valid after portalization */
|
||||
brush_t *volume; /* one for each leaf/node */
|
||||
|
||||
/* nodes only */
|
||||
@@ -1102,7 +1072,7 @@ struct node_t
|
||||
node_t *children[ 2 ];
|
||||
int compileFlags; /* ydnar: hint, antiportal */
|
||||
int tinyportals;
|
||||
vec3_t referencepoint;
|
||||
Vector3 referencepoint;
|
||||
|
||||
/* leafs only */
|
||||
bool opaque; /* view can never be inside */
|
||||
@@ -1141,7 +1111,7 @@ struct tree_t
|
||||
{
|
||||
node_t *headnode;
|
||||
node_t outside_node;
|
||||
vec3_t mins, maxs;
|
||||
MinMax minmax;
|
||||
};
|
||||
|
||||
|
||||
@@ -1152,17 +1122,13 @@ struct tree_t
|
||||
|
||||
------------------------------------------------------------------------------- */
|
||||
|
||||
struct visPlane_t
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
};
|
||||
using visPlane_t = Plane3f;
|
||||
|
||||
|
||||
struct fixedWinding_t
|
||||
{
|
||||
int numpoints;
|
||||
vec3_t points[ MAX_POINTS_ON_FIXED_WINDING ]; /* variable sized */
|
||||
Vector3 points[ MAX_POINTS_ON_FIXED_WINDING ]; /* variable sized */
|
||||
};
|
||||
|
||||
|
||||
@@ -1190,7 +1156,7 @@ struct vportal_t
|
||||
visPlane_t plane; /* normal pointing into neighbor */
|
||||
int leaf; /* neighbor */
|
||||
|
||||
vec3_t origin; /* for fast clip testing */
|
||||
Vector3 origin; /* for fast clip testing */
|
||||
float radius;
|
||||
|
||||
fixedWinding_t *winding;
|
||||
@@ -1287,13 +1253,13 @@ struct light_t
|
||||
LightFlags flags; /* ydnar: condensed all the booleans into one flags int */
|
||||
shaderInfo_t *si;
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t normal; /* for surfaces, spotlights, and suns */
|
||||
Vector3 origin;
|
||||
Vector3 normal; /* for surfaces, spotlights, and suns */
|
||||
float dist; /* plane location along normal */
|
||||
|
||||
float photons;
|
||||
int style;
|
||||
vec3_t color;
|
||||
Vector3 color;
|
||||
float radiusByDist; /* for spotlights */
|
||||
float fade; /* ydnar: from wolf, for linear lights */
|
||||
float angleScale; /* ydnar: stolen from vlight for K */
|
||||
@@ -1302,11 +1268,11 @@ struct light_t
|
||||
float add; /* ydnar: used for area lights */
|
||||
float envelope; /* ydnar: units until falloff < tolerance */
|
||||
float envelope2; /* ydnar: envelope squared (tiny optimization) */
|
||||
vec3_t mins, maxs; /* ydnar: pvs envelope */
|
||||
MinMax minmax; /* ydnar: pvs envelope */
|
||||
int cluster; /* ydnar: cluster light falls into */
|
||||
|
||||
winding_t *w;
|
||||
vec3_t emitColor; /* full out-of-gamut value */
|
||||
Vector3 emitColor; /* full out-of-gamut value */
|
||||
|
||||
float falloffTolerance; /* ydnar: minimum attenuation threshold */
|
||||
float filterRadius; /* ydnar: lightmap filter radius in world units, 0 == default */
|
||||
@@ -1329,28 +1295,28 @@ struct trace_t
|
||||
|
||||
/* per-sample input */
|
||||
int cluster;
|
||||
vec3_t origin, normal;
|
||||
vec_t inhibitRadius; /* sphere in which occluding geometry is ignored */
|
||||
Vector3 origin, normal;
|
||||
float inhibitRadius; /* sphere in which occluding geometry is ignored */
|
||||
|
||||
/* per-light input */
|
||||
light_t *light;
|
||||
vec3_t end;
|
||||
Vector3 end;
|
||||
|
||||
/* calculated input */
|
||||
vec3_t displacement, direction;
|
||||
vec_t distance;
|
||||
Vector3 displacement, direction;
|
||||
float distance;
|
||||
|
||||
/* input and output */
|
||||
vec3_t color; /* starts out at full color, may be reduced if transparent surfaces are crossed */
|
||||
vec3_t colorNoShadow; /* result color with no shadow casting */
|
||||
vec3_t directionContribution; /* result contribution to the deluxe map */
|
||||
Vector3 color; /* starts out at full color, may be reduced if transparent surfaces are crossed */
|
||||
Vector3 colorNoShadow; /* result color with no shadow casting */
|
||||
Vector3 directionContribution; /* result contribution to the deluxe map */
|
||||
|
||||
/* output */
|
||||
vec3_t hit;
|
||||
Vector3 hit;
|
||||
int compileFlags; /* for determining surface compile flags traced through */
|
||||
bool passSolid;
|
||||
bool opaque;
|
||||
vec_t forceSubsampling; /* needs subsampling (alphashadow), value = max color contribution possible from it */
|
||||
float forceSubsampling; /* needs subsampling (alphashadow), value = max color contribution possible from it */
|
||||
|
||||
/* working data */
|
||||
int numTestNodes;
|
||||
@@ -1358,15 +1324,14 @@ struct trace_t
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* must be identical to bspDrawVert_t except for float color! */
|
||||
struct radVert_t
|
||||
{
|
||||
vec3_t xyz;
|
||||
float st[ 2 ];
|
||||
float lightmap[ MAX_LIGHTMAPS ][ 2 ];
|
||||
vec3_t normal;
|
||||
float color[ MAX_LIGHTMAPS ][ 4 ];
|
||||
Vector3 xyz;
|
||||
Vector2 st;
|
||||
Vector2 lightmap[ MAX_LIGHTMAPS ];
|
||||
Vector3 normal;
|
||||
Color4f color[ MAX_LIGHTMAPS ];
|
||||
};
|
||||
|
||||
|
||||
@@ -1380,8 +1345,8 @@ struct radWinding_t
|
||||
/* crutch for poor local allocations in win32 smp */
|
||||
struct clipWork_t
|
||||
{
|
||||
vec_t dists[ MAX_POINTS_ON_WINDING + 4 ];
|
||||
int sides[ MAX_POINTS_ON_WINDING + 4 ];
|
||||
float dists[ MAX_POINTS_ON_WINDING + 4 ];
|
||||
EPlaneSide sides[ MAX_POINTS_ON_WINDING + 4 ];
|
||||
};
|
||||
|
||||
|
||||
@@ -1395,10 +1360,19 @@ struct outLightmap_t
|
||||
int numShaders;
|
||||
shaderInfo_t *shaders[ MAX_LIGHTMAP_SHADERS ];
|
||||
byte *lightBits;
|
||||
byte *bspLightBytes;
|
||||
byte *bspDirBytes;
|
||||
Vector3b *bspLightBytes;
|
||||
Vector3b *bspDirBytes;
|
||||
};
|
||||
|
||||
struct SuperLuxel{
|
||||
Vector3 value;
|
||||
float count;
|
||||
};
|
||||
|
||||
struct SuperFloodLight{
|
||||
Vector3 value;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct rawLightmap_t
|
||||
{
|
||||
@@ -1414,18 +1388,19 @@ struct rawLightmap_t
|
||||
|
||||
/* vortex: per-surface floodlight */
|
||||
float floodlightDirectionScale;
|
||||
vec3_t floodlightRGB;
|
||||
Vector3 floodlightRGB;
|
||||
float floodlightIntensity;
|
||||
float floodlightDistance;
|
||||
|
||||
int entityNum;
|
||||
int recvShadows;
|
||||
vec3_t mins, maxs, axis, origin, *vecs;
|
||||
float *plane;
|
||||
MinMax minmax;
|
||||
Vector3 axis, origin, *vecs;
|
||||
Plane3f *plane;
|
||||
int w, h, sw, sh, used;
|
||||
|
||||
bool solid[ MAX_LIGHTMAPS ];
|
||||
vec3_t solidColor[ MAX_LIGHTMAPS ];
|
||||
Vector3 solidColor[ MAX_LIGHTMAPS ];
|
||||
|
||||
int numStyledTwins;
|
||||
rawLightmap_t *twins[ MAX_LIGHTMAPS ];
|
||||
@@ -1434,25 +1409,92 @@ struct rawLightmap_t
|
||||
int twinNums[ MAX_LIGHTMAPS ];
|
||||
int lightmapX[ MAX_LIGHTMAPS ], lightmapY[ MAX_LIGHTMAPS ];
|
||||
byte styles[ MAX_LIGHTMAPS ];
|
||||
float *bspLuxels[ MAX_LIGHTMAPS ];
|
||||
float *radLuxels[ MAX_LIGHTMAPS ];
|
||||
float *superLuxels[ MAX_LIGHTMAPS ];
|
||||
unsigned char *superFlags;
|
||||
float *superOrigins;
|
||||
float *superNormals;
|
||||
Vector3 *bspLuxels[ MAX_LIGHTMAPS ];
|
||||
Vector3 *radLuxels[ MAX_LIGHTMAPS ];
|
||||
SuperLuxel *superLuxels[ MAX_LIGHTMAPS ];
|
||||
byte *superFlags;
|
||||
Vector3 *superOrigins;
|
||||
Vector3 *superNormals;
|
||||
float *superDirt;
|
||||
int *superClusters;
|
||||
|
||||
float *superDeluxels; /* average light direction */
|
||||
float *bspDeluxels;
|
||||
float *superFloodLight;
|
||||
Vector3 *superDeluxels; /* average light direction */
|
||||
Vector3 *bspDeluxels;
|
||||
SuperFloodLight *superFloodLight;
|
||||
Vector3& getBspLuxel( int lightmapNum, int x, int y ){
|
||||
return bspLuxels[ lightmapNum ][y * w + x];
|
||||
}
|
||||
const Vector3& getBspLuxel( int lightmapNum, int x, int y ) const {
|
||||
return bspLuxels[ lightmapNum ][y * w + x];
|
||||
}
|
||||
Vector3& getRadLuxel( int lightmapNum, int x, int y ){
|
||||
return radLuxels[ lightmapNum ][y * w + x];
|
||||
}
|
||||
const Vector3& getRadLuxel( int lightmapNum, int x, int y ) const {
|
||||
return radLuxels[ lightmapNum ][y * w + x];
|
||||
}
|
||||
SuperLuxel& getSuperLuxel( int lightmapNum, int x, int y ){
|
||||
return superLuxels[ lightmapNum ][y * sw + x];
|
||||
}
|
||||
const SuperLuxel& getSuperLuxel( int lightmapNum, int x, int y ) const {
|
||||
return superLuxels[ lightmapNum ][y * sw + x];
|
||||
}
|
||||
const byte& getSuperFlag( int x, int y ) const {
|
||||
return superFlags[y * sw + x];
|
||||
}
|
||||
byte& getSuperFlag( int x, int y ){
|
||||
return superFlags[y * sw + x];
|
||||
}
|
||||
Vector3& getSuperOrigin( int x, int y ){
|
||||
return superOrigins[y * sw + x];
|
||||
}
|
||||
const Vector3& getSuperOrigin( int x, int y ) const {
|
||||
return superOrigins[y * sw + x];
|
||||
}
|
||||
Vector3& getSuperNormal( int x, int y ){
|
||||
return superNormals[y * sw + x];
|
||||
}
|
||||
const Vector3& getSuperNormal( int x, int y ) const {
|
||||
return superNormals[y * sw + x];
|
||||
}
|
||||
float& getSuperDirt( int x, int y ){
|
||||
return superDirt[y * sw + x];
|
||||
}
|
||||
const float& getSuperDirt( int x, int y ) const {
|
||||
return superDirt[y * sw + x];
|
||||
}
|
||||
int& getSuperCluster( int x, int y ){
|
||||
return superClusters[y * sw + x];
|
||||
}
|
||||
const int& getSuperCluster( int x, int y ) const {
|
||||
return superClusters[y * sw + x];
|
||||
}
|
||||
Vector3& getSuperDeluxel( int x, int y ){
|
||||
return superDeluxels[y * sw + x];
|
||||
}
|
||||
const Vector3& getSuperDeluxel( int x, int y ) const {
|
||||
return superDeluxels[y * sw + x];
|
||||
}
|
||||
Vector3& getBspDeluxel( int x, int y ){
|
||||
return bspDeluxels[y * w + x];
|
||||
}
|
||||
const Vector3& getBspDeluxel( int x, int y ) const {
|
||||
return bspDeluxels[y * w + x];
|
||||
}
|
||||
SuperFloodLight& getSuperFloodLight( int x, int y ){
|
||||
return superFloodLight[y * sw + x];
|
||||
}
|
||||
const SuperFloodLight& getSuperFloodLight( int x, int y ) const {
|
||||
return superFloodLight[y * sw + x];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct rawGridPoint_t
|
||||
{
|
||||
vec3_t ambient[ MAX_LIGHTMAPS ];
|
||||
vec3_t directed[ MAX_LIGHTMAPS ];
|
||||
vec3_t dir;
|
||||
Vector3 ambient[ MAX_LIGHTMAPS ];
|
||||
Vector3 directed[ MAX_LIGHTMAPS ];
|
||||
Vector3 dir;
|
||||
byte styles[ MAX_LIGHTMAPS ];
|
||||
};
|
||||
|
||||
@@ -1465,8 +1507,9 @@ struct surfaceInfo_t
|
||||
int parentSurfaceNum, childSurfaceNum;
|
||||
int entityNum, castShadows, recvShadows, sampleSize, patchIterations;
|
||||
float longestCurve;
|
||||
float *plane;
|
||||
vec3_t axis, mins, maxs;
|
||||
Plane3f *plane;
|
||||
Vector3 axis;
|
||||
MinMax minmax;
|
||||
bool hasLightmap, approximated;
|
||||
int firstSurfaceCluster, numSurfaceClusters;
|
||||
};
|
||||
@@ -1477,8 +1520,8 @@ struct surfaceInfo_t
|
||||
|
||||
------------------------------------------------------------------------------- */
|
||||
|
||||
static inline vec_t Random( void ){ /* returns a pseudorandom number between 0 and 1 */
|
||||
return (vec_t) rand() / RAND_MAX;
|
||||
inline float Random( void ){ /* returns a pseudorandom number between 0 and 1 */
|
||||
return (float) rand() / RAND_MAX;
|
||||
}
|
||||
|
||||
/* help.c */
|
||||
@@ -1524,15 +1567,15 @@ void FreeBrush( brush_t *brushes );
|
||||
void FreeBrushList( brush_t *brushes );
|
||||
brush_t *CopyBrush( const brush_t *brush );
|
||||
bool BoundBrush( brush_t *brush );
|
||||
void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out );
|
||||
bool CreateBrushWindings( brush_t *brush );
|
||||
brush_t *BrushFromBounds( vec3_t mins, vec3_t maxs );
|
||||
vec_t BrushVolume( brush_t *brush );
|
||||
brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs );
|
||||
float BrushVolume( brush_t *brush );
|
||||
void WriteBSPBrushMap( const char *name, brush_t *list );
|
||||
|
||||
void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree );
|
||||
void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree );
|
||||
|
||||
int BoxOnPlaneSide( vec3_t mins, vec3_t maxs, plane_t *plane );
|
||||
bool WindingIsTiny( winding_t *w );
|
||||
|
||||
void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back );
|
||||
@@ -1542,7 +1585,7 @@ node_t *AllocNode( void );
|
||||
|
||||
|
||||
/* mesh.c */
|
||||
void LerpDrawVert( bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *out );
|
||||
void LerpDrawVert( const bspDrawVert_t *a, const bspDrawVert_t *b, bspDrawVert_t *out );
|
||||
void LerpDrawVertAmount( bspDrawVert_t *a, bspDrawVert_t *b, float amount, bspDrawVert_t *out );
|
||||
void FreeMesh( mesh_t *m );
|
||||
mesh_t *CopyMesh( mesh_t *mesh );
|
||||
@@ -1560,9 +1603,11 @@ void PutMeshOnCurve( mesh_t in );
|
||||
|
||||
/* map.c */
|
||||
void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups );
|
||||
int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points );
|
||||
bool PlaneEqual( plane_t *p, vec3_t normal, vec_t dist );
|
||||
int PlaneTypeForNormal( vec3_t normal );
|
||||
int FindFloatPlane( const Plane3f& plane, int numPoints, const Vector3 *points );
|
||||
inline int FindFloatPlane( const Vector3& normal, float dist, int numPoints, const Vector3 *points ){
|
||||
return FindFloatPlane( Plane3f( normal, dist ), numPoints, points );
|
||||
}
|
||||
bool PlaneEqual( const plane_t *p, const Plane3f& plane );
|
||||
void AddBrushBevels( void );
|
||||
brush_t *FinishBrush( bool noCollapseGroups );
|
||||
|
||||
@@ -1634,8 +1679,8 @@ void FixTJunctions( entity_t *e );
|
||||
/* fog.c */
|
||||
winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds );
|
||||
void FogDrawSurfaces( entity_t *e );
|
||||
int FogForPoint( vec3_t point, float epsilon );
|
||||
int FogForBounds( vec3_t mins, vec3_t maxs, float epsilon );
|
||||
int FogForPoint( const Vector3& point, float epsilon );
|
||||
int FogForBounds( const MinMax& minmax, float epsilon );
|
||||
void CreateMapFogs( void );
|
||||
|
||||
|
||||
@@ -1650,7 +1695,7 @@ void PicoPrintFunc( int level, const char *str );
|
||||
void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize );
|
||||
picoModel_t *FindModel( const char *name, int frame );
|
||||
picoModel_t *LoadModel( const char *name, int frame );
|
||||
void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth );
|
||||
void InsertModel( const char *name, int skin, int frame, const Matrix4& transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth );
|
||||
void AddTriangleModels( entity_t *e );
|
||||
|
||||
|
||||
@@ -1660,7 +1705,7 @@ void FinishSurface( mapDrawSurface_t *ds );
|
||||
void StripFaceSurface( mapDrawSurface_t *ds );
|
||||
void MaxAreaFaceSurface( mapDrawSurface_t *ds );
|
||||
bool CalcSurfaceTextureRange( mapDrawSurface_t *ds );
|
||||
bool CalcLightmapAxis( vec3_t normal, vec3_t axis );
|
||||
bool CalcLightmapAxis( const Vector3& normal, Vector3& axis );
|
||||
void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds );
|
||||
void ClassifyEntitySurfaces( entity_t *e );
|
||||
void TidyEntitySurfaces( entity_t *e );
|
||||
@@ -1671,7 +1716,7 @@ void ClearSurface( mapDrawSurface_t *ds );
|
||||
void AddEntitySurfaceModels( entity_t *e );
|
||||
mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, winding_t *w );
|
||||
mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh );
|
||||
mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, const char *flareShader, int lightStyle );
|
||||
mapDrawSurface_t *DrawSurfaceForFlare( int entNum, const Vector3& origin, const Vector3& normal, const Vector3& color, const char *flareShader, int lightStyle );
|
||||
mapDrawSurface_t *DrawSurfaceForShader( const char *shader );
|
||||
void ClipSidesIntoTree( entity_t *e, tree_t *tree );
|
||||
void MakeDebugPortalSurfs( tree_t *tree );
|
||||
@@ -1715,7 +1760,7 @@ int GetSurfaceExtraRecvShadows( int num );
|
||||
int GetSurfaceExtraSampleSize( int num );
|
||||
int GetSurfaceExtraMinSampleSize( int num );
|
||||
float GetSurfaceExtraLongestCurve( int num );
|
||||
void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis );
|
||||
void GetSurfaceExtraLightmapAxis( int num, Vector3& lightmapAxis );
|
||||
|
||||
void WriteSurfaceExtraFile( const char *path );
|
||||
void LoadSurfaceExtraFile( const char *path );
|
||||
@@ -1726,11 +1771,7 @@ void ProcessDecals( void );
|
||||
void MakeEntityDecals( entity_t *e );
|
||||
|
||||
/* map.c */
|
||||
void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv );
|
||||
|
||||
/* brush_primit.c */
|
||||
void ComputeAxisBase( vec3_t normal, vec3_t texX, vec3_t texY );
|
||||
|
||||
void TextureAxisFromPlane( const plane_t *pln, Vector3& xv, Vector3& yv );
|
||||
|
||||
/* vis.c */
|
||||
fixedWinding_t *NewFixedWinding( int points );
|
||||
@@ -1749,9 +1790,9 @@ void PassagePortalFlow( int portalnum );
|
||||
|
||||
|
||||
/* light.c */
|
||||
float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w );
|
||||
float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t *w );
|
||||
int LightContributionToSample( trace_t *trace );
|
||||
void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colors[ MAX_LIGHTMAPS ] );
|
||||
void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] );
|
||||
bool LightContributionToPoint( trace_t *trace );
|
||||
int LightMain( int argc, char **argv );
|
||||
|
||||
@@ -1763,7 +1804,7 @@ float SetupTrace( trace_t *trace );
|
||||
|
||||
|
||||
/* light_bounce.c */
|
||||
bool RadSampleImage( byte * pixels, int width, int height, float st[ 2 ], float color[ 4 ] );
|
||||
bool RadSampleImage( byte * pixels, int width, int height, const Vector2& st, Color4f& color );
|
||||
void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t *si, float scale, float subdivide, clipWork_t *cw );
|
||||
void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t *si, float scale, float subdivide, clipWork_t *cw );
|
||||
void RadCreateDiffuseLights( void );
|
||||
@@ -1771,7 +1812,7 @@ void RadFreeLights();
|
||||
|
||||
|
||||
/* light_ydnar.c */
|
||||
void ColorToBytes( const float *color, byte *colorBytes, float scale );
|
||||
void ColorToBytes( const Vector3& color, Vector3b& colorBytes, float scale );
|
||||
void SmoothNormals( void );
|
||||
|
||||
void MapRawLightmap( int num );
|
||||
@@ -1793,14 +1834,14 @@ void SetupBrushesFlags( int mask_any, int test_any, int m
|
||||
void SetupBrushes( void );
|
||||
void SetupClusters( void );
|
||||
bool ClusterVisible( int a, int b );
|
||||
bool ClusterVisibleToPoint( vec3_t point, int cluster );
|
||||
int ClusterForPoint( vec3_t point );
|
||||
int ClusterForPointExt( vec3_t point, float epsilon );
|
||||
int ClusterForPointExtFilter( vec3_t point, float epsilon, int numClusters, int *clusters );
|
||||
int ShaderForPointInLeaf( vec3_t point, int leafNum, float epsilon, int wantContentFlags, int wantSurfaceFlags, int *contentFlags, int *surfaceFlags );
|
||||
bool ClusterVisibleToPoint( const Vector3& point, int cluster );
|
||||
int ClusterForPoint( const Vector3& point );
|
||||
int ClusterForPointExt( const Vector3& point, float epsilon );
|
||||
int ClusterForPointExtFilter( const Vector3& point, float epsilon, int numClusters, int *clusters );
|
||||
int ShaderForPointInLeaf( const Vector3& point, int leafNum, float epsilon, int wantContentFlags, int wantSurfaceFlags, int *contentFlags, int *surfaceFlags );
|
||||
void SetupEnvelopes( bool forGrid, bool fastFlag );
|
||||
void FreeTraceLights( trace_t *trace );
|
||||
void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace );
|
||||
void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace );
|
||||
void CreateTraceLightsForSurface( int num, trace_t *trace );
|
||||
|
||||
|
||||
@@ -1829,7 +1870,7 @@ image_t *ImageLoad( const char *filename );
|
||||
/* shaders.c */
|
||||
void ColorMod( colorMod_t *am, int numVerts, bspDrawVert_t *drawVerts );
|
||||
|
||||
void TCMod( tcMod_t mod, float st[ 2 ] );
|
||||
void TCMod( tcMod_t mod, Vector2& st );
|
||||
void TCModIdentity( tcMod_t mod );
|
||||
void TCModMultiply( tcMod_t a, tcMod_t b, tcMod_t out );
|
||||
void TCModTranslate( tcMod_t mod, float s, float t );
|
||||
@@ -2085,7 +2126,7 @@ Q_EXTERN plane_t *mapplanes Q_ASSIGN( NULL ); /* mapplanes[ num ^ 1
|
||||
Q_EXTERN int nummapplanes Q_ASSIGN( 0 ); /* nummapplanes will always be even */
|
||||
Q_EXTERN int allocatedmapplanes Q_ASSIGN( 0 );
|
||||
Q_EXTERN int numMapPatches;
|
||||
Q_EXTERN vec3_t mapMins, mapMaxs;
|
||||
Q_EXTERN MinMax g_mapMinmax;
|
||||
|
||||
Q_EXTERN int defaultFogNum Q_ASSIGN( -1 ); /* ydnar: cleaner fog handling */
|
||||
Q_EXTERN int numMapFogs Q_ASSIGN( 0 );
|
||||
@@ -2114,7 +2155,7 @@ Q_EXTERN int numRedundantIndexes;
|
||||
|
||||
Q_EXTERN int numSurfaceModels Q_ASSIGN( 0 );
|
||||
|
||||
Q_EXTERN byte debugColors[ 12 ][ 3 ]
|
||||
Q_EXTERN Vector3b debugColors[ 12 ]
|
||||
#ifndef MAIN_C
|
||||
;
|
||||
#else
|
||||
@@ -2136,7 +2177,7 @@ Q_EXTERN byte debugColors[ 12 ][ 3 ]
|
||||
#endif
|
||||
|
||||
Q_EXTERN int skyboxArea Q_ASSIGN( -1 );
|
||||
Q_EXTERN m4x4_t skyboxTransform;
|
||||
Q_EXTERN Matrix4 skyboxTransform;
|
||||
|
||||
|
||||
|
||||
@@ -2255,7 +2296,7 @@ Q_EXTERN float dirtGain Q_ASSIGN( 1.0f );
|
||||
Q_EXTERN bool debugnormals Q_ASSIGN( false );
|
||||
Q_EXTERN bool floodlighty Q_ASSIGN( false );
|
||||
Q_EXTERN bool floodlight_lowquality Q_ASSIGN( false );
|
||||
Q_EXTERN vec3_t floodlightRGB;
|
||||
Q_EXTERN Vector3 floodlightRGB;
|
||||
Q_EXTERN float floodlightIntensity Q_ASSIGN( 512.0f );
|
||||
Q_EXTERN float floodlightDistance Q_ASSIGN( 1024.0f );
|
||||
Q_EXTERN float floodlightDirectionScale Q_ASSIGN( 1.0f );
|
||||
@@ -2343,15 +2384,15 @@ Q_EXTERN FILE *dumpFile;
|
||||
|
||||
Q_EXTERN int defaultLightSubdivide Q_ASSIGN( 999 );
|
||||
|
||||
Q_EXTERN vec3_t ambientColor;
|
||||
Q_EXTERN vec3_t minLight, minVertexLight, minGridLight;
|
||||
Q_EXTERN Vector3 ambientColor;
|
||||
Q_EXTERN Vector3 minLight, minVertexLight, minGridLight;
|
||||
Q_EXTERN float maxLight Q_ASSIGN( 255.f );
|
||||
|
||||
Q_EXTERN int *entitySurface;
|
||||
Q_EXTERN vec3_t *surfaceOrigin;
|
||||
Q_EXTERN Vector3 *surfaceOrigin;
|
||||
|
||||
Q_EXTERN vec3_t sunDirection;
|
||||
Q_EXTERN vec3_t sunLight;
|
||||
Q_EXTERN Vector3 sunDirection;
|
||||
Q_EXTERN Vector3 sunLight;
|
||||
|
||||
/* ydnar: light optimization */
|
||||
Q_EXTERN float subdivideThreshold Q_ASSIGN( DEFAULT_SUBDIVIDE_THRESHOLD );
|
||||
@@ -2392,8 +2433,15 @@ Q_EXTERN rawLightmap_t *rawLightmaps Q_ASSIGN( NULL );
|
||||
Q_EXTERN int *sortLightmaps Q_ASSIGN( NULL );
|
||||
|
||||
/* vertex luxels */
|
||||
Q_EXTERN float *vertexLuxels[ MAX_LIGHTMAPS ];
|
||||
Q_EXTERN float *radVertexLuxels[ MAX_LIGHTMAPS ];
|
||||
Q_EXTERN Vector3 *vertexLuxels[ MAX_LIGHTMAPS ];
|
||||
Q_EXTERN Vector3 *radVertexLuxels[ MAX_LIGHTMAPS ];
|
||||
|
||||
inline Vector3& getVertexLuxel( int lightmapNum, int vertexNum ){
|
||||
return vertexLuxels[lightmapNum][vertexNum];
|
||||
}
|
||||
inline Vector3& getRadVertexLuxel( int lightmapNum, int vertexNum ){
|
||||
return radVertexLuxels[lightmapNum][vertexNum];
|
||||
}
|
||||
|
||||
/* bsp lightmaps */
|
||||
Q_EXTERN int numLightmapShaders Q_ASSIGN( 0 );
|
||||
@@ -2426,9 +2474,9 @@ Q_EXTERN int numLuxelsIlluminated Q_ASSIGN( 0 );
|
||||
Q_EXTERN int numVertsIlluminated Q_ASSIGN( 0 );
|
||||
|
||||
/* lightgrid */
|
||||
Q_EXTERN vec3_t gridMins;
|
||||
Q_EXTERN Vector3 gridMins;
|
||||
Q_EXTERN int gridBounds[ 3 ];
|
||||
Q_EXTERN vec3_t gridSize
|
||||
Q_EXTERN Vector3 gridSize
|
||||
#ifndef MAIN_C
|
||||
;
|
||||
#else
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){
|
||||
int i, j, k;
|
||||
float c;
|
||||
vec4_t mult, add;
|
||||
Vector4 mult, add;
|
||||
bspDrawVert_t *dv;
|
||||
colorMod_t *cm2;
|
||||
|
||||
@@ -62,17 +62,16 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){
|
||||
for ( cm2 = cm; cm2 != NULL; cm2 = cm2->next )
|
||||
{
|
||||
/* default */
|
||||
VectorSet( mult, 1.0f, 1.0f, 1.0f );
|
||||
mult[ 3 ] = 1.0f;
|
||||
VectorSet( add, 0.0f, 0.0f, 0.0f );
|
||||
add[ 3 ] = 0.0f;
|
||||
mult.set( 1 );
|
||||
add.set( 0 );
|
||||
|
||||
const Vector3 cm2_data = vector3_from_array( cm2->data );
|
||||
/* switch on type */
|
||||
switch ( cm2->type )
|
||||
{
|
||||
case EColorMod::ColorSet:
|
||||
VectorClear( mult );
|
||||
VectorScale( cm2->data, 255.0f, add );
|
||||
mult.vec3().set( 0 );
|
||||
add.vec3() = cm2_data * 255.0f;
|
||||
break;
|
||||
|
||||
case EColorMod::AlphaSet:
|
||||
@@ -81,7 +80,7 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){
|
||||
break;
|
||||
|
||||
case EColorMod::ColorScale:
|
||||
VectorCopy( cm2->data, mult );
|
||||
mult.vec3() = cm2_data;
|
||||
break;
|
||||
|
||||
case EColorMod::AlphaScale:
|
||||
@@ -89,46 +88,46 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){
|
||||
break;
|
||||
|
||||
case EColorMod::ColorDotProduct:
|
||||
c = DotProduct( dv->normal, cm2->data );
|
||||
VectorSet( mult, c, c, c );
|
||||
c = vector3_dot( dv->normal, cm2_data );
|
||||
mult.vec3().set( c );
|
||||
break;
|
||||
|
||||
case EColorMod::ColorDotProductScale:
|
||||
c = DotProduct( dv->normal, cm2->data );
|
||||
c = vector3_dot( dv->normal, cm2_data );
|
||||
c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
|
||||
VectorSet( mult, c, c, c );
|
||||
mult.vec3().set( c );
|
||||
break;
|
||||
|
||||
case EColorMod::AlphaDotProduct:
|
||||
mult[ 3 ] = DotProduct( dv->normal, cm2->data );
|
||||
mult[ 3 ] = vector3_dot( dv->normal, cm2_data );
|
||||
break;
|
||||
|
||||
case EColorMod::AlphaDotProductScale:
|
||||
c = DotProduct( dv->normal, cm2->data );
|
||||
c = vector3_dot( dv->normal, cm2_data );
|
||||
c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
|
||||
mult[ 3 ] = c;
|
||||
break;
|
||||
|
||||
case EColorMod::ColorDotProduct2:
|
||||
c = DotProduct( dv->normal, cm2->data );
|
||||
c = vector3_dot( dv->normal, cm2_data );
|
||||
c *= c;
|
||||
VectorSet( mult, c, c, c );
|
||||
mult.vec3().set( c );
|
||||
break;
|
||||
|
||||
case EColorMod::ColorDotProduct2Scale:
|
||||
c = DotProduct( dv->normal, cm2->data );
|
||||
c = vector3_dot( dv->normal, cm2_data );
|
||||
c *= c;
|
||||
c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
|
||||
VectorSet( mult, c, c, c );
|
||||
mult.vec3().set( c );
|
||||
break;
|
||||
|
||||
case EColorMod::AlphaDotProduct2:
|
||||
mult[ 3 ] = DotProduct( dv->normal, cm2->data );
|
||||
mult[ 3 ] = vector3_dot( dv->normal, cm2_data );
|
||||
mult[ 3 ] *= mult[ 3 ];
|
||||
break;
|
||||
|
||||
case EColorMod::AlphaDotProduct2Scale:
|
||||
c = DotProduct( dv->normal, cm2->data );
|
||||
c = vector3_dot( dv->normal, cm2_data );
|
||||
c *= c;
|
||||
c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] );
|
||||
mult[ 3 ] = c;
|
||||
@@ -164,7 +163,7 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){
|
||||
routines for dealing with a 3x3 texture mod matrix
|
||||
*/
|
||||
|
||||
void TCMod( tcMod_t mod, float st[ 2 ] ){
|
||||
void TCMod( tcMod_t mod, Vector2& st ){
|
||||
float old[ 2 ];
|
||||
|
||||
|
||||
@@ -215,7 +214,7 @@ void TCModRotate( tcMod_t mod, float euler ){
|
||||
memcpy( old, mod, sizeof( tcMod_t ) );
|
||||
TCModIdentity( temp );
|
||||
|
||||
radians = euler / 180 * Q_PI;
|
||||
radians = degrees_to_radians( euler );
|
||||
sinv = sin( radians );
|
||||
cosv = cos( radians );
|
||||
|
||||
@@ -663,8 +662,7 @@ static shaderInfo_t *AllocShaderInfo( void ){
|
||||
|
||||
void FinishShader( shaderInfo_t *si ){
|
||||
int x, y;
|
||||
float st[ 2 ], o[ 2 ], dist, bestDist;
|
||||
vec4_t color, delta;
|
||||
Vector2 st;
|
||||
|
||||
|
||||
/* don't double-dip */
|
||||
@@ -682,28 +680,26 @@ void FinishShader( shaderInfo_t *si ){
|
||||
if ( si->legacyTerrain && !si->tcGen ) {
|
||||
/* set xy texture projection */
|
||||
si->tcGen = true;
|
||||
VectorSet( si->vecs[ 0 ], ( 1.0f / ( si->shaderWidth * 0.5f ) ), 0, 0 );
|
||||
VectorSet( si->vecs[ 1 ], 0, ( 1.0f / ( si->shaderHeight * 0.5f ) ), 0 );
|
||||
si->vecs[ 0 ] = { ( 1.0f / ( si->shaderWidth * 0.5f ) ), 0, 0 };
|
||||
si->vecs[ 1 ] = { 0, ( 1.0f / ( si->shaderHeight * 0.5f ) ), 0 };
|
||||
}
|
||||
|
||||
/* find pixel coordinates best matching the average color of the image */
|
||||
bestDist = 99999999;
|
||||
o[ 0 ] = 1.0f / si->shaderImage->width;
|
||||
o[ 1 ] = 1.0f / si->shaderImage->height;
|
||||
float bestDist = 99999999;
|
||||
const Vector2 o( 1.0f / si->shaderImage->width, 1.0f / si->shaderImage->height );
|
||||
for ( y = 0, st[ 1 ] = 0.0f; y < si->shaderImage->height; y++, st[ 1 ] += o[ 1 ] )
|
||||
{
|
||||
for ( x = 0, st[ 0 ] = 0.0f; x < si->shaderImage->width; x++, st[ 0 ] += o[ 0 ] )
|
||||
{
|
||||
/* sample the shader image */
|
||||
Color4f color;
|
||||
RadSampleImage( si->shaderImage->pixels, si->shaderImage->width, si->shaderImage->height, st, color );
|
||||
|
||||
/* determine error squared */
|
||||
VectorSubtract( color, si->averageColor, delta );
|
||||
delta[ 3 ] = color[ 3 ] - si->averageColor[ 3 ];
|
||||
dist = delta[ 0 ] * delta[ 0 ] + delta[ 1 ] * delta[ 1 ] + delta[ 2 ] * delta[ 2 ] + delta[ 3 ] * delta[ 3 ];
|
||||
const Color4f delta = color - si->averageColor;
|
||||
const float dist = vector4_dot( delta, delta );
|
||||
if ( dist < bestDist ) {
|
||||
si->stFlat[ 0 ] = st[ 0 ];
|
||||
si->stFlat[ 1 ] = st[ 1 ];
|
||||
si->stFlat = st;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -725,9 +721,6 @@ void FinishShader( shaderInfo_t *si ){
|
||||
*/
|
||||
|
||||
static void LoadShaderImages( shaderInfo_t *si ){
|
||||
int i, count;
|
||||
float color[ 4 ];
|
||||
|
||||
|
||||
/* nodraw shaders don't need images */
|
||||
if ( si->compileFlags & C_NODRAW ) {
|
||||
@@ -779,10 +772,9 @@ static void LoadShaderImages( shaderInfo_t *si ){
|
||||
}
|
||||
|
||||
/* create default and average colors */
|
||||
count = si->lightImage->width * si->lightImage->height;
|
||||
VectorClear( color );
|
||||
color[ 3 ] = 0.0f;
|
||||
for ( i = 0; i < count; i++ )
|
||||
const int count = si->lightImage->width * si->lightImage->height;
|
||||
Color4f color( 0, 0, 0, 0 );
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
color[ 0 ] += si->lightImage->pixels[ i * 4 + 0 ];
|
||||
color[ 1 ] += si->lightImage->pixels[ i * 4 + 1 ];
|
||||
@@ -790,15 +782,15 @@ static void LoadShaderImages( shaderInfo_t *si ){
|
||||
color[ 3 ] += si->lightImage->pixels[ i * 4 + 3 ];
|
||||
}
|
||||
|
||||
if ( VectorLength( si->color ) <= 0.0f ) {
|
||||
ColorNormalize( color, si->color );
|
||||
VectorScale( color, ( 1.0f / count ), si->averageColor );
|
||||
si->averageColor[ 3 ] = color[ 3 ] / count;
|
||||
if ( vector3_length( si->color ) == 0.0f ) {
|
||||
si->color = color.rgb();
|
||||
ColorNormalize( si->color );
|
||||
si->averageColor = color / count;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( si->color, si->averageColor );
|
||||
si->averageColor[ 3 ] = 1.0f;
|
||||
si->averageColor.rgb() = si->color;
|
||||
si->averageColor.alpha() = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,14 +913,12 @@ bool GetTokenAppend( char *buffer, bool crossline ){
|
||||
}
|
||||
|
||||
|
||||
void Parse1DMatrixAppend( char *buffer, int x, vec_t *m ){
|
||||
int i;
|
||||
|
||||
void Parse1DMatrixAppend( char *buffer, int x, float *m ){
|
||||
|
||||
if ( !GetTokenAppend( buffer, true ) || !strEqual( token, "(" ) ) {
|
||||
Error( "Parse1DMatrixAppend(): line %d: ( not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation );
|
||||
}
|
||||
for ( i = 0; i < x; i++ )
|
||||
for ( int i = 0; i < x; i++ )
|
||||
{
|
||||
if ( !GetTokenAppend( buffer, false ) ) {
|
||||
Error( "Parse1DMatrixAppend(): line %d: Number not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation );
|
||||
@@ -968,7 +958,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
if ( si != NULL && !strEmpty( shaderText ) ) {
|
||||
strcat( shaderText, "\n" );
|
||||
si->shaderText = copystring( shaderText );
|
||||
//% if( VectorLength( si->vecs[ 0 ] ) )
|
||||
//% if( vector3_length( si->vecs[ 0 ] ) )
|
||||
//% Sys_Printf( "%s\n", shaderText );
|
||||
}
|
||||
|
||||
@@ -1119,7 +1109,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
|
||||
/* deformVertexes move <x> <y> <z> <func> <base> <amplitude> <phase> <freq> (ydnar: for particle studio support) */
|
||||
if ( striEqual( token, "move" ) ) {
|
||||
vec3_t amt, mins, maxs;
|
||||
Vector3 amt;
|
||||
float base, amp;
|
||||
|
||||
|
||||
@@ -1136,10 +1126,10 @@ static void ParseShaderFile( const char *filename ){
|
||||
GetTokenAppend( shaderText, false ); amp = atof( token );
|
||||
|
||||
/* calculate */
|
||||
VectorScale( amt, base, mins );
|
||||
VectorMA( mins, amp, amt, maxs );
|
||||
VectorAdd( si->mins, mins, si->mins );
|
||||
VectorAdd( si->maxs, maxs, si->maxs );
|
||||
const Vector3 mins = amt * base;
|
||||
const Vector3 maxs = amt * amp + mins;
|
||||
si->minmax.mins += mins;
|
||||
si->minmax.maxs += maxs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1271,7 +1261,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
}
|
||||
|
||||
/* normalize it */
|
||||
ColorNormalize( sun->color, sun->color );
|
||||
ColorNormalize( sun->color );
|
||||
|
||||
/* scale color by brightness */
|
||||
GetTokenAppend( shaderText, false );
|
||||
@@ -1279,12 +1269,10 @@ static void ParseShaderFile( const char *filename ){
|
||||
|
||||
/* get sun angle/elevation */
|
||||
GetTokenAppend( shaderText, false );
|
||||
a = atof( token );
|
||||
a = a / 180.0f * Q_PI;
|
||||
a = degrees_to_radians( atof( token ) );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
b = atof( token );
|
||||
b = b / 180.0f * Q_PI;
|
||||
b = degrees_to_radians( atof( token ) );
|
||||
|
||||
sun->direction[ 0 ] = cos( a ) * cos( b );
|
||||
sun->direction[ 1 ] = sin( a ) * cos( b );
|
||||
@@ -1296,8 +1284,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
/* ydnar: get sun angular deviance/samples */
|
||||
if ( ext && TokenAvailable() ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
sun->deviance = atof( token );
|
||||
sun->deviance = sun->deviance / 180.0f * Q_PI;
|
||||
sun->deviance = degrees_to_radians( atof( token ) );
|
||||
|
||||
GetTokenAppend( shaderText, false );
|
||||
sun->numSamples = atoi( token );
|
||||
@@ -1436,7 +1423,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
|
||||
/* wolf: q3map_lightRGB <red> <green> <blue> */
|
||||
else if ( striEqual( token, "q3map_lightRGB" ) ) {
|
||||
VectorClear( si->color );
|
||||
si->color.set( 0 );
|
||||
GetTokenAppend( shaderText, false );
|
||||
si->color[ 0 ] = atof( token );
|
||||
GetTokenAppend( shaderText, false );
|
||||
@@ -1448,7 +1435,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
si->color[1] = Image_LinearFloatFromsRGBFloat( si->color[1] );
|
||||
si->color[2] = Image_LinearFloatFromsRGBFloat( si->color[2] );
|
||||
}
|
||||
ColorNormalize( si->color, si->color );
|
||||
ColorNormalize( si->color );
|
||||
}
|
||||
|
||||
/* q3map_lightSubdivide <value> */
|
||||
@@ -1485,7 +1472,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
si->floodlightRGB[1] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[1] );
|
||||
si->floodlightRGB[2] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[2] );
|
||||
}
|
||||
ColorNormalize( si->floodlightRGB, si->floodlightRGB );
|
||||
ColorNormalize( si->floodlightRGB );
|
||||
}
|
||||
|
||||
/* jal: q3map_nodirty : skip dirty */
|
||||
@@ -1517,18 +1504,18 @@ static void ParseShaderFile( const char *filename ){
|
||||
else if ( striEqual( token, "q3map_lightmapAxis" ) ) {
|
||||
GetTokenAppend( shaderText, false );
|
||||
if ( striEqual( token, "x" ) ) {
|
||||
VectorSet( si->lightmapAxis, 1, 0, 0 );
|
||||
si->lightmapAxis = g_vector3_axis_x;
|
||||
}
|
||||
else if ( striEqual( token, "y" ) ) {
|
||||
VectorSet( si->lightmapAxis, 0, 1, 0 );
|
||||
si->lightmapAxis = g_vector3_axis_y;
|
||||
}
|
||||
else if ( striEqual( token, "z" ) ) {
|
||||
VectorSet( si->lightmapAxis, 0, 0, 1 );
|
||||
si->lightmapAxis = g_vector3_axis_z;
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Warning( "Unknown value for lightmap axis: %s\n", token );
|
||||
VectorClear( si->lightmapAxis );
|
||||
si->lightmapAxis.set( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1636,7 +1623,7 @@ static void ParseShaderFile( const char *filename ){
|
||||
si->nonplanar = true;
|
||||
si->forceMeta = true;
|
||||
si->shadeAngleDegrees = 179.0f;
|
||||
//% VectorSet( si->lightmapAxis, 0, 0, 1 ); /* ydnar 2002-09-21: turning this off for better lightmapping of cliff faces */
|
||||
//% si->lightmapAxis = g_vector3_axis_z; /* ydnar 2002-09-21: turning this off for better lightmapping of cliff faces */
|
||||
}
|
||||
|
||||
/* ydnar: picomodel: q3map_forceMeta (forces brush faces and/or triangle models to go through the metasurface pipeline) */
|
||||
@@ -1665,14 +1652,14 @@ static void ParseShaderFile( const char *filename ){
|
||||
|
||||
/* q3map_tcGen vector <s vector> <t vector> */
|
||||
if ( striEqual( token, "vector" ) ) {
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ] );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ] );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ].data() );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ].data() );
|
||||
}
|
||||
|
||||
/* q3map_tcGen ivector <1.0/s vector> <1.0/t vector> (inverse vector, easier for mappers to understand) */
|
||||
else if ( striEqual( token, "ivector" ) ) {
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ] );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ] );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ].data() );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ].data() );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
si->vecs[ 0 ][ i ] = si->vecs[ 0 ][ i ] ? 1.0 / si->vecs[ 0 ][ i ] : 0;
|
||||
@@ -1682,8 +1669,8 @@ static void ParseShaderFile( const char *filename ){
|
||||
else
|
||||
{
|
||||
Sys_Warning( "Unknown q3map_tcGen method: %s\n", token );
|
||||
VectorClear( si->vecs[ 0 ] );
|
||||
VectorClear( si->vecs[ 1 ] );
|
||||
si->vecs[ 0 ].set( 0 );
|
||||
si->vecs[ 1 ].set( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1825,8 +1812,8 @@ static void ParseShaderFile( const char *filename ){
|
||||
|
||||
/* q3map_fogDir (direction a fog shader fades from transparent to opaque) */
|
||||
else if ( striEqual( token, "q3map_fogDir" ) ) {
|
||||
Parse1DMatrixAppend( shaderText, 3, si->fogDir );
|
||||
VectorNormalize( si->fogDir, si->fogDir );
|
||||
Parse1DMatrixAppend( shaderText, 3, si->fogDir.data() );
|
||||
VectorNormalize( si->fogDir );
|
||||
}
|
||||
|
||||
/* q3map_globaltexture */
|
||||
|
||||
+236
-381
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,7 @@ struct surfaceExtra_t
|
||||
int castShadows, recvShadows;
|
||||
int sampleSize;
|
||||
float longestCurve;
|
||||
vec3_t lightmapAxis;
|
||||
Vector3 lightmapAxis;
|
||||
};
|
||||
|
||||
#define GROW_SURFACE_EXTRAS 1024
|
||||
@@ -117,7 +117,7 @@ void SetSurfaceExtra( mapDrawSurface_t *ds, int num ){
|
||||
se->recvShadows = ds->recvShadows;
|
||||
se->sampleSize = ds->sampleSize;
|
||||
se->longestCurve = ds->longestCurve;
|
||||
VectorCopy( ds->lightmapAxis, se->lightmapAxis );
|
||||
se->lightmapAxis = ds->lightmapAxis;
|
||||
|
||||
/* debug code */
|
||||
//% Sys_FPrintf( SYS_VRB, "SetSurfaceExtra(): entityNum = %d\n", ds->entityNum );
|
||||
@@ -180,9 +180,9 @@ float GetSurfaceExtraLongestCurve( int num ){
|
||||
}
|
||||
|
||||
|
||||
void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis ){
|
||||
void GetSurfaceExtraLightmapAxis( int num, Vector3& lightmapAxis ){
|
||||
surfaceExtra_t *se = GetSurfaceExtra( num );
|
||||
VectorCopy( se->lightmapAxis, lightmapAxis );
|
||||
lightmapAxis = se->lightmapAxis;
|
||||
}
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ void LoadSurfaceExtraFile( const char *path ){
|
||||
|
||||
/* lightmap axis vector */
|
||||
else if ( striEqual( token, "lightmapAxis" ) ) {
|
||||
Parse1DMatrix( 3, se->lightmapAxis );
|
||||
Parse1DMatrix( 3, se->lightmapAxis.data() );
|
||||
}
|
||||
|
||||
/* ignore all other tokens on the line */
|
||||
|
||||
@@ -57,8 +57,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
|
||||
/* plane test */
|
||||
{
|
||||
vec4_t plane;
|
||||
|
||||
Plane3f plane;
|
||||
|
||||
/* make a plane */
|
||||
if ( !PlaneFromPoints( plane, tri[ 0 ]->xyz, tri[ 1 ]->xyz, tri[ 2 ]->xyz ) ) {
|
||||
@@ -66,7 +65,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
}
|
||||
|
||||
/* if normal is too far off vertical, then don't place an instance */
|
||||
if ( plane[ 2 ] < 0.5f ) {
|
||||
if ( plane.normal().z() < 0.5f ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +73,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
/* subdivide calc */
|
||||
{
|
||||
int i;
|
||||
float *a, *b, dx, dy, dz, dist, maxDist;
|
||||
float dx, dy, dz, dist, maxDist;
|
||||
foliageInstance_t *fi;
|
||||
|
||||
|
||||
@@ -84,13 +83,13 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
/* find the longest edge and split it */
|
||||
max = -1;
|
||||
maxDist = 0.0f;
|
||||
VectorClear( fi->xyz );
|
||||
VectorClear( fi->normal );
|
||||
fi->xyz.set( 0 );
|
||||
fi->normal.set( 0 );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
/* get verts */
|
||||
a = tri[ i ]->xyz;
|
||||
b = tri[ ( i + 1 ) % 3 ]->xyz;
|
||||
const Vector3& a = tri[ i ]->xyz;
|
||||
const Vector3& b = tri[ ( i + 1 ) % 3 ]->xyz;
|
||||
|
||||
/* get dists */
|
||||
dx = a[ 0 ] - b[ 0 ];
|
||||
@@ -105,8 +104,8 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
}
|
||||
|
||||
/* add to centroid */
|
||||
VectorAdd( fi->xyz, tri[ i ]->xyz, fi->xyz );
|
||||
VectorAdd( fi->normal, tri[ i ]->normal, fi->normal );
|
||||
fi->xyz += tri[ i ]->xyz;
|
||||
fi->normal += tri[ i ]->normal;
|
||||
}
|
||||
|
||||
/* is the triangle small enough? */
|
||||
@@ -120,7 +119,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = ( (float) tri[ 0 ]->color[ 0 ][ 3 ] + (float) tri[ 1 ]->color[ 0 ][ 3 ] + (float) tri[ 2 ]->color[ 0 ][ 3 ] ) / 765.0f;
|
||||
alpha = ( (float) tri[ 0 ]->color[ 0 ].alpha() + (float) tri[ 1 ]->color[ 0 ].alpha() + (float) tri[ 2 ]->color[ 0 ].alpha() ) / 765.0f;
|
||||
if ( foliage.inverseAlpha == 1 ) {
|
||||
alpha = 1.0f - alpha;
|
||||
}
|
||||
@@ -137,8 +136,8 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f
|
||||
}
|
||||
|
||||
/* scale centroid */
|
||||
VectorScale( fi->xyz, 0.33333333f, fi->xyz );
|
||||
if ( VectorNormalize( fi->normal, fi->normal ) == 0.0f ) {
|
||||
fi->xyz *= 0.33333333f;
|
||||
if ( VectorNormalize( fi->normal ) == 0.0f ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,8 +174,6 @@ void Foliage( mapDrawSurface_t *src ){
|
||||
shaderInfo_t *si;
|
||||
mesh_t srcMesh, *subdivided, *mesh;
|
||||
bspDrawVert_t *verts, *dv[ 3 ], *fi;
|
||||
vec3_t scale;
|
||||
m4x4_t transform;
|
||||
|
||||
|
||||
/* get shader */
|
||||
@@ -270,12 +267,8 @@ void Foliage( mapDrawSurface_t *src ){
|
||||
/* remember surface count */
|
||||
oldNumMapDrawSurfs = numMapDrawSurfs;
|
||||
|
||||
/* set transform matrix */
|
||||
VectorSet( scale, foliage.scale, foliage.scale, foliage.scale );
|
||||
m4x4_scale_for_vec3( transform, scale );
|
||||
|
||||
/* add the model to the bsp */
|
||||
InsertModel( foliage.model.c_str(), 0, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal );
|
||||
InsertModel( foliage.model.c_str(), 0, 0, matrix4_scale_for_vec3( Vector3().set( foliage.scale ) ), NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal );
|
||||
|
||||
/* walk each new surface */
|
||||
for ( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ )
|
||||
@@ -307,16 +300,13 @@ void Foliage( mapDrawSurface_t *src ){
|
||||
fi = &ds->verts[ ds->numVerts + j ];
|
||||
|
||||
/* copy xyz and normal */
|
||||
VectorCopy( foliageInstances[ j ].xyz, fi->xyz );
|
||||
VectorCopy( foliageInstances[ j ].normal, fi->normal );
|
||||
fi->xyz = foliageInstances[ j ].xyz;
|
||||
fi->normal = foliageInstances[ j ].normal;
|
||||
|
||||
/* ydnar: set color */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
fi->color[ k ][ 0 ] = 255;
|
||||
fi->color[ k ][ 1 ] = 255;
|
||||
fi->color[ k ][ 2 ] = 255;
|
||||
fi->color[ k ][ 3 ] = 255;
|
||||
fi->color[ k ].set( 255 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,10 +73,10 @@ void Fur( mapDrawSurface_t *ds ){
|
||||
dv = &ds->verts[ j ];
|
||||
|
||||
/* offset is scaled by original vertex alpha */
|
||||
a = (float) dv->color[ 0 ][ 3 ] / 255.0;
|
||||
a = (float) dv->color[ 0 ].alpha() / 255.0;
|
||||
|
||||
/* offset it */
|
||||
VectorMA( dv->xyz, ( offset * a ), dv->normal, dv->xyz );
|
||||
dv->xyz += dv->normal * ( offset * a );
|
||||
}
|
||||
|
||||
/* wash, rinse, repeat */
|
||||
@@ -98,27 +98,19 @@ void Fur( mapDrawSurface_t *ds ){
|
||||
dv = &ds->verts[ j ];
|
||||
|
||||
/* offset is scaled by original vertex alpha */
|
||||
a = (float) dv->color[ 0 ][ 3 ] / 255.0;
|
||||
a = (float) dv->color[ 0 ].alpha() / 255.0;
|
||||
|
||||
/* get fur vert */
|
||||
dv = &fur->verts[ j ];
|
||||
|
||||
/* offset it */
|
||||
VectorMA( dv->xyz, ( offset * a * i ), dv->normal, dv->xyz );
|
||||
dv->xyz += dv->normal * ( offset * a * i );
|
||||
|
||||
/* fade alpha */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
a = (float) dv->color[ k ][ 3 ] - fade;
|
||||
if ( a > 255.0f ) {
|
||||
dv->color[ k ][ 3 ] = 255;
|
||||
}
|
||||
else if ( a < 0 ) {
|
||||
dv->color[ k ][ 3 ] = 0;
|
||||
}
|
||||
else{
|
||||
dv->color[ k ][ 3 ] = a;
|
||||
}
|
||||
a = (float) dv->color[ k ].alpha() - fade;
|
||||
dv->color[ k ].alpha() = ( a > 255.0f )? 255 : ( a < 0 )? 0 : a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,21 +123,15 @@ static int AddMetaTriangle( void ){
|
||||
|
||||
int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *c, int planeNum ){
|
||||
int triIndex;
|
||||
vec3_t dir;
|
||||
|
||||
|
||||
|
||||
/* detect degenerate triangles fixme: do something proper here */
|
||||
VectorSubtract( a->xyz, b->xyz, dir );
|
||||
if ( VectorLength( dir ) < 0.125f ) {
|
||||
if ( vector3_length( a->xyz - b->xyz ) < 0.125f ) {
|
||||
return -1;
|
||||
}
|
||||
VectorSubtract( b->xyz, c->xyz, dir );
|
||||
if ( VectorLength( dir ) < 0.125f ) {
|
||||
if ( vector3_length( b->xyz - c->xyz ) < 0.125f ) {
|
||||
return -1;
|
||||
}
|
||||
VectorSubtract( c->xyz, a->xyz, dir );
|
||||
if ( VectorLength( dir ) < 0.125f ) {
|
||||
if ( vector3_length( c->xyz - a->xyz ) < 0.125f ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -145,8 +139,7 @@ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, b
|
||||
if ( planeNum >= 0 ) {
|
||||
/* because of precision issues with small triangles, try to use the specified plane */
|
||||
src->planeNum = planeNum;
|
||||
VectorCopy( mapplanes[ planeNum ].normal, src->plane );
|
||||
src->plane[ 3 ] = mapplanes[ planeNum ].dist;
|
||||
src->plane = mapplanes[ planeNum ].plane;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -158,14 +151,14 @@ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, b
|
||||
}
|
||||
|
||||
/* ydnar 2002-10-03: repair any bogus normals (busted ase import kludge) */
|
||||
if ( VectorLength( a->normal ) <= 0.0f ) {
|
||||
VectorCopy( src->plane, a->normal );
|
||||
if ( vector3_length( a->normal ) == 0.0f ) {
|
||||
a->normal = src->plane.normal();
|
||||
}
|
||||
if ( VectorLength( b->normal ) <= 0.0f ) {
|
||||
VectorCopy( src->plane, b->normal );
|
||||
if ( vector3_length( b->normal ) == 0.0f ) {
|
||||
b->normal = src->plane.normal();
|
||||
}
|
||||
if ( VectorLength( c->normal ) <= 0.0f ) {
|
||||
VectorCopy( src->plane, c->normal );
|
||||
if ( vector3_length( c->normal ) == 0.0f ) {
|
||||
c->normal = src->plane.normal();
|
||||
}
|
||||
|
||||
/* ydnar 2002-10-04: set lightmap axis if not already set */
|
||||
@@ -173,12 +166,12 @@ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, b
|
||||
src->lightmapAxis[ 0 ] == 0.0f && src->lightmapAxis[ 1 ] == 0.0f && src->lightmapAxis[ 2 ] == 0.0f ) {
|
||||
/* the shader can specify an explicit lightmap axis */
|
||||
if ( src->si->lightmapAxis[ 0 ] || src->si->lightmapAxis[ 1 ] || src->si->lightmapAxis[ 2 ] ) {
|
||||
VectorCopy( src->si->lightmapAxis, src->lightmapAxis );
|
||||
src->lightmapAxis = src->si->lightmapAxis;
|
||||
}
|
||||
|
||||
/* new axis-finding code */
|
||||
else{
|
||||
CalcLightmapAxis( src->plane, src->lightmapAxis );
|
||||
CalcLightmapAxis( src->plane.normal(), src->lightmapAxis );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +254,7 @@ static void SurfaceToMetaTriangles( mapDrawSurface_t *ds ){
|
||||
src.fogNum = ds->fogNum;
|
||||
src.sampleSize = ds->sampleSize;
|
||||
src.shadeAngleDegrees = ds->shadeAngleDegrees;
|
||||
VectorCopy( ds->lightmapAxis, src.lightmapAxis );
|
||||
src.lightmapAxis = ds->lightmapAxis;
|
||||
|
||||
/* copy drawverts */
|
||||
memcpy( &a, &ds->verts[ ds->indexes[ i ] ], sizeof( a ) );
|
||||
@@ -385,7 +378,6 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){
|
||||
int r, s, t, bestR = 0, bestS = 1, bestT = 2;
|
||||
int i, j;
|
||||
double A, bestA = -1, V, bestV = -1;
|
||||
vec3_t ab, ac, bc, cross;
|
||||
bspDrawVert_t *buf;
|
||||
double shiftWidth;
|
||||
|
||||
@@ -397,16 +389,12 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){
|
||||
A = 0;
|
||||
for ( i = 1; i + 1 < cnt; ++i )
|
||||
{
|
||||
VectorSubtract( vert[i].xyz, vert[0].xyz, ab );
|
||||
VectorSubtract( vert[i + 1].xyz, vert[0].xyz, ac );
|
||||
CrossProduct( ab, ac, cross );
|
||||
A += VectorLength( cross );
|
||||
A += vector3_length( vector3_cross( vert[i].xyz - vert[0].xyz, vert[i + 1].xyz - vert[0].xyz ) );
|
||||
}
|
||||
V = 0;
|
||||
for ( i = 0; i < cnt; ++i )
|
||||
{
|
||||
VectorSubtract( vert[( i + 1 ) % cnt].xyz, vert[i].xyz, ab );
|
||||
V += VectorLength( ab );
|
||||
V += vector3_length( vert[( i + 1 ) % cnt].xyz - vert[i].xyz );
|
||||
}
|
||||
|
||||
/* calculate shift width from the area sensibly, assuming the polygon
|
||||
@@ -429,13 +417,12 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){
|
||||
for ( s = r + 1; s + 1 < cnt; ++s )
|
||||
for ( t = s + 1; t < cnt; ++t )
|
||||
{
|
||||
VectorSubtract( vert[s].xyz, vert[r].xyz, ab );
|
||||
VectorSubtract( vert[t].xyz, vert[r].xyz, ac );
|
||||
VectorSubtract( vert[t].xyz, vert[s].xyz, bc );
|
||||
CrossProduct( ab, ac, cross );
|
||||
A = VectorLength( cross );
|
||||
const Vector3 ab = vert[s].xyz - vert[r].xyz;
|
||||
const Vector3 ac = vert[t].xyz - vert[r].xyz;
|
||||
const Vector3 bc = vert[t].xyz - vert[s].xyz;
|
||||
A = vector3_length( vector3_cross( ab, ac ) );
|
||||
|
||||
V = A - ( VectorLength( ab ) - VectorLength( ac ) - VectorLength( bc ) ) * shiftWidth;
|
||||
V = A - ( vector3_length( ab ) - vector3_length( ac ) - vector3_length( bc ) ) * shiftWidth;
|
||||
/* value = A - circumference * shiftWidth, i.e. we back out by shiftWidth units from each side, to prevent too acute triangles */
|
||||
/* this kind of simulates "number of shiftWidth*shiftWidth fragments in the triangle not touched by an edge" */
|
||||
|
||||
@@ -483,10 +470,7 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){
|
||||
}
|
||||
// abc abc abc abc abc abc
|
||||
|
||||
VectorSubtract( vert[bestS].xyz, vert[bestR].xyz, ab );
|
||||
VectorSubtract( vert[bestT].xyz, vert[bestR].xyz, ac );
|
||||
CrossProduct( ab, ac, cross );
|
||||
bestA = VectorLength( cross );
|
||||
bestA = vector3_length( vector3_cross( vert[bestS].xyz - vert[bestR].xyz, vert[bestT].xyz - vert[bestR].xyz ) );
|
||||
}
|
||||
|
||||
if ( bestA < TINY_AREA ) {
|
||||
@@ -599,7 +583,9 @@ void MaxAreaFaceSurface( mapDrawSurface_t *ds ){
|
||||
|
||||
void FanFaceSurface( mapDrawSurface_t *ds ){
|
||||
int i, j, k, a, b, c;
|
||||
int color[ MAX_LIGHTMAPS ][ 4 ] = {{0}};
|
||||
BasicVector4<int> color[ MAX_LIGHTMAPS ];
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
color[k].set( 0 );
|
||||
bspDrawVert_t *verts, *centroid, *dv;
|
||||
double iv;
|
||||
|
||||
@@ -620,37 +606,28 @@ void FanFaceSurface( mapDrawSurface_t *ds ){
|
||||
centroid = &verts[ 0 ];
|
||||
for ( i = 1, dv = &verts[ 1 ]; i < ( ds->numVerts + 1 ); i++, dv++ )
|
||||
{
|
||||
VectorAdd( centroid->xyz, dv->xyz, centroid->xyz );
|
||||
VectorAdd( centroid->normal, dv->normal, centroid->normal );
|
||||
for ( j = 0; j < 4; j++ )
|
||||
{
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
color[ k ][ j ] += dv->color[ k ][ j ];
|
||||
if ( j < 2 ) {
|
||||
centroid->st[ j ] += dv->st[ j ];
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
centroid->lightmap[ k ][ j ] += dv->lightmap[ k ][ j ];
|
||||
}
|
||||
centroid->xyz += dv->xyz;
|
||||
centroid->normal += dv->normal;
|
||||
centroid->st += dv->st;
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ ){
|
||||
color[ k ] += dv->color[ k ];
|
||||
centroid->lightmap[ k ] += dv->lightmap[ k ];
|
||||
}
|
||||
}
|
||||
|
||||
/* average the centroid */
|
||||
iv = 1.0f / ds->numVerts;
|
||||
VectorScale( centroid->xyz, iv, centroid->xyz );
|
||||
if ( VectorNormalize( centroid->normal, centroid->normal ) <= 0 ) {
|
||||
VectorCopy( verts[ 1 ].normal, centroid->normal );
|
||||
centroid->xyz *= iv;
|
||||
if ( VectorNormalize( centroid->normal ) == 0 ) {
|
||||
centroid->normal = verts[ 1 ].normal;
|
||||
}
|
||||
for ( j = 0; j < 4; j++ )
|
||||
{
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
centroid->st *= iv;
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ ){
|
||||
centroid->lightmap[ k ] *= iv;
|
||||
for ( j = 0; j < 4; j++ )
|
||||
{
|
||||
color[ k ][ j ] /= ds->numVerts;
|
||||
centroid->color[ k ][ j ] = ( color[ k ][ j ] < 255.0f ? color[ k ][ j ] : 255 );
|
||||
}
|
||||
if ( j < 2 ) {
|
||||
centroid->st[ j ] *= iv;
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
centroid->lightmap[ k ][ j ] *= iv;
|
||||
centroid->color[ k ][ j ] = ( color[ k ][ j ] < 255 ? color[ k ][ j ] : 255 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,7 +667,6 @@ void FanFaceSurface( mapDrawSurface_t *ds ){
|
||||
|
||||
void StripFaceSurface( mapDrawSurface_t *ds ){
|
||||
int i, r, least, rotate, numIndexes, ni, a, b, c, indexes[ MAX_INDEXES ];
|
||||
vec_t *v1, *v2;
|
||||
|
||||
|
||||
/* try to early out */
|
||||
@@ -711,8 +687,8 @@ void StripFaceSurface( mapDrawSurface_t *ds ){
|
||||
for ( i = 0; i < ds->numVerts; i++ )
|
||||
{
|
||||
/* get points */
|
||||
v1 = ds->verts[ i ].xyz;
|
||||
v2 = ds->verts[ least ].xyz;
|
||||
const Vector3& v1 = ds->verts[ i ].xyz;
|
||||
const Vector3& v2 = ds->verts[ least ].xyz;
|
||||
|
||||
/* compare */
|
||||
if ( v1[ 0 ] < v2[ 0 ] ||
|
||||
@@ -912,38 +888,30 @@ void MakeEntityMetaTriangles( entity_t *e ){
|
||||
|
||||
struct edge_t
|
||||
{
|
||||
vec3_t origin;
|
||||
vec4_t edge;
|
||||
vec_t length, kingpinLength;
|
||||
Vector3 origin;
|
||||
Plane3f edge;
|
||||
float length, kingpinLength;
|
||||
int kingpin;
|
||||
vec4_t plane;
|
||||
Plane3f plane;
|
||||
};
|
||||
|
||||
void CreateEdge( vec4_t plane, vec3_t a, vec3_t b, edge_t *edge ){
|
||||
void CreateEdge( const Plane3f& plane, const Vector3& a, const Vector3& b, edge_t *edge ){
|
||||
/* copy edge origin */
|
||||
VectorCopy( a, edge->origin );
|
||||
edge->origin = a;
|
||||
|
||||
/* create vector aligned with winding direction of edge */
|
||||
VectorSubtract( b, a, edge->edge );
|
||||
edge->edge.normal() = b - a;
|
||||
|
||||
if ( fabs( edge->edge[ 0 ] ) > fabs( edge->edge[ 1 ] ) && fabs( edge->edge[ 0 ] ) > fabs( edge->edge[ 2 ] ) ) {
|
||||
edge->kingpin = 0;
|
||||
}
|
||||
else if ( fabs( edge->edge[ 1 ] ) > fabs( edge->edge[ 0 ] ) && fabs( edge->edge[ 1 ] ) > fabs( edge->edge[ 2 ] ) ) {
|
||||
edge->kingpin = 1;
|
||||
}
|
||||
else{
|
||||
edge->kingpin = 2;
|
||||
}
|
||||
edge->kingpinLength = edge->edge[ edge->kingpin ];
|
||||
edge->kingpin = vector3_max_abs_component_index( edge->edge.normal() );
|
||||
edge->kingpinLength = edge->edge.normal()[ edge->kingpin ];
|
||||
|
||||
VectorNormalize( edge->edge, edge->edge );
|
||||
edge->edge[ 3 ] = DotProduct( a, edge->edge );
|
||||
edge->length = DotProduct( b, edge->edge ) - edge->edge[ 3 ];
|
||||
VectorNormalize( edge->edge.normal() );
|
||||
edge->edge.dist() = vector3_dot( a, edge->edge.normal() );
|
||||
edge->length = plane3_distance_to_point( edge->edge, b );
|
||||
|
||||
/* create perpendicular plane that edge lies in */
|
||||
CrossProduct( plane, edge->edge, edge->plane );
|
||||
edge->plane[ 3 ] = DotProduct( a, edge->plane );
|
||||
edge->plane.normal() = vector3_cross( plane.normal(), edge->edge.normal() );
|
||||
edge->plane.dist() = vector3_dot( a, edge->plane.normal() );
|
||||
}
|
||||
|
||||
|
||||
@@ -962,9 +930,8 @@ void FixMetaTJunctions( void ){
|
||||
metaTriangle_t *tri, *newTri;
|
||||
shaderInfo_t *si;
|
||||
bspDrawVert_t *a, *b, *c, junc;
|
||||
float dist, amount;
|
||||
vec3_t pt;
|
||||
vec4_t plane;
|
||||
float amount;
|
||||
Plane3f plane;
|
||||
edge_t edges[ 3 ];
|
||||
|
||||
|
||||
@@ -999,8 +966,7 @@ void FixMetaTJunctions( void ){
|
||||
}
|
||||
|
||||
/* calculate planes */
|
||||
VectorCopy( tri->plane, plane );
|
||||
plane[ 3 ] = tri->plane[ 3 ];
|
||||
plane = tri->plane;
|
||||
CreateEdge( plane, metaVerts[ tri->indexes[ 0 ] ].xyz, metaVerts[ tri->indexes[ 1 ] ].xyz, &edges[ 0 ] );
|
||||
CreateEdge( plane, metaVerts[ tri->indexes[ 1 ] ].xyz, metaVerts[ tri->indexes[ 2 ] ].xyz, &edges[ 1 ] );
|
||||
CreateEdge( plane, metaVerts[ tri->indexes[ 2 ] ].xyz, metaVerts[ tri->indexes[ 0 ] ].xyz, &edges[ 2 ] );
|
||||
@@ -1009,11 +975,10 @@ void FixMetaTJunctions( void ){
|
||||
for ( j = 0; j < numMetaVerts; j++ )
|
||||
{
|
||||
/* get vert */
|
||||
VectorCopy( metaVerts[ j ].xyz, pt );
|
||||
const Vector3 pt = metaVerts[ j ].xyz;
|
||||
|
||||
/* determine if point lies in the triangle's plane */
|
||||
dist = DotProduct( pt, plane ) - plane[ 3 ];
|
||||
if ( fabs( dist ) > TJ_PLANE_EPSILON ) {
|
||||
if ( fabs( plane3_distance_to_point( plane, pt ) ) > TJ_PLANE_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1039,8 +1004,7 @@ void FixMetaTJunctions( void ){
|
||||
}
|
||||
|
||||
/* determine if point lies on the edge */
|
||||
dist = DotProduct( pt, edges[ k ].plane ) - edges[ k ].plane[ 3 ];
|
||||
if ( fabs( dist ) > TJ_EDGE_EPSILON ) {
|
||||
if ( fabs( plane3_distance_to_point( edges[ k ].plane, pt ) ) > TJ_EDGE_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1051,7 +1015,7 @@ void FixMetaTJunctions( void ){
|
||||
}
|
||||
|
||||
#if 0
|
||||
dist = DotProduct( pt, edges[ k ].edge ) - edges[ k ].edge[ 3 ];
|
||||
dist = plane3_distance_to_point( edges[ k ].edge, pt );
|
||||
if ( dist <= -0.0f || dist >= edges[ k ].length ) {
|
||||
continue;
|
||||
}
|
||||
@@ -1065,7 +1029,7 @@ void FixMetaTJunctions( void ){
|
||||
|
||||
/* make new vert */
|
||||
LerpDrawVertAmount( a, b, amount, &junc );
|
||||
VectorCopy( pt, junc.xyz );
|
||||
junc.xyz = pt;
|
||||
|
||||
/* compare against existing verts */
|
||||
if ( VectorCompare( junc.xyz, a->xyz ) || VectorCompare( junc.xyz, b->xyz ) || VectorCompare( junc.xyz, c->xyz ) ) {
|
||||
@@ -1109,9 +1073,7 @@ void FixMetaTJunctions( void ){
|
||||
CreateEdge( plane, metaVerts[ tri->indexes[ 2 ] ].xyz, metaVerts[ tri->indexes[ 0 ] ].xyz, &edges[ 2 ] );
|
||||
|
||||
/* debug code */
|
||||
metaVerts[ vertIndex ].color[ 0 ][ 0 ] = 255;
|
||||
metaVerts[ vertIndex ].color[ 0 ][ 1 ] = 204;
|
||||
metaVerts[ vertIndex ].color[ 0 ][ 2 ] = 0;
|
||||
metaVerts[ vertIndex ].color[ 0 ].rgb() = { 255, 204, 0 };
|
||||
|
||||
/* add to counter and end processing of this vert */
|
||||
numTJuncs++;
|
||||
@@ -1136,7 +1098,7 @@ void FixMetaTJunctions( void ){
|
||||
|
||||
#define MAX_SAMPLES 256
|
||||
#define THETA_EPSILON 0.000001
|
||||
#define EQUAL_NORMAL_EPSILON 0.01
|
||||
#define EQUAL_NORMAL_EPSILON 0.01f
|
||||
|
||||
void SmoothMetaTriangles( void ){
|
||||
int i, j, k, f, fOld, start, numVerts, numVotes, numSmoothed;
|
||||
@@ -1144,9 +1106,9 @@ void SmoothMetaTriangles( void ){
|
||||
metaTriangle_t *tri;
|
||||
float *shadeAngles;
|
||||
byte *smoothed;
|
||||
vec3_t average, diff;
|
||||
Vector3 average;
|
||||
int indexes[ MAX_SAMPLES ];
|
||||
vec3_t votes[ MAX_SAMPLES ];
|
||||
Vector3 votes[ MAX_SAMPLES ];
|
||||
|
||||
/* note it */
|
||||
Sys_FPrintf( SYS_VRB, "--- SmoothMetaTriangles ---\n" );
|
||||
@@ -1158,7 +1120,7 @@ void SmoothMetaTriangles( void ){
|
||||
smoothed = safe_calloc( ( numMetaVerts / 8 ) + 1 );
|
||||
|
||||
/* set default shade angle */
|
||||
defaultShadeAngle = DEG2RAD( npDegrees );
|
||||
defaultShadeAngle = degrees_to_radians( npDegrees );
|
||||
maxShadeAngle = 0.0f;
|
||||
|
||||
/* run through every surface and flag verts belonging to non-lightmapped surfaces
|
||||
@@ -1169,11 +1131,11 @@ void SmoothMetaTriangles( void ){
|
||||
|
||||
/* get shade angle from shader */
|
||||
if ( tri->si->shadeAngleDegrees > 0.0f ) {
|
||||
shadeAngle = DEG2RAD( tri->si->shadeAngleDegrees );
|
||||
shadeAngle = degrees_to_radians( tri->si->shadeAngleDegrees );
|
||||
}
|
||||
/* get shade angle from entity */
|
||||
else if ( tri->shadeAngleDegrees > 0.0f ) {
|
||||
shadeAngle = DEG2RAD( tri->shadeAngleDegrees );
|
||||
shadeAngle = degrees_to_radians( tri->shadeAngleDegrees );
|
||||
}
|
||||
|
||||
if ( shadeAngle <= 0.0f ) {
|
||||
@@ -1223,7 +1185,7 @@ void SmoothMetaTriangles( void ){
|
||||
}
|
||||
|
||||
/* clear */
|
||||
VectorClear( average );
|
||||
average.set( 0 );
|
||||
numVerts = 0;
|
||||
numVotes = 0;
|
||||
|
||||
@@ -1244,7 +1206,7 @@ void SmoothMetaTriangles( void ){
|
||||
shadeAngle = ( shadeAngles[ i ] < shadeAngles[ j ] ? shadeAngles[ i ] : shadeAngles[ j ] );
|
||||
|
||||
/* check shade angle */
|
||||
dot = DotProduct( metaVerts[ i ].normal, metaVerts[ j ].normal );
|
||||
dot = vector3_dot( metaVerts[ i ].normal, metaVerts[ j ].normal );
|
||||
if ( dot > 1.0 ) {
|
||||
dot = 1.0;
|
||||
}
|
||||
@@ -1265,18 +1227,15 @@ void SmoothMetaTriangles( void ){
|
||||
/* see if this normal has already been voted */
|
||||
for ( k = 0; k < numVotes; k++ )
|
||||
{
|
||||
VectorSubtract( metaVerts[ j ].normal, votes[ k ], diff );
|
||||
if ( fabs( diff[ 0 ] ) < EQUAL_NORMAL_EPSILON &&
|
||||
fabs( diff[ 1 ] ) < EQUAL_NORMAL_EPSILON &&
|
||||
fabs( diff[ 2 ] ) < EQUAL_NORMAL_EPSILON ) {
|
||||
if ( vector3_equal_epsilon( metaVerts[ j ].normal, votes[ k ], EQUAL_NORMAL_EPSILON ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* add a new vote? */
|
||||
if ( k == numVotes && numVotes < MAX_SAMPLES ) {
|
||||
VectorAdd( average, metaVerts[ j ].normal, average );
|
||||
VectorCopy( metaVerts[ j ].normal, votes[ numVotes ] );
|
||||
average += metaVerts[ j ].normal;
|
||||
votes[ numVotes ] = metaVerts[ j ].normal;
|
||||
numVotes++;
|
||||
}
|
||||
}
|
||||
@@ -1287,10 +1246,10 @@ void SmoothMetaTriangles( void ){
|
||||
}
|
||||
|
||||
/* average normal */
|
||||
if ( VectorNormalize( average, average ) > 0 ) {
|
||||
if ( VectorNormalize( average ) != 0 ) {
|
||||
/* smooth */
|
||||
for ( j = 0; j < numVerts; j++ )
|
||||
VectorCopy( average, metaVerts[ indexes[ j ] ].normal );
|
||||
metaVerts[ indexes[ j ] ].normal = average;
|
||||
numSmoothed++;
|
||||
}
|
||||
}
|
||||
@@ -1340,7 +1299,7 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid
|
||||
if ( dv1->st[ 0 ] != dv2->st[ 0 ] || dv1->st[ 1 ] != dv2->st[ 1 ] ) {
|
||||
continue;
|
||||
}
|
||||
if ( dv1->color[ 0 ][ 3 ] != dv2->color[ 0 ][ 3 ] ) {
|
||||
if ( dv1->color[ 0 ].alpha() != dv2->color[ 0 ].alpha() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1384,10 +1343,8 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid
|
||||
#define GOOD_SCORE ( metaGoodScore >= 0 ? metaGoodScore : DEFAULT_GOOD_SCORE )
|
||||
|
||||
static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, bool testAdd ){
|
||||
vec3_t p;
|
||||
int i, score, coincident, ai, bi, ci, oldTexRange[ 2 ];
|
||||
float lmMax;
|
||||
vec3_t mins, maxs;
|
||||
bool inTexRange;
|
||||
mapDrawSurface_t old;
|
||||
|
||||
@@ -1410,14 +1367,14 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||
#if 0
|
||||
if ( !( ds->shaderInfo->compileFlags & C_VERTEXLIT ) &&
|
||||
//% !VectorCompare( ds->lightmapAxis, tri->lightmapAxis ) )
|
||||
DotProduct( ds->lightmapAxis, tri->plane ) < 0.25f ) {
|
||||
vector3_dot( ds->lightmapAxis, tri->plane.normal() ) < 0.25f ) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* planar surfaces will only merge with triangles in the same plane */
|
||||
if ( npDegrees == 0.0f && !ds->shaderInfo->nonplanar && ds->planeNum >= 0 ) {
|
||||
if ( !VectorCompare( mapplanes[ ds->planeNum ].normal, tri->plane ) || mapplanes[ ds->planeNum ].dist != tri->plane[ 3 ] ) {
|
||||
if ( !VectorCompare( mapplanes[ ds->planeNum ].normal(), tri->plane.normal() ) || mapplanes[ ds->planeNum ].dist() != tri->plane.dist() ) {
|
||||
return 0;
|
||||
}
|
||||
if ( tri->planeNum >= 0 && tri->planeNum != ds->planeNum ) {
|
||||
@@ -1429,21 +1386,15 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||
|
||||
if ( metaMaxBBoxDistance >= 0 ) {
|
||||
if ( ds->numIndexes > 0 ) {
|
||||
VectorCopy( ds->mins, mins );
|
||||
VectorCopy( ds->maxs, maxs );
|
||||
mins[0] -= metaMaxBBoxDistance;
|
||||
mins[1] -= metaMaxBBoxDistance;
|
||||
mins[2] -= metaMaxBBoxDistance;
|
||||
maxs[0] += metaMaxBBoxDistance;
|
||||
maxs[1] += metaMaxBBoxDistance;
|
||||
maxs[2] += metaMaxBBoxDistance;
|
||||
const Vector3 mins = ds->minmax.mins - Vector3( metaMaxBBoxDistance, metaMaxBBoxDistance, metaMaxBBoxDistance );
|
||||
const Vector3 maxs = ds->minmax.maxs + Vector3( metaMaxBBoxDistance, metaMaxBBoxDistance, metaMaxBBoxDistance );
|
||||
#define CHECK_1D( mins, v, maxs ) ( ( mins ) <= ( v ) && ( v ) <= ( maxs ) )
|
||||
#define CHECK_3D( mins, v, maxs ) ( CHECK_1D( ( mins )[0], ( v )[0], ( maxs )[0] ) && CHECK_1D( ( mins )[1], ( v )[1], ( maxs )[1] ) && CHECK_1D( ( mins )[2], ( v )[2], ( maxs )[2] ) )
|
||||
VectorCopy( metaVerts[ tri->indexes[ 0 ] ].xyz, p );
|
||||
Vector3 p = metaVerts[ tri->indexes[ 0 ] ].xyz;
|
||||
if ( !CHECK_3D( mins, p, maxs ) ) {
|
||||
VectorCopy( metaVerts[ tri->indexes[ 1 ] ].xyz, p );
|
||||
p = metaVerts[ tri->indexes[ 1 ] ].xyz;
|
||||
if ( !CHECK_3D( mins, p, maxs ) ) {
|
||||
VectorCopy( metaVerts[ tri->indexes[ 2 ] ].xyz, p );
|
||||
p = metaVerts[ tri->indexes[ 2 ] ].xyz;
|
||||
if ( !CHECK_3D( mins, p, maxs ) ) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1462,7 +1413,7 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||
score += AXIS_SCORE;
|
||||
}
|
||||
else{
|
||||
score += AXIS_SCORE * DotProduct( ds->lightmapAxis, tri->plane );
|
||||
score += AXIS_SCORE * vector3_dot( ds->lightmapAxis, tri->plane.normal() );
|
||||
}
|
||||
|
||||
/* preserve old drawsurface if this fails */
|
||||
@@ -1484,23 +1435,22 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||
score += ( coincident * VERT_SCORE );
|
||||
|
||||
/* add new vertex bounds to mins/maxs */
|
||||
VectorCopy( ds->mins, mins );
|
||||
VectorCopy( ds->maxs, maxs );
|
||||
AddPointToBounds( metaVerts[ tri->indexes[ 0 ] ].xyz, mins, maxs );
|
||||
AddPointToBounds( metaVerts[ tri->indexes[ 1 ] ].xyz, mins, maxs );
|
||||
AddPointToBounds( metaVerts[ tri->indexes[ 2 ] ].xyz, mins, maxs );
|
||||
MinMax minmax( ds->minmax );
|
||||
minmax.extend( metaVerts[ tri->indexes[ 0 ] ].xyz );
|
||||
minmax.extend( metaVerts[ tri->indexes[ 1 ] ].xyz );
|
||||
minmax.extend( metaVerts[ tri->indexes[ 2 ] ].xyz );
|
||||
|
||||
/* check lightmap bounds overflow (after at least 1 triangle has been added) */
|
||||
if ( !( ds->shaderInfo->compileFlags & C_VERTEXLIT ) &&
|
||||
ds->numIndexes > 0 && VectorLength( ds->lightmapAxis ) > 0.0f &&
|
||||
( !VectorCompare( ds->mins, mins ) || !VectorCompare( ds->maxs, maxs ) ) ) {
|
||||
ds->numIndexes > 0 && vector3_length( ds->lightmapAxis ) != 0.0f &&
|
||||
( !VectorCompare( ds->minmax.mins, minmax.mins ) || !VectorCompare( ds->minmax.maxs, minmax.maxs ) ) ) {
|
||||
/* set maximum size before lightmap scaling (normally 2032 units) */
|
||||
/* 2004-02-24: scale lightmap test size by 2 to catch larger brush faces */
|
||||
/* 2004-04-11: reverting to actual lightmap size */
|
||||
lmMax = ( ds->sampleSize * ( ds->shaderInfo->lmCustomWidth - 1 ) );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( ( maxs[ i ] - mins[ i ] ) > lmMax ) {
|
||||
if ( ( minmax.maxs[ i ] - minmax.mins[ i ] ) > lmMax ) {
|
||||
memcpy( ds, &old, sizeof( *ds ) );
|
||||
return 0;
|
||||
}
|
||||
@@ -1595,8 +1545,7 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||
else
|
||||
{
|
||||
/* copy bounds back to surface */
|
||||
VectorCopy( mins, ds->mins );
|
||||
VectorCopy( maxs, ds->maxs );
|
||||
ds->minmax = minmax;
|
||||
|
||||
/* mark triangle as used */
|
||||
tri->si = NULL;
|
||||
@@ -1655,10 +1604,10 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles,
|
||||
ds->shadeAngleDegrees = seed->shadeAngleDegrees;
|
||||
ds->verts = verts;
|
||||
ds->indexes = indexes;
|
||||
VectorCopy( seed->lightmapAxis, ds->lightmapAxis );
|
||||
ds->lightmapAxis = seed->lightmapAxis;
|
||||
ds->sideRef = AllocSideRef( seed->side, NULL );
|
||||
|
||||
ClearBounds( ds->mins, ds->maxs );
|
||||
ds->minmax.clear();
|
||||
|
||||
/* clear verts/indexes */
|
||||
memset( verts, 0, sizeof( *verts ) * maxSurfaceVerts );
|
||||
@@ -1756,8 +1705,6 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles,
|
||||
|
||||
static int CompareMetaTriangles( const void *a, const void *b ){
|
||||
int i, j, av, bv;
|
||||
vec3_t aMins, bMins;
|
||||
|
||||
|
||||
/* shader first */
|
||||
if ( ( (const metaTriangle_t*) a )->si < ( (const metaTriangle_t*) b )->si ) {
|
||||
@@ -1809,8 +1756,8 @@ static int CompareMetaTriangles( const void *a, const void *b ){
|
||||
/* then position in world */
|
||||
|
||||
/* find mins */
|
||||
VectorSet( aMins, 999999, 999999, 999999 );
|
||||
VectorSet( bMins, 999999, 999999, 999999 );
|
||||
Vector3 aMins( 999999, 999999, 999999 );
|
||||
Vector3 bMins( 999999, 999999, 999999 );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
av = ( (const metaTriangle_t*) a )->indexes[ i ];
|
||||
|
||||
@@ -37,20 +37,20 @@
|
||||
struct edgePoint_t
|
||||
{
|
||||
float intercept;
|
||||
vec3_t xyz;
|
||||
Vector3 xyz;
|
||||
struct edgePoint_t *prev, *next;
|
||||
};
|
||||
|
||||
struct edgeLine_t
|
||||
{
|
||||
vec3_t normal1;
|
||||
Vector3 normal1;
|
||||
float dist1;
|
||||
|
||||
vec3_t normal2;
|
||||
Vector3 normal2;
|
||||
float dist2;
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t dir;
|
||||
Vector3 origin;
|
||||
Vector3 dir;
|
||||
|
||||
edgePoint_t *chain; // unused element of doubly linked list
|
||||
};
|
||||
@@ -86,17 +86,15 @@ int c_natural, c_rotate, c_cant;
|
||||
InsertPointOnEdge
|
||||
====================
|
||||
*/
|
||||
void InsertPointOnEdge( vec3_t v, edgeLine_t *e ) {
|
||||
vec3_t delta;
|
||||
void InsertPointOnEdge( const Vector3 &v, edgeLine_t *e ) {
|
||||
float d;
|
||||
edgePoint_t *p, *scan;
|
||||
|
||||
VectorSubtract( v, e->origin, delta );
|
||||
d = DotProduct( delta, e->dir );
|
||||
d = vector3_dot( v - e->origin, e->dir );
|
||||
|
||||
p = safe_malloc( sizeof( edgePoint_t ) );
|
||||
p->intercept = d;
|
||||
VectorCopy( v, p->xyz );
|
||||
p->xyz = v;
|
||||
|
||||
if ( e->chain->next == e->chain ) {
|
||||
e->chain->next = e->chain->prev = p;
|
||||
@@ -135,14 +133,16 @@ void InsertPointOnEdge( vec3_t v, edgeLine_t *e ) {
|
||||
AddEdge
|
||||
====================
|
||||
*/
|
||||
int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) {
|
||||
int AddEdge( bspDrawVert_t& dv1, bspDrawVert_t& dv2, bool createNonAxial ) {
|
||||
int i;
|
||||
edgeLine_t *e;
|
||||
float d;
|
||||
vec3_t dir;
|
||||
Vector3 dir;
|
||||
const Vector3& v1 = dv1.xyz;
|
||||
const Vector3& v2 = dv2.xyz;
|
||||
|
||||
VectorSubtract( v2, v1, dir );
|
||||
d = VectorNormalize( dir, dir );
|
||||
dir = v2 - v1;
|
||||
d = VectorNormalize( dir );
|
||||
if ( d < 0.1 ) {
|
||||
// if we added a 0 length vector, it would make degenerate planes
|
||||
c_degenerateEdges++;
|
||||
@@ -152,8 +152,8 @@ int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) {
|
||||
if ( !createNonAxial ) {
|
||||
if ( fabs( dir[0] + dir[1] + dir[2] ) != 1.0 ) {
|
||||
AUTOEXPAND_BY_REALLOC( originalEdges, numOriginalEdges, allocatedOriginalEdges, 1024 );
|
||||
originalEdges[ numOriginalEdges ].dv[0] = (bspDrawVert_t *)v1;
|
||||
originalEdges[ numOriginalEdges ].dv[1] = (bspDrawVert_t *)v2;
|
||||
originalEdges[ numOriginalEdges ].dv[0] = &dv1;
|
||||
originalEdges[ numOriginalEdges ].dv[1] = &dv2;
|
||||
originalEdges[ numOriginalEdges ].length = d;
|
||||
numOriginalEdges++;
|
||||
return -1;
|
||||
@@ -163,20 +163,20 @@ int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) {
|
||||
for ( i = 0 ; i < numEdgeLines ; i++ ) {
|
||||
e = &edgeLines[i];
|
||||
|
||||
d = DotProduct( v1, e->normal1 ) - e->dist1;
|
||||
d = vector3_dot( v1, e->normal1 ) - e->dist1;
|
||||
if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( v1, e->normal2 ) - e->dist2;
|
||||
d = vector3_dot( v1, e->normal2 ) - e->dist2;
|
||||
if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
d = DotProduct( v2, e->normal1 ) - e->dist1;
|
||||
d = vector3_dot( v2, e->normal1 ) - e->dist1;
|
||||
if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( v2, e->normal2 ) - e->dist2;
|
||||
d = vector3_dot( v2, e->normal2 ) - e->dist2;
|
||||
if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
@@ -196,12 +196,12 @@ int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) {
|
||||
e->chain = safe_malloc( sizeof( edgePoint_t ) );
|
||||
e->chain->next = e->chain->prev = e->chain;
|
||||
|
||||
VectorCopy( v1, e->origin );
|
||||
VectorCopy( dir, e->dir );
|
||||
e->origin = v1;
|
||||
e->dir = dir;
|
||||
|
||||
MakeNormalVectors( e->dir, e->normal1, e->normal2 );
|
||||
e->dist1 = DotProduct( e->origin, e->normal1 );
|
||||
e->dist2 = DotProduct( e->origin, e->normal2 );
|
||||
e->dist1 = vector3_dot( e->origin, e->normal1 );
|
||||
e->dist2 = vector3_dot( e->origin, e->normal2 );
|
||||
|
||||
InsertPointOnEdge( v1, e );
|
||||
InsertPointOnEdge( v2, e );
|
||||
@@ -221,7 +221,7 @@ void AddSurfaceEdges( mapDrawSurface_t *ds ){
|
||||
{
|
||||
/* save the edge number in the lightmap field so we don't need to look it up again */
|
||||
ds->verts[i].lightmap[ 0 ][ 0 ] =
|
||||
AddEdge( ds->verts[ i ].xyz, ds->verts[ ( i + 1 ) % ds->numVerts ].xyz, false );
|
||||
AddEdge( ds->verts[ i ], ds->verts[ ( i + 1 ) % ds->numVerts ], false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,21 +232,20 @@ void AddSurfaceEdges( mapDrawSurface_t *ds ){
|
||||
determines if an edge is colinear
|
||||
*/
|
||||
|
||||
bool ColinearEdge( vec3_t v1, vec3_t v2, vec3_t v3 ){
|
||||
vec3_t midpoint, dir, offset, on;
|
||||
bool ColinearEdge( const Vector3& v1, const Vector3& v2, const Vector3& v3 ){
|
||||
Vector3 midpoint, dir, offset, on;
|
||||
float d;
|
||||
|
||||
VectorSubtract( v2, v1, midpoint );
|
||||
VectorSubtract( v3, v1, dir );
|
||||
d = VectorNormalize( dir, dir );
|
||||
if ( d == 0 ) {
|
||||
midpoint = v2 - v1;
|
||||
dir = v3 - v1;
|
||||
if ( VectorNormalize( dir ) == 0 ) {
|
||||
return false; // degenerate
|
||||
}
|
||||
|
||||
d = DotProduct( midpoint, dir );
|
||||
VectorScale( dir, d, on );
|
||||
VectorSubtract( midpoint, on, offset );
|
||||
d = VectorLength( offset );
|
||||
d = vector3_dot( midpoint, dir );
|
||||
on = dir * d;
|
||||
offset = midpoint - on;
|
||||
d = vector3_length( offset );
|
||||
|
||||
if ( d < 0.1 ) {
|
||||
return true;
|
||||
@@ -267,45 +266,50 @@ bool ColinearEdge( vec3_t v1, vec3_t v2, vec3_t v3 ){
|
||||
*/
|
||||
void AddPatchEdges( mapDrawSurface_t *ds ) {
|
||||
int i;
|
||||
float *v1, *v2, *v3;
|
||||
|
||||
for ( i = 0 ; i < ds->patchWidth - 2; i += 2 ) {
|
||||
v1 = ds->verts[ i ].xyz;
|
||||
v2 = ds->verts[ i + 1 ].xyz;
|
||||
v3 = ds->verts[ i + 2 ].xyz;
|
||||
{
|
||||
bspDrawVert_t& v1 = ds->verts[ i ];
|
||||
bspDrawVert_t& v2 = ds->verts[ i + 1 ];
|
||||
bspDrawVert_t& v3 = ds->verts[ i + 2 ];
|
||||
|
||||
// if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1, v2, v3 ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
// if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
}
|
||||
}
|
||||
{
|
||||
bspDrawVert_t& v1 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i ];
|
||||
bspDrawVert_t& v2 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 1 ];
|
||||
bspDrawVert_t& v3 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 2 ];
|
||||
|
||||
v1 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i ].xyz;
|
||||
v2 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 1 ].xyz;
|
||||
v3 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 2 ].xyz;
|
||||
|
||||
// if v2 is on the v1 to v3 line, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1, v2, v3 ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
// if v2 is on the v1 to v3 line, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < ds->patchHeight - 2 ; i += 2 ) {
|
||||
v1 = ds->verts[ i * ds->patchWidth ].xyz;
|
||||
v2 = ds->verts[ ( i + 1 ) * ds->patchWidth ].xyz;
|
||||
v3 = ds->verts[ ( i + 2 ) * ds->patchWidth ].xyz;
|
||||
{
|
||||
bspDrawVert_t& v1 = ds->verts[ i * ds->patchWidth ];
|
||||
bspDrawVert_t& v2 = ds->verts[ ( i + 1 ) * ds->patchWidth ];
|
||||
bspDrawVert_t& v3 = ds->verts[ ( i + 2 ) * ds->patchWidth ];
|
||||
|
||||
// if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1, v2, v3 ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
// if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
}
|
||||
}
|
||||
{
|
||||
bspDrawVert_t& v1 = ds->verts[ ( ds->patchWidth - 1 ) + i * ds->patchWidth ];
|
||||
bspDrawVert_t& v2 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 1 ) * ds->patchWidth ];
|
||||
bspDrawVert_t& v3 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 2 ) * ds->patchWidth ];
|
||||
|
||||
v1 = ds->verts[ ( ds->patchWidth - 1 ) + i * ds->patchWidth ].xyz;
|
||||
v2 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 1 ) * ds->patchWidth ].xyz;
|
||||
v3 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 2 ) * ds->patchWidth ].xyz;
|
||||
|
||||
// if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1, v2, v3 ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
// if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
|
||||
if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) {
|
||||
AddEdge( v1, v3, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,8 +331,7 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) {
|
||||
int originals[MAX_SURFACE_VERTS];
|
||||
bspDrawVert_t verts[MAX_SURFACE_VERTS], *v1, *v2;
|
||||
int numVerts;
|
||||
float start, end, frac, c;
|
||||
vec3_t delta;
|
||||
float start, end, c;
|
||||
|
||||
|
||||
numVerts = 0;
|
||||
@@ -354,11 +357,9 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) {
|
||||
}
|
||||
e = &edgeLines[ j ];
|
||||
|
||||
VectorSubtract( v1->xyz, e->origin, delta );
|
||||
start = DotProduct( delta, e->dir );
|
||||
start = vector3_dot( v1->xyz - e->origin, e->dir );
|
||||
|
||||
VectorSubtract( v2->xyz, e->origin, delta );
|
||||
end = DotProduct( delta, e->dir );
|
||||
end = vector3_dot( v2->xyz - e->origin, e->dir );
|
||||
|
||||
|
||||
if ( start < end ) {
|
||||
@@ -389,17 +390,14 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) {
|
||||
}
|
||||
|
||||
/* take the exact intercept point */
|
||||
VectorCopy( p->xyz, verts[ numVerts ].xyz );
|
||||
verts[ numVerts ].xyz = p->xyz;
|
||||
|
||||
/* interpolate the texture coordinates */
|
||||
frac = ( p->intercept - start ) / ( end - start );
|
||||
for ( j = 0 ; j < 2 ; j++ ) {
|
||||
verts[ numVerts ].st[j] = v1->st[j] +
|
||||
frac * ( v2->st[j] - v1->st[j] );
|
||||
}
|
||||
const float frac = ( p->intercept - start ) / ( end - start );
|
||||
verts[ numVerts ].st = v1->st + ( v2->st - v1->st ) * frac;
|
||||
|
||||
/* copy the normal (FIXME: what about nonplanar surfaces? */
|
||||
VectorCopy( v1->normal, verts[ numVerts ].normal );
|
||||
verts[ numVerts ].normal = v1->normal;
|
||||
|
||||
/* ydnar: interpolate the color */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
@@ -500,8 +498,6 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) {
|
||||
returns false if the surface is broken
|
||||
*/
|
||||
|
||||
extern void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out );
|
||||
|
||||
#define DEGENERATE_EPSILON 0.1
|
||||
|
||||
int c_broken = 0;
|
||||
@@ -509,7 +505,6 @@ int c_broken = 0;
|
||||
bool FixBrokenSurface( mapDrawSurface_t *ds ){
|
||||
bspDrawVert_t *dv1, *dv2, avg;
|
||||
int i, j, k;
|
||||
float dist;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
@@ -528,24 +523,20 @@ bool FixBrokenSurface( mapDrawSurface_t *ds ){
|
||||
dv2 = &ds->verts[ ( i + 1 ) % ds->numVerts ];
|
||||
|
||||
/* degenerate edge? */
|
||||
VectorSubtract( dv1->xyz, dv2->xyz, avg.xyz );
|
||||
dist = VectorLength( avg.xyz );
|
||||
if ( dist < DEGENERATE_EPSILON ) {
|
||||
avg.xyz = dv1->xyz - dv2->xyz;
|
||||
if ( vector3_length( avg.xyz ) < DEGENERATE_EPSILON ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Degenerate T-junction edge found, fixing...\n" );
|
||||
|
||||
/* create an average drawvert */
|
||||
/* ydnar 2002-01-26: added nearest-integer welding preference */
|
||||
SnapWeldVector( dv1->xyz, dv2->xyz, avg.xyz );
|
||||
VectorAdd( dv1->normal, dv2->normal, avg.normal );
|
||||
VectorNormalize( avg.normal, avg.normal );
|
||||
avg.st[ 0 ] = ( dv1->st[ 0 ] + dv2->st[ 0 ] ) * 0.5f;
|
||||
avg.st[ 1 ] = ( dv1->st[ 1 ] + dv2->st[ 1 ] ) * 0.5f;
|
||||
avg.normal = VectorNormalized( dv1->normal + dv2->normal );
|
||||
avg.st = vector2_mid( dv1->st, dv2->st );
|
||||
|
||||
/* lightmap st/colors */
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
{
|
||||
avg.lightmap[ k ][ 0 ] = ( dv1->lightmap[ k ][ 0 ] + dv2->lightmap[ k ][ 0 ] ) * 0.5f;
|
||||
avg.lightmap[ k ][ 1 ] = ( dv1->lightmap[ k ][ 1 ] + dv2->lightmap[ k ][ 1 ] ) * 0.5f;
|
||||
avg.lightmap[ k ] = vector2_mid( dv1->lightmap[ k ], dv2->lightmap[ k ] );
|
||||
for ( j = 0; j < 4; j++ )
|
||||
avg.color[ k ][ j ] = (int) ( dv1->color[ k ][ j ] + dv2->color[ k ][ j ] ) >> 1;
|
||||
}
|
||||
@@ -670,7 +661,7 @@ void FixTJunctions( entity_t *ent ){
|
||||
for ( i = 0 ; i < numOriginalEdges ; i++ ) {
|
||||
e = &originalEdges[i];
|
||||
dv = e->dv[0]; // e might change during AddEdge
|
||||
dv->lightmap[ 0 ][ 0 ] = AddEdge( e->dv[ 0 ]->xyz, e->dv[ 1 ]->xyz, true );
|
||||
dv->lightmap[ 0 ][ 0 ] = AddEdge( *e->dv[ 0 ], *e->dv[ 1 ], true );
|
||||
}
|
||||
|
||||
Sys_FPrintf( SYS_VRB, "%9d axial edge lines\n", axialEdgeLines );
|
||||
|
||||
@@ -36,15 +36,10 @@
|
||||
|
||||
void RemovePortalFromNode( portal_t *portal, node_t *l );
|
||||
|
||||
node_t *NodeForPoint( node_t *node, vec3_t origin ){
|
||||
plane_t *plane;
|
||||
vec_t d;
|
||||
|
||||
node_t *NodeForPoint( node_t *node, const Vector3& origin ){
|
||||
while ( node->planenum != PLANENUM_LEAF )
|
||||
{
|
||||
plane = &mapplanes[node->planenum];
|
||||
d = DotProduct( origin, plane->normal ) - plane->dist;
|
||||
if ( d >= 0 ) {
|
||||
if ( plane3_distance_to_point( mapplanes[node->planenum].plane, origin ) >= 0 ) {
|
||||
node = node->children[0];
|
||||
}
|
||||
else{
|
||||
@@ -143,8 +138,8 @@ void PrintTree_r( node_t *node, int depth ){
|
||||
|
||||
plane = &mapplanes[node->planenum];
|
||||
Sys_Printf( "#%d (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum,
|
||||
plane->normal[0], plane->normal[1], plane->normal[2],
|
||||
plane->dist );
|
||||
plane->normal()[0], plane->normal()[1], plane->normal()[2],
|
||||
plane->dist() );
|
||||
PrintTree_r( node->children[0], depth + 1 );
|
||||
PrintTree_r( node->children[1], depth + 1 );
|
||||
}
|
||||
|
||||
+46
-64
@@ -34,15 +34,11 @@
|
||||
|
||||
|
||||
|
||||
void PlaneFromWinding( fixedWinding_t *w, visPlane_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->normal );
|
||||
plane->dist = DotProduct( w->points[0], plane->normal );
|
||||
visPlane_t PlaneFromWinding( const fixedWinding_t *w ){
|
||||
// calc plane
|
||||
visPlane_t plane;
|
||||
PlaneFromPoints( plane, w->points[0], w->points[1], w->points[2] );
|
||||
return plane;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +66,7 @@ void prl( leaf_t *l ){
|
||||
{
|
||||
p = l->portals[i];
|
||||
pl = p->plane;
|
||||
Sys_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] );
|
||||
Sys_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] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,30 +370,27 @@ void CalcVis( void ){
|
||||
*/
|
||||
void SetPortalSphere( vportal_t *p ){
|
||||
int i;
|
||||
vec3_t total, dist;
|
||||
Vector3 total( 0, 0, 0 );
|
||||
fixedWinding_t *w;
|
||||
float r, bestr;
|
||||
|
||||
w = p->winding;
|
||||
VectorCopy( vec3_origin, total );
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
VectorAdd( total, w->points[i], total );
|
||||
total += w->points[i];
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
total[i] /= w->numpoints;
|
||||
total /= w->numpoints;
|
||||
|
||||
bestr = 0;
|
||||
for ( i = 0 ; i < w->numpoints ; i++ )
|
||||
{
|
||||
VectorSubtract( w->points[i], total, dist );
|
||||
r = VectorLength( dist );
|
||||
r = vector3_length( w->points[i] - total );
|
||||
if ( r > bestr ) {
|
||||
bestr = r;
|
||||
}
|
||||
}
|
||||
VectorCopy( total, p->origin );
|
||||
p->origin = total;
|
||||
p->radius = bestr;
|
||||
}
|
||||
|
||||
@@ -408,9 +401,8 @@ void SetPortalSphere( vportal_t *p ){
|
||||
*/
|
||||
#define WCONVEX_EPSILON 0.2
|
||||
|
||||
static bool Winding_PlanesConcave( fixedWinding_t *w1, fixedWinding_t *w2,
|
||||
vec3_t normal1, vec3_t normal2,
|
||||
float dist1, float dist2 ){
|
||||
static bool Winding_PlanesConcave( const fixedWinding_t *w1, const fixedWinding_t *w2,
|
||||
const Plane3f& plane1, const Plane3f& plane2 ){
|
||||
int i;
|
||||
|
||||
if ( !w1 || !w2 ) {
|
||||
@@ -420,14 +412,14 @@ static bool Winding_PlanesConcave( fixedWinding_t *w1, fixedWinding_t *w2,
|
||||
// check if one of the points of winding 1 is at the front of the plane of winding 2
|
||||
for ( i = 0; i < w1->numpoints; i++ )
|
||||
{
|
||||
if ( DotProduct( normal2, w1->points[i] ) - dist2 > WCONVEX_EPSILON ) {
|
||||
if ( plane3_distance_to_point( plane2, w1->points[i] ) > WCONVEX_EPSILON ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// check if one of the points of winding 2 is at the front of the plane of winding 1
|
||||
for ( i = 0; i < w2->numpoints; i++ )
|
||||
{
|
||||
if ( DotProduct( normal1, w2->points[i] ) - dist1 > WCONVEX_EPSILON ) {
|
||||
if ( plane3_distance_to_point( plane1, w2->points[i] ) > WCONVEX_EPSILON ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -442,7 +434,6 @@ static bool Winding_PlanesConcave( fixedWinding_t *w1, fixedWinding_t *w2,
|
||||
*/
|
||||
static bool TryMergeLeaves( int l1num, int l2num ){
|
||||
int i, j, k, n, numportals;
|
||||
visPlane_t plane1, plane2;
|
||||
leaf_t *l1, *l2;
|
||||
vportal_t *p1, *p2;
|
||||
vportal_t *portals[MAX_PORTALS_ON_LEAF];
|
||||
@@ -464,7 +455,9 @@ static bool TryMergeLeaves( int l1num, int l2num ){
|
||||
if ( n ) {
|
||||
l2 = &leafs[l2num];
|
||||
}
|
||||
else{l2 = &faceleafs[l2num]; }
|
||||
else{
|
||||
l2 = &faceleafs[l2num];
|
||||
}
|
||||
for ( j = 0; j < l2->numportals; j++ )
|
||||
{
|
||||
p2 = l2->portals[j];
|
||||
@@ -472,9 +465,7 @@ static bool TryMergeLeaves( int l1num, int l2num ){
|
||||
continue;
|
||||
}
|
||||
//
|
||||
plane1 = p1->plane;
|
||||
plane2 = p2->plane;
|
||||
if ( Winding_PlanesConcave( p1->winding, p2->winding, plane1.normal, plane2.normal, plane1.dist, plane2.dist ) ) {
|
||||
if ( Winding_PlanesConcave( p1->winding, p2->winding, p1->plane, p2->plane ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -599,12 +590,12 @@ void MergeLeaves( void ){
|
||||
*/
|
||||
#define CONTINUOUS_EPSILON 0.005
|
||||
|
||||
fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t planenormal ){
|
||||
vec_t *p1, *p2, *p3, *p4, *back;
|
||||
fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, const Vector3& planenormal ){
|
||||
const Vector3 *p1, *p2, *p3, *p4, *back;
|
||||
fixedWinding_t *newf;
|
||||
int i, j, k, l;
|
||||
vec3_t normal, delta;
|
||||
vec_t dot;
|
||||
Vector3 normal;
|
||||
float dot;
|
||||
bool keep1, keep2;
|
||||
|
||||
|
||||
@@ -616,18 +607,18 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t
|
||||
|
||||
for ( i = 0; i < f1->numpoints; i++ )
|
||||
{
|
||||
p1 = f1->points[i];
|
||||
p2 = f1->points[( i + 1 ) % f1->numpoints];
|
||||
p1 = &f1->points[i];
|
||||
p2 = &f1->points[( i + 1 ) % f1->numpoints];
|
||||
for ( j = 0; j < f2->numpoints; j++ )
|
||||
{
|
||||
p3 = f2->points[j];
|
||||
p4 = f2->points[( j + 1 ) % f2->numpoints];
|
||||
p3 = &f2->points[j];
|
||||
p4 = &f2->points[( j + 1 ) % f2->numpoints];
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
if ( fabs( p1[k] - p4[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME
|
||||
if ( fabs( (*p1)[k] - (*p4)[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME
|
||||
break;
|
||||
}
|
||||
if ( fabs( p2[k] - p3[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME
|
||||
if ( fabs( (*p2)[k] - (*p3)[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME
|
||||
break;
|
||||
}
|
||||
} //end for
|
||||
@@ -648,27 +639,21 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t
|
||||
// check slope of connected lines
|
||||
// if the slopes are colinear, the point can be removed
|
||||
//
|
||||
back = f1->points[( i + f1->numpoints - 1 ) % f1->numpoints];
|
||||
VectorSubtract( p1, back, delta );
|
||||
CrossProduct( planenormal, delta, normal );
|
||||
VectorNormalize( normal, normal );
|
||||
back = &f1->points[( i + f1->numpoints - 1 ) % f1->numpoints];
|
||||
normal = VectorNormalized( vector3_cross( planenormal, *p1 - *back ) );
|
||||
|
||||
back = f2->points[( j + 2 ) % f2->numpoints];
|
||||
VectorSubtract( back, p1, delta );
|
||||
dot = DotProduct( delta, normal );
|
||||
back = &f2->points[( j + 2 ) % f2->numpoints];
|
||||
dot = vector3_dot( *back - *p1, normal );
|
||||
if ( dot > CONTINUOUS_EPSILON ) {
|
||||
return NULL; // not a convex polygon
|
||||
}
|
||||
keep1 = ( dot < -CONTINUOUS_EPSILON );
|
||||
|
||||
back = f1->points[( i + 2 ) % f1->numpoints];
|
||||
VectorSubtract( back, p2, delta );
|
||||
CrossProduct( planenormal, delta, normal );
|
||||
VectorNormalize( normal, normal );
|
||||
back = &f1->points[( i + 2 ) % f1->numpoints];
|
||||
normal = VectorNormalized( vector3_cross( planenormal, *back - *p2 ) );
|
||||
|
||||
back = f2->points[( j + f2->numpoints - 1 ) % f2->numpoints];
|
||||
VectorSubtract( back, p2, delta );
|
||||
dot = DotProduct( delta, normal );
|
||||
back = &f2->points[( j + f2->numpoints - 1 ) % f2->numpoints];
|
||||
dot = vector3_dot( *back - *p2, normal );
|
||||
if ( dot > CONTINUOUS_EPSILON ) {
|
||||
return NULL; // not a convex polygon
|
||||
}
|
||||
@@ -686,7 +671,7 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy( f1->points[k], newf->points[newf->numpoints] );
|
||||
newf->points[newf->numpoints] = f1->points[k];
|
||||
newf->numpoints++;
|
||||
}
|
||||
|
||||
@@ -696,7 +681,7 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t
|
||||
if ( l == ( j + 1 ) % f2->numpoints && !keep1 ) {
|
||||
continue;
|
||||
}
|
||||
VectorCopy( f2->points[l], newf->points[newf->numpoints] );
|
||||
newf->points[newf->numpoints] = f2->points[l];
|
||||
newf->numpoints++;
|
||||
}
|
||||
|
||||
@@ -735,7 +720,7 @@ void MergeLeafPortals( void ){
|
||||
continue;
|
||||
}
|
||||
if ( p1->leaf == p2->leaf ) {
|
||||
w = TryMergeWinding( p1->winding, p2->winding, p1->plane.normal );
|
||||
w = TryMergeWinding( p1->winding, p2->winding, p1->plane.normal() );
|
||||
if ( w ) {
|
||||
free( p1->winding ); //% FreeWinding(p1->winding);
|
||||
p1->winding = w;
|
||||
@@ -793,7 +778,7 @@ int CountActivePortals( void ){
|
||||
WritePortals
|
||||
============
|
||||
*/
|
||||
void WriteFloat( FILE *f, vec_t v );
|
||||
void WriteFloat( FILE *f, float v );
|
||||
|
||||
void WritePortals( char *filename ){
|
||||
int i, j, num;
|
||||
@@ -877,7 +862,6 @@ void LoadPortals( char *name ){
|
||||
int numpoints;
|
||||
fixedWinding_t *w;
|
||||
int leafnums[2];
|
||||
visPlane_t plane;
|
||||
|
||||
if ( strEqual( name, "-" ) ) {
|
||||
f = stdin;
|
||||
@@ -963,7 +947,7 @@ void LoadPortals( char *name ){
|
||||
}
|
||||
|
||||
// calc plane
|
||||
PlaneFromWinding( w, &plane );
|
||||
const visPlane_t plane = PlaneFromWinding( w );
|
||||
|
||||
// create forward portal
|
||||
l = &leafs[leafnums[0]];
|
||||
@@ -977,8 +961,7 @@ void LoadPortals( char *name ){
|
||||
p->hint = ((flags & 1) != 0);
|
||||
p->sky = ((flags & 2) != 0);
|
||||
p->winding = w;
|
||||
VectorSubtract( vec3_origin, plane.normal, p->plane.normal );
|
||||
p->plane.dist = -plane.dist;
|
||||
p->plane = plane3_flipped( plane );
|
||||
p->leaf = leafnums[1];
|
||||
SetPortalSphere( p );
|
||||
p++;
|
||||
@@ -997,7 +980,7 @@ void LoadPortals( char *name ){
|
||||
p->winding->numpoints = w->numpoints;
|
||||
for ( j = 0 ; j < w->numpoints ; j++ )
|
||||
{
|
||||
VectorCopy( w->points[w->numpoints - 1 - j], p->winding->points[j] );
|
||||
p->winding->points[j] = w->points[w->numpoints - 1 - j];
|
||||
}
|
||||
|
||||
p->plane = plane;
|
||||
@@ -1038,7 +1021,7 @@ void LoadPortals( char *name ){
|
||||
}
|
||||
|
||||
// calc plane
|
||||
PlaneFromWinding( w, &plane );
|
||||
const visPlane_t plane = PlaneFromWinding( w );
|
||||
|
||||
l = &faceleafs[leafnums[0]];
|
||||
l->merged = -1;
|
||||
@@ -1051,8 +1034,7 @@ void LoadPortals( char *name ){
|
||||
p->num = i + 1;
|
||||
p->winding = w;
|
||||
// normal pointing out of the leaf
|
||||
VectorSubtract( vec3_origin, plane.normal, p->plane.normal );
|
||||
p->plane.dist = -plane.dist;
|
||||
p->plane = plane3_flipped( plane );
|
||||
p->leaf = -1;
|
||||
SetPortalSphere( p );
|
||||
p++;
|
||||
|
||||
+90
-170
@@ -122,14 +122,13 @@ void FreeStackWinding( fixedWinding_t *w, pstack_t *stack ){
|
||||
|
||||
==============
|
||||
*/
|
||||
fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t *split ){
|
||||
vec_t dists[128];
|
||||
int sides[128];
|
||||
fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, const visPlane_t& split ){
|
||||
float dists[128];
|
||||
EPlaneSide sides[128];
|
||||
int counts[3];
|
||||
vec_t dot;
|
||||
float dot;
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec3_t mid;
|
||||
Vector3 mid;
|
||||
fixedWinding_t *neww;
|
||||
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
@@ -137,18 +136,16 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t
|
||||
// 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;
|
||||
dists[i] = plane3_distance_to_point( split, in->points[i] );
|
||||
if ( dists[i] > ON_EPSILON ) {
|
||||
sides[i] = eSideFront;
|
||||
}
|
||||
else if ( dot < -ON_EPSILON ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
else if ( dists[i] < -ON_EPSILON ) {
|
||||
sides[i] = eSideBack;
|
||||
}
|
||||
else
|
||||
{
|
||||
sides[i] = SIDE_ON;
|
||||
sides[i] = eSideOn;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
@@ -171,25 +168,25 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t
|
||||
|
||||
for ( i = 0 ; i < in->numpoints ; i++ )
|
||||
{
|
||||
p1 = in->points[i];
|
||||
const Vector3& 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] );
|
||||
if ( sides[i] == eSideOn ) {
|
||||
neww->points[neww->numpoints] = p1;
|
||||
neww->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_FRONT ) {
|
||||
VectorCopy( p1, neww->points[neww->numpoints] );
|
||||
if ( sides[i] == eSideFront ) {
|
||||
neww->points[neww->numpoints] = p1;
|
||||
neww->numpoints++;
|
||||
}
|
||||
|
||||
if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
|
||||
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -199,23 +196,23 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t
|
||||
}
|
||||
|
||||
// generate a split point
|
||||
p2 = in->points[( i + 1 ) % in->numpoints];
|
||||
const Vector3& 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;
|
||||
if ( split.normal()[j] == 1 ) {
|
||||
mid[j] = split.dist();
|
||||
}
|
||||
else 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->points[neww->numpoints] = mid;
|
||||
neww->numpoints++;
|
||||
}
|
||||
|
||||
@@ -243,10 +240,7 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t
|
||||
*/
|
||||
fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, fixedWinding_t *target, bool flipclip, pstack_t *stack ){
|
||||
int i, j, k, l;
|
||||
visPlane_t plane;
|
||||
vec3_t v1, v2;
|
||||
float d;
|
||||
vec_t length;
|
||||
int counts[3];
|
||||
bool fliptest;
|
||||
|
||||
@@ -254,37 +248,18 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
for ( i = 0 ; i < source->numpoints ; i++ )
|
||||
{
|
||||
l = ( i + 1 ) % source->numpoints;
|
||||
VectorSubtract( source->points[l], source->points[i], v1 );
|
||||
|
||||
// find 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];
|
||||
|
||||
visPlane_t plane;
|
||||
// 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 ) {
|
||||
if ( !PlaneFromPoints( plane, source->points[i], pass->points[j], source->points[l] ) ) {
|
||||
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
|
||||
@@ -296,7 +271,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
if ( k == i || k == l ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( source->points[k], plane.normal ) - plane.dist;
|
||||
d = plane3_distance_to_point( plane, source->points[k] );
|
||||
if ( d < -ON_EPSILON ) { // source is on the negative side, so we want all
|
||||
// pass and target on the positive side
|
||||
fliptest = false;
|
||||
@@ -318,8 +293,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
// flip the normal if the source portal is backwards
|
||||
//
|
||||
if ( fliptest ) {
|
||||
VectorSubtract( vec3_origin, plane.normal, plane.normal );
|
||||
plane.dist = -plane.dist;
|
||||
plane = plane3_flipped( plane );
|
||||
}
|
||||
#if 1
|
||||
//
|
||||
@@ -332,7 +306,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
if ( k == j ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( pass->points[k], plane.normal ) - plane.dist;
|
||||
d = plane3_distance_to_point( plane, pass->points[k] );
|
||||
if ( d < -ON_EPSILON ) {
|
||||
break;
|
||||
}
|
||||
@@ -352,12 +326,12 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
}
|
||||
#else
|
||||
k = ( j + 1 ) % pass->numpoints;
|
||||
d = DotProduct( pass->points[k], plane.normal ) - plane.dist;
|
||||
d = plane3_distance_to_point( plane, pass->points[k] );
|
||||
if ( d < -ON_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
k = ( j + pass->numpoints - 1 ) % pass->numpoints;
|
||||
d = DotProduct( pass->points[k], plane.normal ) - plane.dist;
|
||||
d = plane3_distance_to_point( plane, pass->points[k] );
|
||||
if ( d < -ON_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
@@ -366,8 +340,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
// flip the normal if we want the back side
|
||||
//
|
||||
if ( flipclip ) {
|
||||
VectorSubtract( vec3_origin, plane.normal, plane.normal );
|
||||
plane.dist = -plane.dist;
|
||||
plane = plane3_flipped( plane );
|
||||
}
|
||||
|
||||
#ifdef SEPERATORCACHE
|
||||
@@ -377,7 +350,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
}
|
||||
#endif
|
||||
//MrE: fast check first
|
||||
d = DotProduct( stack->portal->origin, plane.normal ) - plane.dist;
|
||||
d = plane3_distance_to_point( plane, stack->portal->origin );
|
||||
//if completely at the back of the seperator plane
|
||||
if ( d < -stack->portal->radius ) {
|
||||
return NULL;
|
||||
@@ -390,7 +363,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass,
|
||||
//
|
||||
// clip target by the seperating plane
|
||||
//
|
||||
target = VisChopWinding( target, stack, &plane );
|
||||
target = VisChopWinding( target, stack, plane );
|
||||
if ( !target ) {
|
||||
return NULL; // target is not visible
|
||||
|
||||
@@ -495,8 +468,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
|
||||
// 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;
|
||||
backplane = plane3_flipped( p->plane );
|
||||
|
||||
stack.portal = p;
|
||||
stack.next = NULL;
|
||||
@@ -506,10 +478,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
|
||||
#if 1
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct( p->origin, thread->pstack_head.portalplane.normal );
|
||||
d -= thread->pstack_head.portalplane.dist;
|
||||
const float d = plane3_distance_to_point( thread->pstack_head.portalplane, p->origin );
|
||||
if ( d < -p->radius ) {
|
||||
continue;
|
||||
}
|
||||
@@ -518,7 +487,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.pass = VisChopWinding( p->winding, &stack, &thread->pstack_head.portalplane );
|
||||
stack.pass = VisChopWinding( p->winding, &stack, thread->pstack_head.portalplane );
|
||||
if ( !stack.pass ) {
|
||||
continue;
|
||||
}
|
||||
@@ -534,10 +503,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
|
||||
#if 1
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct( thread->base->origin, p->plane.normal );
|
||||
d -= p->plane.dist;
|
||||
const float d = plane3_distance_to_point( p->plane, thread->base->origin );
|
||||
//MrE: vis-bug fix
|
||||
//if (d > p->radius)
|
||||
if ( d > thread->base->radius ) {
|
||||
@@ -550,7 +516,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, &backplane );
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, backplane );
|
||||
//FIXME: shouldn't we create a new source origin and radius for fast checks?
|
||||
if ( !stack.source ) {
|
||||
continue;
|
||||
@@ -558,7 +524,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
}
|
||||
}
|
||||
#else
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, &backplane );
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, backplane );
|
||||
if ( !stack.source ) {
|
||||
continue;
|
||||
}
|
||||
@@ -577,7 +543,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
if ( stack.numseperators[0] ) {
|
||||
for ( n = 0; n < stack.numseperators[0]; n++ )
|
||||
{
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[0][n] );
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[0][n] );
|
||||
if ( !stack.pass ) {
|
||||
break; // target is not visible
|
||||
}
|
||||
@@ -601,7 +567,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack )
|
||||
if ( stack.numseperators[1] ) {
|
||||
for ( n = 0; n < stack.numseperators[1]; n++ )
|
||||
{
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[1][n] );
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[1][n] );
|
||||
if ( !stack.pass ) {
|
||||
break; // target is not visible
|
||||
}
|
||||
@@ -884,8 +850,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
|
||||
// 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;
|
||||
backplane = plane3_flipped( p->plane );
|
||||
|
||||
stack.portal = p;
|
||||
stack.next = NULL;
|
||||
@@ -895,10 +860,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
|
||||
#if 1
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct( p->origin, thread->pstack_head.portalplane.normal );
|
||||
d -= thread->pstack_head.portalplane.dist;
|
||||
const float d = plane3_distance_to_point( thread->pstack_head.portalplane, p->origin );
|
||||
if ( d < -p->radius ) {
|
||||
continue;
|
||||
}
|
||||
@@ -907,14 +869,14 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.pass = VisChopWinding( p->winding, &stack, &thread->pstack_head.portalplane );
|
||||
stack.pass = VisChopWinding( p->winding, &stack, thread->pstack_head.portalplane );
|
||||
if ( !stack.pass ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
stack.pass = VisChopWinding( p->winding, &stack, &thread->pstack_head.portalplane );
|
||||
stack.pass = VisChopWinding( p->winding, &stack, thread->pstack_head.portalplane );
|
||||
if ( !stack.pass ) {
|
||||
continue;
|
||||
}
|
||||
@@ -923,10 +885,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
|
||||
#if 1
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct( thread->base->origin, p->plane.normal );
|
||||
d -= p->plane.dist;
|
||||
const float d = plane3_distance_to_point( p->plane, thread->base->origin );
|
||||
//MrE: vis-bug fix
|
||||
//if (d > p->radius)
|
||||
if ( d > thread->base->radius ) {
|
||||
@@ -939,7 +898,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, &backplane );
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, backplane );
|
||||
//FIXME: shouldn't we create a new source origin and radius for fast checks?
|
||||
if ( !stack.source ) {
|
||||
continue;
|
||||
@@ -947,7 +906,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
}
|
||||
}
|
||||
#else
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, &backplane );
|
||||
stack.source = VisChopWinding( prevstack->source, &stack, backplane );
|
||||
if ( !stack.source ) {
|
||||
continue;
|
||||
}
|
||||
@@ -966,7 +925,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
if ( stack.numseperators[0] ) {
|
||||
for ( n = 0; n < stack.numseperators[0]; n++ )
|
||||
{
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[0][n] );
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[0][n] );
|
||||
if ( !stack.pass ) {
|
||||
break; // target is not visible
|
||||
}
|
||||
@@ -990,7 +949,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
||||
if ( stack.numseperators[1] ) {
|
||||
for ( n = 0; n < stack.numseperators[1]; n++ )
|
||||
{
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[1][n] );
|
||||
stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[1][n] );
|
||||
if ( !stack.pass ) {
|
||||
break; // target is not visible
|
||||
}
|
||||
@@ -1065,14 +1024,13 @@ void PassagePortalFlow( int portalnum ){
|
||||
*/
|
||||
}
|
||||
|
||||
fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, visPlane_t *split ){
|
||||
vec_t dists[128];
|
||||
int sides[128];
|
||||
fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, const visPlane_t& split ){
|
||||
float dists[128];
|
||||
EPlaneSide sides[128];
|
||||
int counts[3];
|
||||
vec_t dot;
|
||||
float dot;
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec3_t mid;
|
||||
Vector3 mid;
|
||||
fixedWinding_t *neww;
|
||||
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
@@ -1080,18 +1038,16 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis
|
||||
// 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;
|
||||
dists[i] = plane3_distance_to_point( split, in->points[i] );
|
||||
if ( dists[i] > ON_EPSILON ) {
|
||||
sides[i] = eSideFront;
|
||||
}
|
||||
else if ( dot < -ON_EPSILON ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
else if ( dists[i] < -ON_EPSILON ) {
|
||||
sides[i] = eSideBack;
|
||||
}
|
||||
else
|
||||
{
|
||||
sides[i] = SIDE_ON;
|
||||
sides[i] = eSideOn;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
@@ -1113,24 +1069,24 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis
|
||||
|
||||
for ( i = 0 ; i < in->numpoints ; i++ )
|
||||
{
|
||||
p1 = in->points[i];
|
||||
const Vector3& p1 = in->points[i];
|
||||
|
||||
if ( neww->numpoints == MAX_POINTS_ON_FIXED_WINDING ) {
|
||||
return in; // can't chop -- fall back to original
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_ON ) {
|
||||
VectorCopy( p1, neww->points[neww->numpoints] );
|
||||
if ( sides[i] == eSideOn ) {
|
||||
neww->points[neww->numpoints] = p1;
|
||||
neww->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_FRONT ) {
|
||||
VectorCopy( p1, neww->points[neww->numpoints] );
|
||||
if ( sides[i] == eSideFront ) {
|
||||
neww->points[neww->numpoints] = p1;
|
||||
neww->numpoints++;
|
||||
}
|
||||
|
||||
if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
|
||||
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1139,23 +1095,23 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis
|
||||
}
|
||||
|
||||
// generate a split point
|
||||
p2 = in->points[( i + 1 ) % in->numpoints];
|
||||
const Vector3& 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;
|
||||
if ( split.normal()[j] == 1 ) {
|
||||
mid[j] = split.dist();
|
||||
}
|
||||
else 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->points[neww->numpoints] = mid;
|
||||
neww->numpoints++;
|
||||
}
|
||||
|
||||
@@ -1169,10 +1125,6 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis
|
||||
*/
|
||||
int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, visPlane_t *seperators, int maxseperators ){
|
||||
int i, j, k, l;
|
||||
visPlane_t plane;
|
||||
vec3_t v1, v2;
|
||||
float d;
|
||||
vec_t length;
|
||||
int counts[3], numseperators;
|
||||
bool fliptest;
|
||||
|
||||
@@ -1181,37 +1133,18 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
for ( i = 0 ; i < source->numpoints ; i++ )
|
||||
{
|
||||
l = ( i + 1 ) % source->numpoints;
|
||||
VectorSubtract( source->points[l], source->points[i], v1 );
|
||||
|
||||
// find 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];
|
||||
|
||||
visPlane_t plane;
|
||||
// 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 ) {
|
||||
if ( !PlaneFromPoints( plane, source->points[i], pass->points[j], source->points[l] ) ) {
|
||||
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
|
||||
@@ -1223,7 +1156,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
if ( k == i || k == l ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( source->points[k], plane.normal ) - plane.dist;
|
||||
const double d = plane3_distance_to_point( plane, source->points[k] );
|
||||
if ( d < -ON_EPSILON ) { // source is on the negative side, so we want all
|
||||
// pass and target on the positive side
|
||||
fliptest = false;
|
||||
@@ -1245,8 +1178,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
// flip the normal if the source portal is backwards
|
||||
//
|
||||
if ( fliptest ) {
|
||||
VectorSubtract( vec3_origin, plane.normal, plane.normal );
|
||||
plane.dist = -plane.dist;
|
||||
plane = plane3_flipped( plane );
|
||||
}
|
||||
#if 1
|
||||
//
|
||||
@@ -1259,7 +1191,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
if ( k == j ) {
|
||||
continue;
|
||||
}
|
||||
d = DotProduct( pass->points[k], plane.normal ) - plane.dist;
|
||||
const double d = plane3_distance_to_point( plane, pass->points[k] );
|
||||
if ( d < -ON_EPSILON ) {
|
||||
break;
|
||||
}
|
||||
@@ -1279,12 +1211,12 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
}
|
||||
#else
|
||||
k = ( j + 1 ) % pass->numpoints;
|
||||
d = DotProduct( pass->points[k], plane.normal ) - plane.dist;
|
||||
d = vector3_dot( 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;
|
||||
d = vector3_dot( pass->points[k], plane.normal ) - plane.dist;
|
||||
if ( d < -ON_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
@@ -1293,8 +1225,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
// flip the normal if we want the back side
|
||||
//
|
||||
if ( flipclip ) {
|
||||
VectorSubtract( vec3_origin, plane.normal, plane.normal );
|
||||
plane.dist = -plane.dist;
|
||||
plane = plane3_flipped( plane );
|
||||
}
|
||||
|
||||
if ( numseperators >= maxseperators ) {
|
||||
@@ -1319,7 +1250,6 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip,
|
||||
*/
|
||||
void CreatePassages( int portalnum ){
|
||||
int i, j, k, n, numseperators, numsee;
|
||||
float d;
|
||||
vportal_t *portal, *p, *target;
|
||||
leaf_t *leaf;
|
||||
passage_t *passage, *lastpassage;
|
||||
@@ -1377,18 +1307,15 @@ void CreatePassages( int portalnum ){
|
||||
}
|
||||
for ( k = 0; k < numseperators; k++ )
|
||||
{
|
||||
//
|
||||
d = DotProduct( p->origin, seperators[k].normal ) - seperators[k].dist;
|
||||
//if completely at the back of the seperator plane
|
||||
if ( d < -p->radius + ON_EPSILON ) {
|
||||
if ( plane3_distance_to_point( seperators[k], p->origin ) < -p->radius + ON_EPSILON ) {
|
||||
break;
|
||||
}
|
||||
w = p->winding;
|
||||
for ( n = 0; n < w->numpoints; n++ )
|
||||
{
|
||||
d = DotProduct( w->points[n], seperators[k].normal ) - seperators[k].dist;
|
||||
//if at the front of the seperator
|
||||
if ( d > ON_EPSILON ) {
|
||||
if ( plane3_distance_to_point( seperators[k], w->points[n] ) > ON_EPSILON ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1407,7 +1334,7 @@ void CreatePassages( int portalnum ){
|
||||
/* ydnar: prefer correctness to stack overflow */
|
||||
//% memcpy( &in, p->winding, (int)((fixedWinding_t *)0)->points[p->winding->numpoints] );
|
||||
if ( p->winding->numpoints <= MAX_POINTS_ON_FIXED_WINDING ) {
|
||||
memcpy( &in, p->winding, (size_t)((fixedWinding_t *)0)->points[p->winding->numpoints] );
|
||||
memcpy( &in, p->winding, (size_t)&( ( (fixedWinding_t *)0 )->points[p->winding->numpoints] ) );
|
||||
// memcpy( &in, p->winding, offsetof( fixedWinding_t, points[p->winding->numpoints] ) );
|
||||
}
|
||||
else{
|
||||
@@ -1423,7 +1350,7 @@ void CreatePassages( int portalnum ){
|
||||
in.numpoints = MAX_POINTS_ON_FIXED_WINDING;
|
||||
}
|
||||
|
||||
res = PassageChopWinding( &in, &out, &seperators[ k ] );
|
||||
res = PassageChopWinding( &in, &out, seperators[ k ] );
|
||||
if ( res == &out ) {
|
||||
memcpy( &in, &out, sizeof( fixedWinding_t ) );
|
||||
}
|
||||
@@ -1557,9 +1484,7 @@ void SimpleFlood( vportal_t *srcportal, int leafnum ){
|
||||
void BasePortalVis( int portalnum ){
|
||||
int j, k;
|
||||
vportal_t *tp, *p;
|
||||
float d;
|
||||
fixedWinding_t *w;
|
||||
vec3_t dir;
|
||||
|
||||
|
||||
p = portals + portalnum;
|
||||
@@ -1593,13 +1518,12 @@ void BasePortalVis( int portalnum ){
|
||||
*/
|
||||
|
||||
if ( !p->sky && !tp->sky && farPlaneDist != 0.0f ) {
|
||||
VectorSubtract( p->origin, tp->origin, dir );
|
||||
if( farPlaneDistMode == 'o' ){
|
||||
if( VectorLength( dir ) > farPlaneDist )
|
||||
if( vector3_length( p->origin - tp->origin ) > farPlaneDist )
|
||||
continue;
|
||||
}
|
||||
else if( farPlaneDistMode == 'e' ){
|
||||
if( VectorLength( dir ) + p->radius + tp->radius > 2.0f * farPlaneDist )
|
||||
if( vector3_length( p->origin - tp->origin ) + p->radius + tp->radius > 2.0f * farPlaneDist )
|
||||
continue;
|
||||
}
|
||||
else if( farPlaneDistMode == 'r' ){
|
||||
@@ -1607,7 +1531,7 @@ void BasePortalVis( int portalnum ){
|
||||
continue;
|
||||
}
|
||||
else{ /* ydnar: this is known-to-be-working farplane code */
|
||||
if ( VectorLength( dir ) - p->radius - tp->radius > farPlaneDist )
|
||||
if ( vector3_length( p->origin - tp->origin ) - p->radius - tp->radius > farPlaneDist )
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1617,9 +1541,7 @@ void BasePortalVis( int portalnum ){
|
||||
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 ) {
|
||||
if ( plane3_distance_to_point( p->plane, w->points[k] ) > ON_EPSILON ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1630,9 +1552,7 @@ void BasePortalVis( int portalnum ){
|
||||
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 ) {
|
||||
if ( plane3_distance_to_point( tp->plane, w->points[k] ) < -ON_EPSILON ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,19 +111,12 @@ int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ){
|
||||
*/
|
||||
|
||||
void EmitPlanes( void ){
|
||||
int i;
|
||||
bspPlane_t *bp;
|
||||
plane_t *mp;
|
||||
|
||||
|
||||
/* walk plane list */
|
||||
mp = mapplanes;
|
||||
for ( i = 0; i < nummapplanes; i++, mp++ )
|
||||
plane_t *mp = mapplanes;
|
||||
for ( int i = 0; i < nummapplanes; i++, mp++ )
|
||||
{
|
||||
AUTOEXPAND_BY_REALLOC_BSP( Planes, 1024 );
|
||||
bp = &bspPlanes[ numBSPPlanes ];
|
||||
VectorCopy( mp->normal, bp->normal );
|
||||
bp->dist = mp->dist;
|
||||
bspPlanes[ numBSPPlanes ] = mp->plane;
|
||||
numBSPPlanes++;
|
||||
}
|
||||
|
||||
@@ -156,8 +149,8 @@ void EmitLeaf( node_t *node ){
|
||||
leaf_p->area = node->area;
|
||||
|
||||
/* emit bounding box */
|
||||
VectorCopy( node->mins, leaf_p->mins );
|
||||
VectorCopy( node->maxs, leaf_p->maxs );
|
||||
leaf_p->minmax.maxs = node->minmax.maxs;
|
||||
leaf_p->minmax.mins = node->minmax.mins;
|
||||
|
||||
/* emit leaf brushes */
|
||||
leaf_p->firstBSPLeafBrush = numBSPLeafBrushes;
|
||||
@@ -218,8 +211,8 @@ int EmitDrawNode_r( node_t *node ){
|
||||
n = &bspNodes[ n0 ];
|
||||
numBSPNodes++;
|
||||
|
||||
VectorCopy( node->mins, n->mins );
|
||||
VectorCopy( node->maxs, n->maxs );
|
||||
n->minmax.mins = node->minmax.mins;
|
||||
n->minmax.maxs = node->minmax.maxs;
|
||||
|
||||
if ( node->planenum & 1 ) {
|
||||
Error( "WriteDrawNodes_r: odd planenum" );
|
||||
@@ -534,66 +527,52 @@ void EmitFogs( void ){
|
||||
*/
|
||||
|
||||
void BeginModel( void ){
|
||||
bspModel_t *mod;
|
||||
brush_t *b;
|
||||
entity_t *e;
|
||||
vec3_t mins, maxs;
|
||||
vec3_t lgMins, lgMaxs; /* ydnar: lightgrid mins/maxs */
|
||||
parseMesh_t *p;
|
||||
int i;
|
||||
|
||||
MinMax minmax;
|
||||
MinMax lgMinmax; /* ydnar: lightgrid mins/maxs */
|
||||
|
||||
/* test limits */
|
||||
AUTOEXPAND_BY_REALLOC_BSP( Models, 256 );
|
||||
|
||||
/* get model and entity */
|
||||
mod = &bspModels[ numBSPModels ];
|
||||
e = &entities[ mapEntityNum ];
|
||||
|
||||
/* ydnar: lightgrid mins/maxs */
|
||||
ClearBounds( lgMins, lgMaxs );
|
||||
bspModel_t *mod = &bspModels[ numBSPModels ];
|
||||
const entity_t& e = entities[ mapEntityNum ];
|
||||
|
||||
/* bound the brushes */
|
||||
ClearBounds( mins, maxs );
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
for ( const brush_t *b = e.brushes; b; b = b->next )
|
||||
{
|
||||
/* ignore non-real brushes (origin, etc) */
|
||||
if ( b->numsides == 0 ) {
|
||||
continue;
|
||||
}
|
||||
AddPointToBounds( b->mins, mins, maxs );
|
||||
AddPointToBounds( b->maxs, mins, maxs );
|
||||
minmax.extend( b->minmax );
|
||||
|
||||
/* ydnar: lightgrid bounds */
|
||||
if ( b->compileFlags & C_LIGHTGRID ) {
|
||||
AddPointToBounds( b->mins, lgMins, lgMaxs );
|
||||
AddPointToBounds( b->maxs, lgMins, lgMaxs );
|
||||
lgMinmax.extend( b->minmax );
|
||||
}
|
||||
}
|
||||
|
||||
/* bound patches */
|
||||
for ( p = e->patches; p; p = p->next )
|
||||
for ( const parseMesh_t *p = e.patches; p; p = p->next )
|
||||
{
|
||||
for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
AddPointToBounds( p->mesh.verts[i].xyz, mins, maxs );
|
||||
for ( int i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
minmax.extend( p->mesh.verts[i].xyz );
|
||||
}
|
||||
|
||||
/* ydnar: lightgrid mins/maxs */
|
||||
if ( lgMins[ 0 ] < 99999 ) {
|
||||
if ( lgMinmax.mins[ 0 ] < 99999 ) {
|
||||
/* use lightgrid bounds */
|
||||
VectorCopy( lgMins, mod->mins );
|
||||
VectorCopy( lgMaxs, mod->maxs );
|
||||
mod->minmax = lgMinmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use brush/patch bounds */
|
||||
VectorCopy( mins, mod->mins );
|
||||
VectorCopy( maxs, mod->maxs );
|
||||
mod->minmax = minmax;
|
||||
}
|
||||
|
||||
/* note size */
|
||||
Sys_FPrintf( SYS_VRB, "BSP bounds: { %f %f %f } { %f %f %f }\n", mins[ 0 ], mins[ 1 ], mins[ 2 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ] );
|
||||
Sys_FPrintf( SYS_VRB, "Lightgrid bounds: { %f %f %f } { %f %f %f }\n", lgMins[ 0 ], lgMins[ 1 ], lgMins[ 2 ], lgMaxs[ 0 ], lgMaxs[ 1 ], lgMaxs[ 2 ] );
|
||||
Sys_FPrintf( SYS_VRB, "BSP bounds: { %f %f %f } { %f %f %f }\n", minmax.mins[0], minmax.mins[1], minmax.mins[2], minmax.maxs[0], minmax.maxs[1], minmax.maxs[2] );
|
||||
Sys_FPrintf( SYS_VRB, "Lightgrid bounds: { %f %f %f } { %f %f %f }\n", lgMinmax.mins[0], lgMinmax.mins[1], lgMinmax.mins[2], lgMinmax.maxs[0], lgMinmax.maxs[1], lgMinmax.maxs[2] );
|
||||
|
||||
/* set firsts */
|
||||
mod->firstBSPSurface = numBSPDrawSurfaces;
|
||||
|
||||
Reference in New Issue
Block a user