Index: bspfile_abstract.c =================================================================== --- bspfile_abstract.c (revision 158) +++ bspfile_abstract.c (working copy) @@ -683,8 +683,26 @@ ep->value = copystring( value ); } +/* +KeyExists() +returns true if entity has this key +*/ +qboolean KeyExists( const entity_t *ent, const char *key ) +{ + epair_t *ep; + + /* walk epair list */ + for( ep = ent->epairs; ep != NULL; ep = ep->next ) + { + if( !EPAIR_STRCMP( ep->key, key ) ) + return qtrue; + } + /* no match */ + return qfalse; +} + /* ValueForKey() gets the value for an entity key @@ -803,7 +821,6 @@ { const char *value; - /* get cast shadows */ if( castShadows != NULL ) { @@ -831,5 +848,19 @@ if( value[ 0 ] != '\0' ) *recvShadows = atoi( value ); } + + /* vortex: game-specific default eneity keys */ + value = ValueForKey( ent, "classname" ); + if (!Q_stricmp( game->magic, "dq" ) || !Q_stricmp( game->magic, "prophecy" ) ) + { + /* vortex: deluxe quake default shadow flags */ + if (!Q_stricmp( value, "func_wall" ) ) + { + if( recvShadows != NULL ) + *recvShadows = 1; + if( castShadows != NULL ) + *castShadows = 1; + } + } } Index: game_ef.h =================================================================== --- game_ef.h (revision 158) +++ game_ef.h (working copy) @@ -113,7 +113,16 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_etut.h =================================================================== --- game_etut.h (revision 158) +++ game_etut.h (working copy) @@ -148,7 +148,16 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 2.2f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_ja.h =================================================================== --- game_ja.h (revision 158) +++ game_ja.h (working copy) @@ -67,7 +67,16 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_jk2.h =================================================================== --- game_jk2.h (revision 158) +++ game_jk2.h (working copy) @@ -64,7 +64,16 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_qfusion.h =================================================================== --- game_qfusion.h (revision 158) +++ game_qfusion.h (working copy) @@ -1,195 +1,204 @@ -/* ------------------------------------------------------------------------------- - -This code is based on source provided under the terms of the Id Software -LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with the -GtkRadiant sources (see LICENSE_ID). If you did not receive a copy of -LICENSE_ID, please contact Id Software immediately at info@idsoftware.com. - -All changes and additions to the original source which have been developed by -other contributors (see CONTRIBUTORS) are provided under the terms of the -license the contributors choose (see LICENSE), to the extent permitted by the -LICENSE_ID. If you did not receive a copy of the contributor license, -please contact the GtkRadiant maintainers at info@gtkradiant.com immediately. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------------------- - -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." - -------------------------------------------------------------------------------- */ - - - -/* marker */ -#ifndef GAME_QFUSION_H -#define GAME_QFUSION_H - - - -/* ------------------------------------------------------------------------------- - -content and surface flags - -------------------------------------------------------------------------------- */ - -/* game flags */ -#define F_CONT_SOLID 1 /* an eye is never valid in a solid */ -#define F_CONT_LAVA 8 -#define F_CONT_SLIME 16 -#define F_CONT_WATER 32 -#define F_CONT_FOG 64 - -#define F_CONT_AREAPORTAL 0x8000 - -#define F_CONT_PLAYERCLIP 0x10000 -#define F_CONT_MONSTERCLIP 0x20000 -#define F_CONT_TELEPORTER 0x40000 -#define F_CONT_JUMPPAD 0x80000 -#define F_CONT_CLUSTERPORTAL 0x100000 -#define F_CONT_DONOTENTER 0x200000 -#define F_CONT_BOTCLIP 0x400000 - -#define F_CONT_ORIGIN 0x1000000 /* removed before bsping an entity */ - -#define F_CONT_BODY 0x2000000 /* should never be on a brush, only in game */ -#define F_CONT_CORPSE 0x4000000 -#define F_CONT_DETAIL 0x8000000 /* brushes not used for the bsp */ -#define F_CONT_STRUCTURAL 0x10000000 /* brushes used for the bsp */ -#define F_CONT_TRANSLUCENT 0x20000000 /* don't consume surface fragments inside */ -#define F_CONT_TRIGGER 0x40000000 -#define F_CONT_NODROP 0x80000000 /* don't leave bodies or items (death fog, lava) */ - -#define F_SURF_NODAMAGE 0x1 /* never give falling damage */ -#define F_SURF_SLICK 0x2 /* effects game physics */ -#define F_SURF_SKY 0x4 /* lighting from environment map */ -#define F_SURF_LADDER 0x8 -#define F_SURF_NOIMPACT 0x10 /* don't make missile explosions */ -#define F_SURF_NOMARKS 0x20 /* don't leave missile marks */ -#define F_SURF_FLESH 0x40 /* make flesh sounds and effects */ -#define F_SURF_NODRAW 0x80 /* don't generate a drawsurface at all */ -#define F_SURF_HINT 0x100 /* make a primary bsp splitter */ -#define F_SURF_SKIP 0x200 /* completely ignore, allowing non-closed brushes */ -#define F_SURF_NOLIGHTMAP 0x400 /* surface doesn't need a lightmap */ -#define F_SURF_POINTLIGHT 0x800 /* generate lighting info at vertexes */ -#define F_SURF_METALSTEPS 0x1000 /* clanking footsteps */ -#define F_SURF_NOSTEPS 0x2000 /* no footstep sounds */ -#define F_SURF_NONSOLID 0x4000 /* don't collide against curves with this set */ -#define F_SURF_LIGHTFILTER 0x8000 /* act as a light filter during q3map -light */ -#define F_SURF_ALPHASHADOW 0x10000 /* do per-pixel light shadow casting in q3map */ -#define F_SURF_NODLIGHT 0x20000 /* don't dlight even if solid (solid lava, skies) */ -#define F_SURF_DUST 0x40000 /* leave a dust trail when walking on this surface */ - -/* ydnar flags */ -#define F_SURF_VERTEXLIT (F_SURF_POINTLIGHT | F_SURF_NOLIGHTMAP) - - - -/* ------------------------------------------------------------------------------- - -game_t struct - -------------------------------------------------------------------------------- */ - -{ - "qfusion", /* -game x */ - "baseq3", /* default base game data dir */ - ".q3a", /* unix home sub-dir */ - "quake", /* magic path word */ - "scripts", /* shader directory */ - 2048, /* max lightmapped surface verts */ - 2048, /* max surface verts */ - 12288, /* max surface indexes */ - qtrue, /* flares */ - "flareshader", /* default flare shader */ - qfalse, /* wolf lighting model? */ - 512, /* lightmap width/height */ - 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap compensate */ - "FBSP", /* bsp file prefix */ - 1, /* bsp file version */ - qfalse, /* cod-style lump len/ofs order */ - LoadRBSPFile, /* bsp load function */ - WriteRBSPFile, /* bsp write function */ - - { - /* name contentFlags contentFlagsClear surfaceFlags surfaceFlagsClear compileFlags compileFlagsClear */ - - /* default */ - { "default", F_CONT_SOLID, -1, 0, -1, C_SOLID, -1 }, - - - /* ydnar */ - { "lightgrid", 0, 0, 0, 0, C_LIGHTGRID, 0 }, - { "antiportal", 0, 0, 0, 0, C_ANTIPORTAL, 0 }, - { "skip", 0, 0, 0, 0, C_SKIP, 0 }, - - - /* compiler */ - { "origin", F_CONT_ORIGIN, F_CONT_SOLID, 0, 0, C_ORIGIN | C_TRANSLUCENT, C_SOLID }, - { "areaportal", F_CONT_AREAPORTAL, F_CONT_SOLID, 0, 0, C_AREAPORTAL | C_TRANSLUCENT, C_SOLID }, - { "trans", F_CONT_TRANSLUCENT, 0, 0, 0, C_TRANSLUCENT, 0 }, - { "detail", F_CONT_DETAIL, 0, 0, 0, C_DETAIL, 0 }, - { "structural", F_CONT_STRUCTURAL, 0, 0, 0, C_STRUCTURAL, 0 }, - { "hint", 0, 0, F_SURF_HINT, 0, C_HINT, 0 }, - { "nodraw", 0, 0, F_SURF_NODRAW, 0, C_NODRAW, 0 }, - - { "alphashadow", 0, 0, F_SURF_ALPHASHADOW, 0, C_ALPHASHADOW | C_TRANSLUCENT, 0 }, - { "lightfilter", 0, 0, F_SURF_LIGHTFILTER, 0, C_LIGHTFILTER | C_TRANSLUCENT, 0 }, - { "nolightmap", 0, 0, F_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, - { "pointlight", 0, 0, F_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, - - - /* game */ - { "nonsolid", 0, F_CONT_SOLID, F_SURF_NONSOLID, 0, 0, C_SOLID }, - - { "trigger", F_CONT_TRIGGER, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - - { "water", F_CONT_WATER, F_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, - { "slime", F_CONT_SLIME, F_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, - { "lava", F_CONT_LAVA, F_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, - - { "playerclip", F_CONT_PLAYERCLIP, F_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, - { "monsterclip", F_CONT_MONSTERCLIP, F_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, - { "nodrop", F_CONT_NODROP, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - - { "clusterportal", F_CONT_CLUSTERPORTAL, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - { "donotenter", F_CONT_DONOTENTER, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - { "botclip", F_CONT_BOTCLIP, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - - { "fog", F_CONT_FOG, F_CONT_SOLID, 0, 0, C_FOG, C_SOLID }, - { "sky", 0, 0, F_SURF_SKY, 0, C_SKY, 0 }, - - { "slick", 0, 0, F_SURF_SLICK, 0, 0, 0 }, - - { "noimpact", 0, 0, F_SURF_NOIMPACT, 0, 0, 0 }, - { "nomarks", 0, 0, F_SURF_NOMARKS, 0, C_NOMARKS, 0 }, - { "ladder", 0, 0, F_SURF_LADDER, 0, 0, 0 }, - { "nodamage", 0, 0, F_SURF_NODAMAGE, 0, 0, 0 }, - { "metalsteps", 0, 0, F_SURF_METALSTEPS, 0, 0, 0 }, - { "flesh", 0, 0, F_SURF_FLESH, 0, 0, 0 }, - { "nosteps", 0, 0, F_SURF_NOSTEPS, 0, 0, 0 }, - { "nodlight", 0, 0, F_SURF_NODLIGHT, 0, 0, 0 }, - { "dust", 0, 0, F_SURF_DUST, 0, 0, 0 }, - - - /* null */ - { NULL, 0, 0, 0, 0, 0, 0 } - } -} - - - -/* end marker */ -#endif - +/* ------------------------------------------------------------------------------- + +This code is based on source provided under the terms of the Id Software +LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with the +GtkRadiant sources (see LICENSE_ID). If you did not receive a copy of +LICENSE_ID, please contact Id Software immediately at info@idsoftware.com. + +All changes and additions to the original source which have been developed by +other contributors (see CONTRIBUTORS) are provided under the terms of the +license the contributors choose (see LICENSE), to the extent permitted by the +LICENSE_ID. If you did not receive a copy of the contributor license, +please contact the GtkRadiant maintainers at info@gtkradiant.com immediately. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------------------- + +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." + +------------------------------------------------------------------------------- */ + + + +/* marker */ +#ifndef GAME_QFUSION_H +#define GAME_QFUSION_H + + + +/* ------------------------------------------------------------------------------- + +content and surface flags + +------------------------------------------------------------------------------- */ + +/* game flags */ +#define F_CONT_SOLID 1 /* an eye is never valid in a solid */ +#define F_CONT_LAVA 8 +#define F_CONT_SLIME 16 +#define F_CONT_WATER 32 +#define F_CONT_FOG 64 + +#define F_CONT_AREAPORTAL 0x8000 + +#define F_CONT_PLAYERCLIP 0x10000 +#define F_CONT_MONSTERCLIP 0x20000 +#define F_CONT_TELEPORTER 0x40000 +#define F_CONT_JUMPPAD 0x80000 +#define F_CONT_CLUSTERPORTAL 0x100000 +#define F_CONT_DONOTENTER 0x200000 +#define F_CONT_BOTCLIP 0x400000 + +#define F_CONT_ORIGIN 0x1000000 /* removed before bsping an entity */ + +#define F_CONT_BODY 0x2000000 /* should never be on a brush, only in game */ +#define F_CONT_CORPSE 0x4000000 +#define F_CONT_DETAIL 0x8000000 /* brushes not used for the bsp */ +#define F_CONT_STRUCTURAL 0x10000000 /* brushes used for the bsp */ +#define F_CONT_TRANSLUCENT 0x20000000 /* don't consume surface fragments inside */ +#define F_CONT_TRIGGER 0x40000000 +#define F_CONT_NODROP 0x80000000 /* don't leave bodies or items (death fog, lava) */ + +#define F_SURF_NODAMAGE 0x1 /* never give falling damage */ +#define F_SURF_SLICK 0x2 /* effects game physics */ +#define F_SURF_SKY 0x4 /* lighting from environment map */ +#define F_SURF_LADDER 0x8 +#define F_SURF_NOIMPACT 0x10 /* don't make missile explosions */ +#define F_SURF_NOMARKS 0x20 /* don't leave missile marks */ +#define F_SURF_FLESH 0x40 /* make flesh sounds and effects */ +#define F_SURF_NODRAW 0x80 /* don't generate a drawsurface at all */ +#define F_SURF_HINT 0x100 /* make a primary bsp splitter */ +#define F_SURF_SKIP 0x200 /* completely ignore, allowing non-closed brushes */ +#define F_SURF_NOLIGHTMAP 0x400 /* surface doesn't need a lightmap */ +#define F_SURF_POINTLIGHT 0x800 /* generate lighting info at vertexes */ +#define F_SURF_METALSTEPS 0x1000 /* clanking footsteps */ +#define F_SURF_NOSTEPS 0x2000 /* no footstep sounds */ +#define F_SURF_NONSOLID 0x4000 /* don't collide against curves with this set */ +#define F_SURF_LIGHTFILTER 0x8000 /* act as a light filter during q3map -light */ +#define F_SURF_ALPHASHADOW 0x10000 /* do per-pixel light shadow casting in q3map */ +#define F_SURF_NODLIGHT 0x20000 /* don't dlight even if solid (solid lava, skies) */ +#define F_SURF_DUST 0x40000 /* leave a dust trail when walking on this surface */ + +/* ydnar flags */ +#define F_SURF_VERTEXLIT (F_SURF_POINTLIGHT | F_SURF_NOLIGHTMAP) + + + +/* ------------------------------------------------------------------------------- + +game_t struct + +------------------------------------------------------------------------------- */ + +{ + "qfusion", /* -game x */ + "baseq3", /* default base game data dir */ + ".q3a", /* unix home sub-dir */ + "quake", /* magic path word */ + "scripts", /* shader directory */ + 2048, /* max lightmapped surface verts */ + 2048, /* max surface verts */ + 12288, /* max surface indexes */ + qtrue, /* flares */ + "flareshader", /* default flare shader */ + qfalse, /* wolf lighting model? */ + 512, /* lightmap width/height */ + 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ + 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ + "FBSP", /* bsp file prefix */ + 1, /* bsp file version */ + qfalse, /* cod-style lump len/ofs order */ + LoadRBSPFile, /* bsp load function */ + WriteRBSPFile, /* bsp write function */ + + { + /* name contentFlags contentFlagsClear surfaceFlags surfaceFlagsClear compileFlags compileFlagsClear */ + + /* default */ + { "default", F_CONT_SOLID, -1, 0, -1, C_SOLID, -1 }, + + + /* ydnar */ + { "lightgrid", 0, 0, 0, 0, C_LIGHTGRID, 0 }, + { "antiportal", 0, 0, 0, 0, C_ANTIPORTAL, 0 }, + { "skip", 0, 0, 0, 0, C_SKIP, 0 }, + + + /* compiler */ + { "origin", F_CONT_ORIGIN, F_CONT_SOLID, 0, 0, C_ORIGIN | C_TRANSLUCENT, C_SOLID }, + { "areaportal", F_CONT_AREAPORTAL, F_CONT_SOLID, 0, 0, C_AREAPORTAL | C_TRANSLUCENT, C_SOLID }, + { "trans", F_CONT_TRANSLUCENT, 0, 0, 0, C_TRANSLUCENT, 0 }, + { "detail", F_CONT_DETAIL, 0, 0, 0, C_DETAIL, 0 }, + { "structural", F_CONT_STRUCTURAL, 0, 0, 0, C_STRUCTURAL, 0 }, + { "hint", 0, 0, F_SURF_HINT, 0, C_HINT, 0 }, + { "nodraw", 0, 0, F_SURF_NODRAW, 0, C_NODRAW, 0 }, + + { "alphashadow", 0, 0, F_SURF_ALPHASHADOW, 0, C_ALPHASHADOW | C_TRANSLUCENT, 0 }, + { "lightfilter", 0, 0, F_SURF_LIGHTFILTER, 0, C_LIGHTFILTER | C_TRANSLUCENT, 0 }, + { "nolightmap", 0, 0, F_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, + { "pointlight", 0, 0, F_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, + + + /* game */ + { "nonsolid", 0, F_CONT_SOLID, F_SURF_NONSOLID, 0, 0, C_SOLID }, + + { "trigger", F_CONT_TRIGGER, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + + { "water", F_CONT_WATER, F_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, + { "slime", F_CONT_SLIME, F_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, + { "lava", F_CONT_LAVA, F_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, + + { "playerclip", F_CONT_PLAYERCLIP, F_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, + { "monsterclip", F_CONT_MONSTERCLIP, F_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, + { "nodrop", F_CONT_NODROP, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + + { "clusterportal", F_CONT_CLUSTERPORTAL, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + { "donotenter", F_CONT_DONOTENTER, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + { "botclip", F_CONT_BOTCLIP, F_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + + { "fog", F_CONT_FOG, F_CONT_SOLID, 0, 0, C_FOG, C_SOLID }, + { "sky", 0, 0, F_SURF_SKY, 0, C_SKY, 0 }, + + { "slick", 0, 0, F_SURF_SLICK, 0, 0, 0 }, + + { "noimpact", 0, 0, F_SURF_NOIMPACT, 0, 0, 0 }, + { "nomarks", 0, 0, F_SURF_NOMARKS, 0, C_NOMARKS, 0 }, + { "ladder", 0, 0, F_SURF_LADDER, 0, 0, 0 }, + { "nodamage", 0, 0, F_SURF_NODAMAGE, 0, 0, 0 }, + { "metalsteps", 0, 0, F_SURF_METALSTEPS, 0, 0, 0 }, + { "flesh", 0, 0, F_SURF_FLESH, 0, 0, 0 }, + { "nosteps", 0, 0, F_SURF_NOSTEPS, 0, 0, 0 }, + { "nodlight", 0, 0, F_SURF_NODLIGHT, 0, 0, 0 }, + { "dust", 0, 0, F_SURF_DUST, 0, 0, 0 }, + + + /* null */ + { NULL, 0, 0, 0, 0, 0, 0 } + } +} + + + +/* end marker */ +#endif + Index: game_quake3.h =================================================================== --- game_quake3.h (revision 158) +++ game_quake3.h (working copy) @@ -112,7 +112,16 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_sof2.h =================================================================== --- game_sof2.h (revision 158) +++ game_sof2.h (working copy) @@ -139,7 +139,16 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_tenebrae.h =================================================================== --- game_tenebrae.h (revision 158) +++ game_tenebrae.h (working copy) @@ -112,7 +112,16 @@ qfalse, /* wolf lighting model? */ 512, /* lightmap width/height */ 2.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qtrue, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qtrue, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_tremulous.h =================================================================== --- game_tremulous.h (revision 158) +++ game_tremulous.h (working copy) @@ -1,160 +1,169 @@ -/* ------------------------------------------------------------------------------- - -Copyright (C) 1999-2006 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." - -------------------------------------------------------------------------------- */ - -/* Tremulous support, by LinuxManMikeC */ - - -/* marker */ -#ifndef GAME_TREMULOUS_H -#define GAME_TREMULOUS_H - - - -/* ------------------------------------------------------------------------------- - -content and surface flags - also uses defines from game_quake3.h - -------------------------------------------------------------------------------- */ -#define TREM_CONT_NOALIENBUILD 0x1000 -#define TREM_CONT_NOHUMANBUILD 0x2000 -#define TREM_CONT_NOBUILD 0x4000 - -#define TREM_SURF_NOALIENBUILDSURFACE 0x80000 -#define TREM_SURF_NOHUMANBUILDSURFACE 0x100000 -#define TREM_SURF_NOBUILDSURFACE 0x200000 - - - -/* ------------------------------------------------------------------------------- - -game_t struct - -------------------------------------------------------------------------------- */ - -{ - "tremulous", /* -game x */ - "base", /* default base game data dir */ - ".tremulous", /* unix home sub-dir */ - "tremulous", /* magic path word - think this is right for trem*/ - "scripts", /* shader directory */ - 64, /* max lightmapped surface verts */ - 999, /* max surface verts */ - 6000, /* max surface indexes */ - qfalse, /* flares */ - "flareshader", /* default flare shader */ - qfalse, /* wolf lighting model? */ - 128, /* lightmap width/height */ - 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap compensate */ - "IBSP", /* bsp file prefix */ - 46, /* bsp file version */ - qfalse, /* cod-style lump len/ofs order */ - LoadIBSPFile, /* bsp load function */ - WriteIBSPFile, /* bsp write function */ - - { - /* name contentFlags contentFlagsClear surfaceFlags surfaceFlagsClear compileFlags compileFlagsClear */ - - /* default */ - { "default", Q_CONT_SOLID, -1, 0, -1, C_SOLID, -1 }, - - - /* ydnar */ - { "lightgrid", 0, 0, 0, 0, C_LIGHTGRID, 0 }, - { "antiportal", 0, 0, 0, 0, C_ANTIPORTAL, 0 }, - { "skip", 0, 0, 0, 0, C_SKIP, 0 }, - - - /* compiler */ - { "origin", Q_CONT_ORIGIN, Q_CONT_SOLID, 0, 0, C_ORIGIN | C_TRANSLUCENT, C_SOLID }, - { "areaportal", Q_CONT_AREAPORTAL, Q_CONT_SOLID, 0, 0, C_AREAPORTAL | C_TRANSLUCENT, C_SOLID }, - { "trans", Q_CONT_TRANSLUCENT, 0, 0, 0, C_TRANSLUCENT, 0 }, - { "detail", Q_CONT_DETAIL, 0, 0, 0, C_DETAIL, 0 }, - { "structural", Q_CONT_STRUCTURAL, 0, 0, 0, C_STRUCTURAL, 0 }, - { "hint", 0, 0, Q_SURF_HINT, 0, C_HINT, 0 }, - { "nodraw", 0, 0, Q_SURF_NODRAW, 0, C_NODRAW, 0 }, - - { "alphashadow", 0, 0, Q_SURF_ALPHASHADOW, 0, C_ALPHASHADOW | C_TRANSLUCENT, 0 }, - { "lightfilter", 0, 0, Q_SURF_LIGHTFILTER, 0, C_LIGHTFILTER | C_TRANSLUCENT, 0 }, - { "nolightmap", 0, 0, Q_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, - { "pointlight", 0, 0, Q_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, - - - /* game */ - { "nonsolid", 0, Q_CONT_SOLID, Q_SURF_NONSOLID, 0, 0, C_SOLID }, - - { "trigger", Q_CONT_TRIGGER, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - - { "water", Q_CONT_WATER, Q_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, - { "slime", Q_CONT_SLIME, Q_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, - { "lava", Q_CONT_LAVA, Q_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, - - { "playerclip", Q_CONT_PLAYERCLIP, Q_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, - { "monsterclip", Q_CONT_MONSTERCLIP, Q_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, - { "nodrop", Q_CONT_NODROP, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - - { "clusterportal", Q_CONT_CLUSTERPORTAL, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - { "donotenter", Q_CONT_DONOTENTER, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - { "botclip", Q_CONT_BOTCLIP, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, - - { "fog", Q_CONT_FOG, Q_CONT_SOLID, 0, 0, C_FOG, C_SOLID }, - { "sky", 0, 0, Q_SURF_SKY, 0, C_SKY, 0 }, - - { "slick", 0, 0, Q_SURF_SLICK, 0, 0, 0 }, - - { "noimpact", 0, 0, Q_SURF_NOIMPACT, 0, 0, 0 }, - { "nomarks", 0, 0, Q_SURF_NOMARKS, 0, C_NOMARKS, 0 }, - { "ladder", 0, 0, Q_SURF_LADDER, 0, 0, 0 }, - { "nodamage", 0, 0, Q_SURF_NODAMAGE, 0, 0, 0 }, - { "metalsteps", 0, 0, Q_SURF_METALSTEPS, 0, 0, 0 }, - { "flesh", 0, 0, Q_SURF_FLESH, 0, 0, 0 }, - { "nosteps", 0, 0, Q_SURF_NOSTEPS, 0, 0, 0 }, - { "nodlight", 0, 0, Q_SURF_NODLIGHT, 0, 0, 0 }, - { "dust", 0, 0, Q_SURF_DUST, 0, 0, 0 }, - - - /* tremulous */ - {"noalienbuild", TREM_CONT_NOALIENBUILD,0,0,0,0,0}, - {"nohumanbuild", TREM_CONT_NOHUMANBUILD,0,0,0,0,0}, - {"nobuild", TREM_CONT_NOBUILD,0,0,0,0,0}, - - {"noalienbuildsurface", 0,0,TREM_SURF_NOALIENBUILDSURFACE,0,0,0}, - {"nohumanbuildsurface", 0,0,TREM_SURF_NOHUMANBUILDSURFACE,0,0,0}, - {"nobuildsurface", 0,0,TREM_SURF_NOBUILDSURFACE,0,0,0}, - - - /* null */ - { NULL, 0, 0, 0, 0, 0, 0 } - } -} - - - -/* end marker */ -#endif - +/* ------------------------------------------------------------------------------- + +Copyright (C) 1999-2006 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." + +------------------------------------------------------------------------------- */ + +/* Tremulous support, by LinuxManMikeC */ + + +/* marker */ +#ifndef GAME_TREMULOUS_H +#define GAME_TREMULOUS_H + + + +/* ------------------------------------------------------------------------------- + +content and surface flags - also uses defines from game_quake3.h + +------------------------------------------------------------------------------- */ +#define TREM_CONT_NOALIENBUILD 0x1000 +#define TREM_CONT_NOHUMANBUILD 0x2000 +#define TREM_CONT_NOBUILD 0x4000 + +#define TREM_SURF_NOALIENBUILDSURFACE 0x80000 +#define TREM_SURF_NOHUMANBUILDSURFACE 0x100000 +#define TREM_SURF_NOBUILDSURFACE 0x200000 + + + +/* ------------------------------------------------------------------------------- + +game_t struct + +------------------------------------------------------------------------------- */ + +{ + "tremulous", /* -game x */ + "base", /* default base game data dir */ + ".tremulous", /* unix home sub-dir */ + "tremulous", /* magic path word - think this is right for trem*/ + "scripts", /* shader directory */ + 64, /* max lightmapped surface verts */ + 999, /* max surface verts */ + 6000, /* max surface indexes */ + qfalse, /* flares */ + "flareshader", /* default flare shader */ + qfalse, /* wolf lighting model? */ + 128, /* lightmap width/height */ + 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ + 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ + "IBSP", /* bsp file prefix */ + 46, /* bsp file version */ + qfalse, /* cod-style lump len/ofs order */ + LoadIBSPFile, /* bsp load function */ + WriteIBSPFile, /* bsp write function */ + + { + /* name contentFlags contentFlagsClear surfaceFlags surfaceFlagsClear compileFlags compileFlagsClear */ + + /* default */ + { "default", Q_CONT_SOLID, -1, 0, -1, C_SOLID, -1 }, + + + /* ydnar */ + { "lightgrid", 0, 0, 0, 0, C_LIGHTGRID, 0 }, + { "antiportal", 0, 0, 0, 0, C_ANTIPORTAL, 0 }, + { "skip", 0, 0, 0, 0, C_SKIP, 0 }, + + + /* compiler */ + { "origin", Q_CONT_ORIGIN, Q_CONT_SOLID, 0, 0, C_ORIGIN | C_TRANSLUCENT, C_SOLID }, + { "areaportal", Q_CONT_AREAPORTAL, Q_CONT_SOLID, 0, 0, C_AREAPORTAL | C_TRANSLUCENT, C_SOLID }, + { "trans", Q_CONT_TRANSLUCENT, 0, 0, 0, C_TRANSLUCENT, 0 }, + { "detail", Q_CONT_DETAIL, 0, 0, 0, C_DETAIL, 0 }, + { "structural", Q_CONT_STRUCTURAL, 0, 0, 0, C_STRUCTURAL, 0 }, + { "hint", 0, 0, Q_SURF_HINT, 0, C_HINT, 0 }, + { "nodraw", 0, 0, Q_SURF_NODRAW, 0, C_NODRAW, 0 }, + + { "alphashadow", 0, 0, Q_SURF_ALPHASHADOW, 0, C_ALPHASHADOW | C_TRANSLUCENT, 0 }, + { "lightfilter", 0, 0, Q_SURF_LIGHTFILTER, 0, C_LIGHTFILTER | C_TRANSLUCENT, 0 }, + { "nolightmap", 0, 0, Q_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, + { "pointlight", 0, 0, Q_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, + + + /* game */ + { "nonsolid", 0, Q_CONT_SOLID, Q_SURF_NONSOLID, 0, 0, C_SOLID }, + + { "trigger", Q_CONT_TRIGGER, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + + { "water", Q_CONT_WATER, Q_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, + { "slime", Q_CONT_SLIME, Q_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, + { "lava", Q_CONT_LAVA, Q_CONT_SOLID, 0, 0, C_LIQUID | C_TRANSLUCENT, C_SOLID }, + + { "playerclip", Q_CONT_PLAYERCLIP, Q_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, + { "monsterclip", Q_CONT_MONSTERCLIP, Q_CONT_SOLID, 0, 0, C_DETAIL | C_TRANSLUCENT, C_SOLID }, + { "nodrop", Q_CONT_NODROP, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + + { "clusterportal", Q_CONT_CLUSTERPORTAL, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + { "donotenter", Q_CONT_DONOTENTER, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + { "botclip", Q_CONT_BOTCLIP, Q_CONT_SOLID, 0, 0, C_TRANSLUCENT, C_SOLID }, + + { "fog", Q_CONT_FOG, Q_CONT_SOLID, 0, 0, C_FOG, C_SOLID }, + { "sky", 0, 0, Q_SURF_SKY, 0, C_SKY, 0 }, + + { "slick", 0, 0, Q_SURF_SLICK, 0, 0, 0 }, + + { "noimpact", 0, 0, Q_SURF_NOIMPACT, 0, 0, 0 }, + { "nomarks", 0, 0, Q_SURF_NOMARKS, 0, C_NOMARKS, 0 }, + { "ladder", 0, 0, Q_SURF_LADDER, 0, 0, 0 }, + { "nodamage", 0, 0, Q_SURF_NODAMAGE, 0, 0, 0 }, + { "metalsteps", 0, 0, Q_SURF_METALSTEPS, 0, 0, 0 }, + { "flesh", 0, 0, Q_SURF_FLESH, 0, 0, 0 }, + { "nosteps", 0, 0, Q_SURF_NOSTEPS, 0, 0, 0 }, + { "nodlight", 0, 0, Q_SURF_NODLIGHT, 0, 0, 0 }, + { "dust", 0, 0, Q_SURF_DUST, 0, 0, 0 }, + + + /* tremulous */ + {"noalienbuild", TREM_CONT_NOALIENBUILD,0,0,0,0,0}, + {"nohumanbuild", TREM_CONT_NOHUMANBUILD,0,0,0,0,0}, + {"nobuild", TREM_CONT_NOBUILD,0,0,0,0,0}, + + {"noalienbuildsurface", 0,0,TREM_SURF_NOALIENBUILDSURFACE,0,0,0}, + {"nohumanbuildsurface", 0,0,TREM_SURF_NOHUMANBUILDSURFACE,0,0,0}, + {"nobuildsurface", 0,0,TREM_SURF_NOBUILDSURFACE,0,0,0}, + + + /* null */ + { NULL, 0, 0, 0, 0, 0, 0 } + } +} + + + +/* end marker */ +#endif + Index: game_wolf.h =================================================================== --- game_wolf.h (revision 158) +++ game_wolf.h (working copy) @@ -129,7 +129,16 @@ qtrue, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: game_wolfet.h =================================================================== --- game_wolfet.h (revision 158) +++ game_wolfet.h (working copy) @@ -66,7 +66,16 @@ qtrue, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ + 1.0f, /* lightgrid scale */ + 1.0f, /* lightgrid ambient scale */ + qfalse, /* disable shader lightstyles hack */ + qfalse, /* keep light entities on bsp */ + 8, /* default patchMeta subdivisions tolerance */ + qfalse, /* patch casting enabled */ + qfalse, /* compile deluxemaps */ + 0, /* deluxemaps default mode */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ Index: light.c =================================================================== --- light.c (revision 158) +++ light.c (working copy) @@ -313,7 +313,15 @@ flags |= LIGHT_GRID; flags &= ~LIGHT_SURFACES; } - + + /* vortex: unnormalized? */ + if (spawnflags & 32) + flags |= LIGHT_UNNORMALIZED; + + /* vortex: distance atten? */ + if (spawnflags & 64) + flags |= LIGHT_ATTEN_DISTANCE; + /* store the flags */ light->flags = flags; @@ -357,12 +365,13 @@ intensity *= scale; /* ydnar: get deviance and samples */ + /* VorteX: now set start value for _samples when _deviance is found */ deviance = FloatForKey( e, "_deviance" ); if( deviance == 0.0f ) deviance = FloatForKey( e, "_deviation" ); if( deviance == 0.0f ) deviance = FloatForKey( e, "_jitter" ); - numSamples = IntForKey( e, "_samples" ); + numSamples = max(IntForKey( e, "_samples" ), deviance); if( deviance < 0.0f || numSamples < 1 ) { deviance = 0.0f; @@ -385,14 +394,16 @@ if( _color && _color[ 0 ] ) { sscanf( _color, "%f %f %f", &light->color[ 0 ], &light->color[ 1 ], &light->color[ 2 ] ); - ColorNormalize( light->color, light->color ); + if (!(light->flags & LIGHT_UNNORMALIZED)) + { + ColorNormalize( light->color, light->color ); + } } else light->color[ 0 ] = light->color[ 1 ] = light->color[ 2 ] = 1.0f; - + intensity = intensity * pointScale; light->photons = intensity; - light->type = EMIT_POINT; /* set falloff threshold */ @@ -741,6 +752,7 @@ /* clear color */ VectorClear( trace->color ); + VectorClear( trace->colorNoShadow ); /* ydnar: early out */ if( !(light->flags & LIGHT_SURFACES) || light->envelope <= 0.0f ) @@ -766,7 +778,6 @@ float d; vec3_t pushedOrigin; - /* project sample point into light plane */ d = DotProduct( trace->origin, light->normal ) - light->dist; if( d < 3.0f ) @@ -881,8 +892,7 @@ { float distByNormal, radiusAtDist, sampleRadius; vec3_t pointAtDist, distToSample; - - + /* do cone calculation */ distByNormal = -DotProduct( trace->displacement, light->normal ); if( distByNormal < 0.0f ) @@ -922,6 +932,9 @@ add = light->photons * angle; if( add <= 0.0f ) return 0; + + /* VorteX: set noShadow color */ + VectorScale(light->color, add, trace->colorNoShadow); /* setup trace */ trace->testAll = qtrue; @@ -942,6 +955,9 @@ /* return to sender */ return 1; } + + /* VorteX: set noShadow color */ + VectorScale(light->color, add, trace->colorNoShadow); /* ydnar: changed to a variable number */ if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) ) @@ -1378,6 +1394,56 @@ break; } + /////// Floodlighting for point ////////////////// + //do our floodlight ambient occlusion loop, and add a single contribution based on the brightest dir + if (floodlighty) + { + int q; + float addSize,f; + vec3_t col,dir; + col[0]=col[1]=col[2]=floodlightIntensity; + dir[0]=dir[1]=0; + dir[2]=1; + + trace.testOcclusion = qtrue; + trace.forceSunlight = qfalse; + trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; + trace.testAll = qtrue; + + for (q=0;q<2;q++) + { + if (q==0) //upper hemisphere + { + trace.normal[0]=0; + trace.normal[1]=0; + trace.normal[2]=1; + } + else //lower hemisphere + { + trace.normal[0]=0; + trace.normal[1]=0; + trace.normal[2]=-1; + } + + f = FloodLightForSample(&trace, floodlightDistance, floodlight_lowquality); + + contributions[ numCon ].color[0]=col[0]*f; + contributions[ numCon ].color[1]=col[1]*f; + contributions[ numCon ].color[2]=col[2]*f; + + contributions[ numCon ].dir[0]=dir[0]; + contributions[ numCon ].dir[1]=dir[1]; + contributions[ numCon ].dir[2]=dir[2]; + + contributions[ numCon ].style = 0; + numCon++; + /* push average direction around */ + addSize = VectorLength( col ); + VectorMA( gp->dir, addSize, dir, gp->dir ); + } + } + ///////////////////// + /* normalize to get primary light direction */ VectorNormalize( gp->dir, gp->dir ); @@ -1420,6 +1486,9 @@ /* ambient light will be at 1/4 the value of directed light */ /* (ydnar: nuke this in favor of more dramatic lighting?) */ + /* (PM: how about actually making it work? d=1 when it got here for single lights/sun :P */ +// 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 ] ); } @@ -1437,8 +1506,10 @@ for( j = 0; j < 3; j++ ) if( color[ j ] < minGridLight[ j ] ) color[ j ] = minGridLight[ j ]; - ColorToBytes( color, bgp->ambient[ i ], 1.0f ); - ColorToBytes( gp->directed[ i ], bgp->directed[ i ], 1.0f ); + + /* vortex: apply gridscale and gridambientscale here */ + ColorToBytes( color, bgp->ambient[ i ], gridScale*gridAmbientScale ); + ColorToBytes( gp->directed[ i ], bgp->directed[ i ], gridScale ); } /* debug code */ @@ -1654,14 +1725,12 @@ if( dirty ) { Sys_Printf( "--- DirtyRawLightmap ---\n" ); - - - - RunThreadsOnIndividual( numRawLightmaps, qtrue, DirtyRawLightmap ); } - + /* floodlight pass */ + FloodlightRawLightmaps(); + /* ydnar: set up light envelopes */ SetupEnvelopes( qfalse, fast ); @@ -1774,12 +1843,64 @@ /* note it */ Sys_Printf( "--- Light ---\n" ); - + Sys_Printf( "--- ProcessGameSpecific ---\n" ); + /* set standard game flags */ wolfLight = game->wolfLight; + if (wolfLight == qtrue) + Sys_Printf( " lightning model: wolf\n" ); + else + Sys_Printf( " lightning model: quake3\n" ); + lmCustomSize = game->lightmapSize; + Sys_Printf( " lightmap size: %d x %d pixels\n", lmCustomSize, lmCustomSize ); + lightmapGamma = game->lightmapGamma; + Sys_Printf( " lightning gamma: %f\n", lightmapGamma ); + lightmapCompensate = game->lightmapCompensate; + Sys_Printf( " lightning compensation: %f\n", lightmapCompensate ); + + lightmapExposure = game->lightmapExposure; + Sys_Printf( " lightning exposure: %f\n", lightmapExposure ); + + gridScale = game->gridScale; + Sys_Printf( " lightgrid scale: %f\n", gridScale ); + + gridAmbientScale = game->gridAmbientScale; + Sys_Printf( " lightgrid ambient scale: %f\n", gridAmbientScale ); + + noStyles = game->noStyles; + if (noStyles == qtrue) + Sys_Printf( " shader lightstyles hack: disabled\n" ); + else + Sys_Printf( " shader lightstyles hack: enabled\n" ); + + keepLights = game->keepLights; + if (keepLights == qtrue) + Sys_Printf( " keep lights: enabled\n" ); + else + Sys_Printf( " keep lights: disabled\n" ); + + patchShadows = game->patchShadows; + if (patchShadows == qtrue) + Sys_Printf( " patch shadows: enabled\n" ); + else + Sys_Printf( " patch shadows: disabled\n" ); + + deluxemap = game->deluxeMap; + deluxemode = game->deluxeMode; + if (deluxemap == qtrue) + { + if (deluxemode) + Sys_Printf( " deluxemapping: enabled with tangentspace deluxemaps\n" ); + else + Sys_Printf( " deluxemapping: enabled with modelspace deluxemaps\n" ); + } + else + Sys_Printf( " deluxemapping: disabled\n" ); + + Sys_Printf( "--- ProcessCommandLine ---\n" ); /* process commandline arguments */ for( i = 1; i < (argc - 1); i++ ) @@ -1827,6 +1948,22 @@ Sys_Printf( "All light scaled by %f\n", f ); i++; } + + else if( !strcmp( argv[ i ], "-gridscale" ) ) + { + f = atof( argv[ i + 1 ] ); + Sys_Printf( "Grid lightning scaled by %f\n", f ); + gridScale *= f; + i++; + } + + else if( !strcmp( argv[ i ], "-gridambientscale" ) ) + { + f = atof( argv[ i + 1 ] ); + Sys_Printf( "Grid ambient lightning scaled by %f\n", f ); + gridAmbientScale *= f; + i++; + } else if( !strcmp( argv[ i ], "-gamma" ) ) { @@ -1836,6 +1973,14 @@ i++; } + else if( !strcmp( argv[ i ], "-exposure" ) ) + { + f = atof( argv[ i + 1 ] ); + lightmapExposure = f; + Sys_Printf( "Lighting exposure set to %f\n", lightmapExposure ); + i++; + } + else if( !strcmp( argv[ i ], "-compensate" ) ) { f = atof( argv[ i + 1 ] ); @@ -1889,12 +2034,6 @@ Sys_Printf( "Dark lightmap seams enabled\n" ); } - - - - - - else if( !strcmp( argv[ i ], "-shadeangle" ) ) { shadeAngleDegrees = atof( argv[ i + 1 ] ); @@ -1927,13 +2066,28 @@ Sys_Printf( "Approximating lightmaps within a byte tolerance of %d\n", approximateTolerance ); i++; } - else if( !strcmp( argv[ i ], "-deluxe" ) || !strcmp( argv[ i ], "-deluxemap" ) ) { deluxemap = qtrue; Sys_Printf( "Generating deluxemaps for average light direction\n" ); } - + else if( !strcmp( argv[ i ], "-deluxemode" )) + { + deluxemode = atoi( argv[ i + 1 ] ); + if (deluxemode == 0 || deluxemode > 1 || deluxemode < 0) + { + Sys_Printf( "Generating modelspace deluxemaps\n" ); + deluxemode = 0; + } + else + Sys_Printf( "Generating tangentspace deluxemaps\n" ); + i++; + } + else if( !strcmp( argv[ i ], "-nodeluxe" ) || !strcmp( argv[ i ], "-nodeluxemap" ) ) + { + deluxemap = qfalse; + Sys_Printf( "Disabling generating of deluxemaps for average light direction\n" ); + } else if( !strcmp( argv[ i ], "-external" ) ) { externalLightmaps = qtrue; @@ -2151,6 +2305,12 @@ i++; Sys_Printf( "Default lightmap sample size set to %dx%d units\n", sampleSize, sampleSize ); } + else if( !strcmp( argv[ i ], "-samplescale" ) ) + { + sampleScale = atoi( argv[ i + 1 ] ); + i++; + Sys_Printf( "Lightmaps sample scale set to %d\n", sampleScale); + } else if( !strcmp( argv[ i ], "-novertex" ) ) { noVertexLighting = qtrue; @@ -2186,11 +2346,36 @@ noStyles = qtrue; Sys_Printf( "Disabling lightstyles\n" ); } + else if( !strcmp( argv[ i ], "-style" ) || !strcmp( argv[ i ], "-styles" ) ) + { + noStyles = qfalse; + Sys_Printf( "Enabling lightstyles\n" ); + } + else if( !strcmp( argv[ i ], "-keeplights" )) + { + keepLights = qtrue; + Sys_Printf( "Leaving light entities on map after compile\n" ); + } else if( !strcmp( argv[ i ], "-cpma" ) ) { cpmaHack = qtrue; Sys_Printf( "Enabling Challenge Pro Mode Asstacular Vertex Lighting Mode (tm)\n" ); } + else if( !strcmp( argv[ i ], "-floodlight" ) ) + { + floodlighty = qtrue; + Sys_Printf( "FloodLighting enabled\n" ); + } + else if( !strcmp( argv[ i ], "-debugnormals" ) ) + { + debugnormals = qtrue; + Sys_Printf( "DebugNormals enabled\n" ); + } + else if( !strcmp( argv[ i ], "-lowquality" ) ) + { + floodlight_lowquality = qtrue; + Sys_Printf( "Low Quality FloodLighting enabled\n" ); + } /* r7: dirtmapping */ else if( !strcmp( argv[ i ], "-dirty" ) ) @@ -2212,6 +2397,7 @@ Sys_Printf( "Enabling randomized dirtmapping\n" ); else Sys_Printf( "Enabling ordered dir mapping\n" ); + i++; } else if( !strcmp( argv[ i ], "-dirtdepth" ) ) { @@ -2219,6 +2405,7 @@ if( dirtDepth <= 0.0f ) dirtDepth = 128.0f; Sys_Printf( "Dirtmapping depth set to %.1f\n", dirtDepth ); + i++; } else if( !strcmp( argv[ i ], "-dirtscale" ) ) { @@ -2226,6 +2413,7 @@ if( dirtScale <= 0.0f ) dirtScale = 1.0f; Sys_Printf( "Dirtmapping scale set to %.1f\n", dirtScale ); + i++; } else if( !strcmp( argv[ i ], "-dirtgain" ) ) { @@ -2233,6 +2421,7 @@ if( dirtGain <= 0.0f ) dirtGain = 1.0f; Sys_Printf( "Dirtmapping gain set to %.1f\n", dirtGain ); + i++; } /* unhandled args */ @@ -2279,6 +2468,7 @@ /* ydnar: set up optimization */ SetupBrushes(); SetupDirt(); + SetupFloodLight(); SetupSurfaceLightmaps(); /* initialize the surface facet tracing */ Index: light_bounce.c =================================================================== --- light_bounce.c (revision 158) +++ light_bounce.c (working copy) @@ -510,7 +510,7 @@ break; case MST_TRIANGLE_SOUP: - numTriangleDiffuseLights; + numTriangleDiffuseLights++; break; case MST_PATCH: Index: light_trace.c =================================================================== --- light_trace.c (revision 158) +++ light_trace.c (working copy) @@ -56,7 +56,7 @@ #define GROW_TRACE_NODES 16384 //% 16384 #define GROW_NODE_ITEMS 16 //% 256 -#define MAX_TW_VERTS 12 +#define MAX_TW_VERTS 24 // vortex: increased from 12 to 24 for ability co compile some insane maps with large curve count #define TRACE_ON_EPSILON 0.1f Index: light_ydnar.c =================================================================== --- light_ydnar.c (revision 158) +++ light_ydnar.c (working copy) @@ -49,6 +49,7 @@ int i; float max, gamma; vec3_t sample; + float inv, dif; /* ydnar: scaling necessary for simulating r_overbrightBits on external lightmaps */ @@ -72,16 +73,51 @@ /* gamma */ sample[ i ] = pow( sample[ i ] / 255.0f, gamma ) * 255.0f; } + + if (lightmapExposure == 1) + { + /* clamp with color normalization */ + max = sample[ 0 ]; + if( sample[ 1 ] > max ) + max = sample[ 1 ]; + if( sample[ 2 ] > max ) + max = sample[ 2 ]; + if( max > 255.0f ) + VectorScale( sample, (255.0f / max), sample ); + } + else + { + if (lightmapExposure==0) + { + lightmapExposure=1.0f; + } + inv=1.f/lightmapExposure; + //Exposure + + max = sample[ 0 ]; + if( sample[ 1 ] > max ) + max = sample[ 1 ]; + if( sample[ 2 ] > max ) + max = sample[ 2 ]; + + dif = (1- exp(-max * inv) ) * 255; + + if (max >0) + { + dif = dif / max; + } + else + { + dif = 0; + } + + for (i=0;i<3;i++) + { + sample[i]*=dif; + } + } + - /* clamp with color normalization */ - max = sample[ 0 ]; - if( sample[ 1 ] > max ) - max = sample[ 1 ]; - if( sample[ 2 ] > max ) - max = sample[ 2 ]; - if( max > 255.0f ) - VectorScale( sample, (255.0f / max), sample ); - /* compensate for ingame overbrighting/bitshifting */ VectorScale( sample, (1.0f / lightmapCompensate), sample ); @@ -384,7 +420,7 @@ #define NUDGE 0.5f #define BOGUS_NUDGE -99999.0f -static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv, vec4_t plane, float pass, vec3_t stv[ 3 ], vec3_t ttv[ 3 ] ) +static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv, vec4_t plane, float pass, vec3_t stv[ 3 ], vec3_t ttv[ 3 ], vec3_t worldverts[ 3 ] ) { int i, x, y, numClusters, *clusters, pointCluster, *cluster; float *luxel, *origin, *normal, d, lightmapSampleOffset; @@ -392,6 +428,12 @@ vec3_t pNormal; vec3_t vecs[ 3 ]; vec3_t nudged; + vec3_t cverts[ 3 ]; + vec3_t temp; + vec4_t sideplane, hostplane; + vec3_t origintwo; + int j, next; + float e; float *nudge; static float nudges[][ 2 ] = { @@ -485,6 +527,51 @@ /* non axial lightmap projection (explicit xyz) */ else VectorCopy( dv->xyz, origin ); + + ////////////////////// + //27's test to make sure samples stay within the triangle boundaries + //1) Test the sample origin to see if it lays on the wrong side of any edge (x/y) + //2) if it does, nudge it onto the correct side. + + if (worldverts!=NULL) + { + for (j=0;j<3;j++) + { + VectorCopy(worldverts[j],cverts[j]); + } + PlaneFromPoints(hostplane,cverts[0],cverts[1],cverts[2]); + + for (j=0;j<3;j++) + { + for (i=0;i<3;i++) + { + //build plane using 2 edges and a normal + next=(i+1)%3; + + VectorCopy(cverts[next],temp); + VectorAdd(temp,hostplane,temp); + PlaneFromPoints(sideplane,cverts[i],cverts[ next ], temp); + + //planetest sample point + e=DotProduct(origin,sideplane); + e=e-sideplane[3]; + if (e>0) + { + //we're bad. + //VectorClear(origin); + //Move the sample point back inside triangle bounds + origin[0]-=sideplane[0]*(e+1); + origin[1]-=sideplane[1]*(e+1); + origin[2]-=sideplane[2]*(e+1); +#ifdef DEBUG_27_1 + VectorClear(origin); +#endif + } + } + } + } + + //////////////////////// /* planar surfaces have precalculated lightmap vectors for nudging */ if( lm->plane != NULL ) @@ -516,8 +603,13 @@ else origin[ lm->axisNum ] += lightmapSampleOffset; + VectorCopy(origin,origintwo); + origintwo[0]+=vecs[2][0]; + origintwo[1]+=vecs[2][1]; + origintwo[2]+=vecs[2][2]; + /* get cluster */ - pointCluster = ClusterForPointExtFilter( origin, LUXEL_EPSILON, numClusters, clusters ); + pointCluster = ClusterForPointExtFilter( origintwo, LUXEL_EPSILON, numClusters, clusters ); /* another retarded hack, storing nudge count in luxel[ 1 ] */ luxel[ 1 ] = 0.0f; @@ -533,14 +625,14 @@ for( i = 0; i < 3; i++ ) { /* set nudged point*/ - nudged[ i ] = origin[ i ] + (nudge[ 0 ] * vecs[ 0 ][ i ]) + (nudge[ 1 ] * vecs[ 1 ][ i ]); + nudged[ i ] = origintwo[ i ] + (nudge[ 0 ] * vecs[ 0 ][ i ]) + (nudge[ 1 ] * vecs[ 1 ][ i ]); } nudge += 2; /* get pvs cluster */ pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); //% + 0.625 ); - if( pointCluster >= 0 ) - VectorCopy( nudged, origin ); + //if( pointCluster >= 0 ) + // VectorCopy( nudged, origin ); luxel[ 1 ] += 1.0f; } } @@ -550,8 +642,8 @@ { VectorMA( dv->xyz, lightmapSampleOffset, dv->normal, nudged ); pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); - if( pointCluster >= 0 ) - VectorCopy( nudged, origin ); + //if( pointCluster >= 0 ) + // VectorCopy( nudged, origin ); luxel[ 1 ] += 1.0f; } @@ -597,7 +689,7 @@ than the distance between two luxels (thanks jc :) */ -static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], vec4_t plane, vec3_t stv[ 3 ], vec3_t ttv[ 3 ] ) +static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], vec4_t plane, vec3_t stv[ 3 ], vec3_t ttv[ 3 ], vec3_t worldverts[ 3 ] ) { bspDrawVert_t mid, *dv2[ 3 ]; int max; @@ -645,7 +737,7 @@ /* split the longest edge and map it */ LerpDrawVert( dv[ max ], dv[ (max + 1) % 3 ], &mid ); - MapSingleLuxel( lm, info, &mid, plane, 1, stv, ttv ); + MapSingleLuxel( lm, info, &mid, plane, 1, stv, ttv, worldverts ); /* push the point up a little bit to account for fp creep (fixme: revisit this) */ //% VectorMA( mid.xyz, 2.0f, mid.normal, mid.xyz ); @@ -653,12 +745,12 @@ /* recurse to first triangle */ VectorCopy( dv, dv2 ); dv2[ max ] = ∣ - MapTriangle_r( lm, info, dv2, plane, stv, ttv ); + MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts ); /* recurse to second triangle */ VectorCopy( dv, dv2 ); dv2[ (max + 1) % 3 ] = ∣ - MapTriangle_r( lm, info, dv2, plane, stv, ttv ); + MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts ); } @@ -674,8 +766,8 @@ int i; vec4_t plane; vec3_t *stv, *ttv, stvStatic[ 3 ], ttvStatic[ 3 ]; + vec3_t worldverts[ 3 ]; - /* get plane if possible */ if( lm->plane != NULL ) { @@ -699,16 +791,20 @@ ttv = NULL; } + VectorCopy( dv[ 0 ]->xyz, worldverts[ 0 ] ); + VectorCopy( dv[ 1 ]->xyz, worldverts[ 1 ] ); + VectorCopy( dv[ 2 ]->xyz, worldverts[ 2 ] ); + /* map the vertexes */ - MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv ); - MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv ); - MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv ); + MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv, worldverts ); + MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv, worldverts ); + MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv, worldverts ); /* 2002-11-20: prefer axial triangle edges */ if( mapNonAxial ) { /* subdivide the triangle */ - MapTriangle_r( lm, info, dv, plane, stv, ttv ); + MapTriangle_r( lm, info, dv, plane, stv, ttv, worldverts ); return qtrue; } @@ -730,7 +826,7 @@ dv2[ 2 ] = dv[ (i + 1) % 3 ]; /* map the degenerate triangle */ - MapTriangle_r( lm, info, dv2, plane, stv, ttv ); + MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts ); } } @@ -792,8 +888,8 @@ LerpDrawVert( dv[ max + 2 ], dv[ (max + 3) % 4 ], &mid[ 1 ] ); /* map the vertexes */ - MapSingleLuxel( lm, info, &mid[ 0 ], plane, 1, stv, ttv ); - MapSingleLuxel( lm, info, &mid[ 1 ], plane, 1, stv, ttv ); + MapSingleLuxel( lm, info, &mid[ 0 ], plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, &mid[ 1 ], plane, 1, stv, ttv, NULL ); /* 0 and 2 */ if( max == 0 ) @@ -848,7 +944,6 @@ vec4_t plane; vec3_t *stv, *ttv, stvStatic[ 4 ], ttvStatic[ 4 ]; - /* get plane if possible */ if( lm->plane != NULL ) { @@ -878,18 +973,16 @@ } /* map the vertexes */ - MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv ); - MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv ); - MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv ); - MapSingleLuxel( lm, info, dv[ 3 ], plane, 1, stv, ttv ); + MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 3 ], plane, 1, stv, ttv, NULL ); /* subdivide the quad */ MapQuad_r( lm, info, dv, plane, stv, ttv ); return qtrue; } - - /* MapRawLightmap() maps the locations, normals, and pvs clusters for a raw lightmap @@ -941,7 +1034,7 @@ num = lightSurfaces[ lm->firstLightSurface + n ]; ds = &bspDrawSurfaces[ num ]; info = &surfaceInfos[ num ]; - + /* bail if no lightmap to calculate */ if( info->lm != lm ) { @@ -1173,7 +1266,7 @@ continue; /* map the fake vert */ - MapSingleLuxel( lm, NULL, &fake, lm->plane, pass, NULL, NULL ); + MapSingleLuxel( lm, NULL, &fake, lm->plane, pass, NULL, NULL, NULL ); } } } @@ -1596,7 +1689,6 @@ VectorSubtract( origin2, origin, originVecs[ 0 ] ); //% VectorSubtract( normal2, normal, normalVecs[ 0 ] ); - /* calulate y vector */ if( (y < (lm->sh - 1) && bx >= 0.0f) || (y == 0 && bx <= 0.0f) ) { @@ -1660,7 +1752,6 @@ float biasDirs[ 4 ][ 2 ] = { { -1.0f, -1.0f }, { 1.0f, -1.0f }, { -1.0f, 1.0f }, { 1.0f, 1.0f } }; vec3_t color, total; - /* limit check */ if( lightLuxel[ 3 ] >= lightSamples ) return; @@ -1693,7 +1784,6 @@ VectorCopy( normal[ b ], trace->normal ); /* sample light */ - LightContributionToSample( trace ); /* add to totals (fixme: make contrast function) */ @@ -1768,7 +1858,6 @@ trace_t trace; float stackLightLuxels[ STACK_LL_SIZE ]; - /* bail if this number exceeds the number of raw lightmaps */ if( rawLightmapNum >= numRawLightmaps ) return; @@ -1904,7 +1993,7 @@ else { VectorCopy( ambientColor, luxel ); - if( deluxemap ) + if( deluxemap) VectorScale( normal, 0.00390625f, deluxel ); luxel[ 3 ] = 1.0f; } @@ -1963,28 +2052,39 @@ deluxel = SUPER_DELUXEL( x, y ); origin = SUPER_ORIGIN( x, y ); normal = SUPER_NORMAL( x, y ); - - /* set contribution count */ - lightLuxel[ 3 ] = 1.0f; - - /* setup trace */ - trace.cluster = *cluster; - VectorCopy( origin, trace.origin ); - VectorCopy( normal, trace.normal ); - - /* get light for this sample */ - LightContributionToSample( &trace ); - VectorCopy( trace.color, lightLuxel ); - - /* add to count */ - if( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] ) + + ////////// 27's temp hack for testing edge clipping //// + if( origin[0]==0 && origin[1]==0 && origin[2]==0 ) + { + lightLuxel[ 1 ] = 255; + lightLuxel[ 3 ] = 1.0f; totalLighted++; + } + else + { + /* set contribution count */ + lightLuxel[ 3 ] = 1.0f; + + /* setup trace */ + trace.cluster = *cluster; + VectorCopy( origin, trace.origin ); + VectorCopy( normal, trace.normal ); + + /* get light for this sample */ + LightContributionToSample( &trace ); + VectorCopy( trace.color, lightLuxel ); + + /* add to count */ + if( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] ) + totalLighted++; + } /* add to light direction map (fixme: use luxel normal as starting point for deluxel?) */ if( deluxemap ) { + /* vortex: use noShadow color */ /* color to grayscale (photoshop rgb weighting) */ - brightness = trace.color[ 0 ] * 0.3f + trace.color[ 1 ] * 0.59f + trace.color[ 2 ] * 0.11f; + brightness = trace.colorNoShadow[ 0 ] * 0.3f + trace.colorNoShadow[ 1 ] * 0.59f + trace.colorNoShadow[ 2 ] * 0.11f; brightness *= (1.0 / 255.0); VectorScale( trace.direction, brightness, trace.direction ); VectorAdd( deluxel, trace.direction, deluxel ); @@ -2222,6 +2322,38 @@ /* free light list */ FreeTraceLights( &trace ); + /* floodlight pass */ + FloodlightIlluminateLightmap(lm); + + if (debugnormals) + { + for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* early out */ + if( lm->superLuxels[ lightmapNum ] == NULL ) + continue; + + for( y = 0; y < lm->sh; y++ ) + { + for( x = 0; x < lm->sw; x++ ) + { + /* get cluster */ + cluster = SUPER_CLUSTER( x, y ); + //% if( *cluster < 0 ) + //% continue; + + /* get particulars */ + luxel = SUPER_LUXEL( lightmapNum, x, y ); + normal = SUPER_NORMAL ( x, y ); + + luxel[0]=(normal[0]*127)+127; + luxel[1]=(normal[1]*127)+127; + luxel[2]=(normal[2]*127)+127; + } + } + } + } + /* ----------------------------------------------------------------- dirt pass ----------------------------------------------------------------- */ @@ -2263,7 +2395,7 @@ /* ----------------------------------------------------------------- filter pass ----------------------------------------------------------------- */ - + /* walk lightmaps */ for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { @@ -3112,7 +3244,7 @@ int i, x, y, z, x1, y1, z1; light_t *light, *light2, **owner; bspLeaf_t *leaf; - vec3_t origin, dir, mins, maxs, nullVector = { 0, 0, 0 }; + vec3_t origin, dir, mins, maxs; float radius, intensity; light_t *buckets[ 256 ]; @@ -3587,7 +3719,430 @@ CreateTraceLightsForBounds( mins, maxs, normal, info->numSurfaceClusters, &surfaceClusters[ info->firstSurfaceCluster ], LIGHT_SURFACES, trace ); } +///////////////////////////////////////////////////////////// +#define FLOODLIGHT_CONE_ANGLE 88 /* degrees */ +#define FLOODLIGHT_NUM_ANGLE_STEPS 16 +#define FLOODLIGHT_NUM_ELEVATION_STEPS 4 +#define FLOODLIGHT_NUM_VECTORS (FLOODLIGHT_NUM_ANGLE_STEPS * FLOODLIGHT_NUM_ELEVATION_STEPS) +static vec3_t floodVectors[ FLOODLIGHT_NUM_VECTORS ]; +static int numFloodVectors = 0; +void SetupFloodLight( void ) +{ + int i, j; + float angle, elevation, angleStep, elevationStep; + const char *value; + double v1,v2,v3,v4,v5; + + /* note it */ + Sys_FPrintf( SYS_VRB, "--- SetupFloodLight ---\n" ); + + /* calculate angular steps */ + angleStep = DEG2RAD( 360.0f / FLOODLIGHT_NUM_ANGLE_STEPS ); + elevationStep = DEG2RAD( FLOODLIGHT_CONE_ANGLE / FLOODLIGHT_NUM_ELEVATION_STEPS ); + + /* iterate angle */ + angle = 0.0f; + for( i = 0, angle = 0.0f; i < FLOODLIGHT_NUM_ANGLE_STEPS; i++, angle += angleStep ) + { + /* iterate elevation */ + for( j = 0, elevation = elevationStep * 0.5f; j < FLOODLIGHT_NUM_ELEVATION_STEPS; j++, elevation += elevationStep ) + { + floodVectors[ numFloodVectors ][ 0 ] = sin( elevation ) * cos( angle ); + floodVectors[ numFloodVectors ][ 1 ] = sin( elevation ) * sin( angle ); + floodVectors[ numFloodVectors ][ 2 ] = cos( elevation ); + numFloodVectors++; + } + } + + /* emit some statistics */ + Sys_FPrintf( SYS_VRB, "%9d numFloodVectors\n", numFloodVectors ); + /* floodlight */ + value = ValueForKey( &entities[ 0 ], "_floodlight" ); + + if( value[ 0 ] != '\0' ) + { + v1=v2=v3=0; + v4=floodlightDistance; + v5=floodlightIntensity; + + sscanf( value, "%lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5); + + floodlightRGB[0]=v1; + floodlightRGB[1]=v2; + floodlightRGB[2]=v3; + + if (VectorLength(floodlightRGB)==0) + { + VectorSet(floodlightRGB,240,240,255); + } + + if (v4<1) v4=1024; + if (v5<1) v5=128; + + floodlightDistance = v4; + floodlightIntensity = v5; + + floodlighty = qtrue; + Sys_Printf( "FloodLighting enabled via worldspawn _floodlight key.\n" ); + } + else + { + VectorSet(floodlightRGB,240,240,255); + //floodlighty = qtrue; + //Sys_Printf( "FloodLighting enabled via worldspawn _floodlight key.\n" ); + } + VectorNormalize(floodlightRGB,floodlightRGB); +} + +/* +FloodLightForSample() +calculates floodlight value for a given sample +once again, kudos to the dirtmapping coder +*/ + +float FloodLightForSample( trace_t *trace , float floodLightDistance, qboolean floodLightLowQuality) +{ + int i; + float d; + float contribution; + int sub = 0; + float gatherLight, outLight; + vec3_t normal, worldUp, myUp, myRt, direction, displacement; + float dd; + int vecs = 0; + + gatherLight=0; + /* dummy check */ + //if( !dirty ) + // return 1.0f; + if( trace == NULL || trace->cluster < 0 ) + return 0.0f; + + + /* setup */ + dd = floodLightDistance; + VectorCopy( trace->normal, normal ); + + /* check if the normal is aligned to the world-up */ + if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f ) + { + if( normal[ 2 ] == 1.0f ) + { + VectorSet( myRt, 1.0f, 0.0f, 0.0f ); + VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + } + else if( normal[ 2 ] == -1.0f ) + { + VectorSet( myRt, -1.0f, 0.0f, 0.0f ); + VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + } + } + else + { + VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); + CrossProduct( normal, worldUp, myRt ); + VectorNormalize( myRt, myRt ); + CrossProduct( myRt, normal, myUp ); + VectorNormalize( myUp, myUp ); + } + + /* vortex: optimise floodLightLowQuality a bit */ + if ( floodLightLowQuality == qtrue ) + { + /* iterate through ordered vectors */ + for( i = 0; i < numFloodVectors; i++ ) + if (rand()%10 != 0 ) continue; + } + else + { + /* iterate through ordered vectors */ + for( i = 0; i < numFloodVectors; i++ ) + { + vecs++; + + /* transform vector into tangent space */ + direction[ 0 ] = myRt[ 0 ] * floodVectors[ i ][ 0 ] + myUp[ 0 ] * floodVectors[ i ][ 1 ] + normal[ 0 ] * floodVectors[ i ][ 2 ]; + direction[ 1 ] = myRt[ 1 ] * floodVectors[ i ][ 0 ] + myUp[ 1 ] * floodVectors[ i ][ 1 ] + normal[ 1 ] * floodVectors[ i ][ 2 ]; + direction[ 2 ] = myRt[ 2 ] * floodVectors[ i ][ 0 ] + myUp[ 2 ] * floodVectors[ i ][ 1 ] + normal[ 2 ] * floodVectors[ i ][ 2 ]; + + /* set endpoint */ + VectorMA( trace->origin, dd, direction, trace->end ); + + //VectorMA( trace->origin, 1, direction, trace->origin ); + + SetupTrace( trace ); + /* trace */ + TraceLine( trace ); + contribution=1; + + if (trace->compileFlags & C_SKY ) + { + contribution=1.0f; + } + else if ( trace->opaque ) + { + VectorSubtract( trace->hit, trace->origin, displacement ); + d=VectorLength( displacement ); + + // d=trace->distance; + //if (d>256) gatherDirt+=1; + contribution=d/dd; + if (contribution>1) contribution=1.0f; + + //gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); + } + + gatherLight+=contribution; + } + } + + /* early out */ + if( gatherLight <= 0.0f ) + return 0.0f; + + sub=vecs; + + if (sub<1) sub=1; + gatherLight/=(sub); + + outLight=gatherLight; + if( outLight > 1.0f ) + outLight = 1.0f; + + /* return to sender */ + return outLight; +} + +/* +FloodLightRawLightmap +lighttracer style ambient occlusion light hack. +Kudos to the dirtmapping author for most of this source. +VorteX: modified to floodlight up custom surfaces (q3map_floodLight) +VorteX: fixed problems with deluxemapping +*/ + +// floodlight pass on a lightmap +void FloodLightRawLightmapPass( rawLightmap_t *lm , vec3_t lmFloodLightRGB, float lmFloodLightIntensity, float lmFloodLightDistance, qboolean lmFloodLightLowQuality, float floodlightDirectionScale) +{ + int i, x, y, *cluster; + float *origin, *normal, *floodlight, floodLightAmount; + surfaceInfo_t *info; + trace_t trace; + // int sx, sy; + // float samples, average, *floodlight2; + + memset(&trace,0,sizeof(trace_t)); + + /* setup trace */ + trace.testOcclusion = qtrue; + trace.forceSunlight = qfalse; + trace.twoSided = qtrue; + trace.recvShadows = lm->recvShadows; + trace.numSurfaces = lm->numLightSurfaces; + trace.surfaces = &lightSurfaces[ lm->firstLightSurface ]; + trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; + trace.testAll = qfalse; + trace.distance = 1024; + + /* twosided lighting (may or may not be a good idea for lightmapped stuff) */ + //trace.twoSided = qfalse; + for( i = 0; i < trace.numSurfaces; i++ ) + { + /* get surface */ + info = &surfaceInfos[ trace.surfaces[ i ] ]; + + /* check twosidedness */ + if( info->si->twoSided ) + { + trace.twoSided = qtrue; + break; + } + } + + /* gather floodlight */ + for( y = 0; y < lm->sh; y++ ) + { + for( x = 0; x < lm->sw; x++ ) + { + /* get luxel */ + cluster = SUPER_CLUSTER( x, y ); + origin = SUPER_ORIGIN( x, y ); + normal = SUPER_NORMAL( x, y ); + floodlight = SUPER_FLOODLIGHT( x, y ); + + /* set default dirt */ + *floodlight = 0.0f; + + /* only look at mapped luxels */ + if( *cluster < 0 ) + continue; + + /* copy to trace */ + trace.cluster = *cluster; + VectorCopy( origin, trace.origin ); + VectorCopy( normal, trace.normal ); + + /* get floodlight */ + floodLightAmount = FloodLightForSample( &trace , lmFloodLightDistance, lmFloodLightLowQuality)*lmFloodLightIntensity; + + /* add floodlight */ + floodlight[0] += lmFloodLightRGB[0]*floodLightAmount; + floodlight[1] += lmFloodLightRGB[1]*floodLightAmount; + floodlight[2] += lmFloodLightRGB[2]*floodLightAmount; + floodlight[3] += floodlightDirectionScale; + } + } + + /* testing no filtering */ + return; + +#if 0 + + /* filter "dirt" */ + for( y = 0; y < lm->sh; y++ ) + { + for( x = 0; x < lm->sw; x++ ) + { + /* get luxel */ + cluster = SUPER_CLUSTER( x, y ); + floodlight = SUPER_FLOODLIGHT(x, y ); + + /* filter dirt by adjacency to unmapped luxels */ + average = *floodlight; + samples = 1.0f; + for( sy = (y - 1); sy <= (y + 1); sy++ ) + { + if( sy < 0 || sy >= lm->sh ) + continue; + + for( sx = (x - 1); sx <= (x + 1); sx++ ) + { + if( sx < 0 || sx >= lm->sw || (sx == x && sy == y) ) + continue; + + /* get neighboring luxel */ + cluster = SUPER_CLUSTER( sx, sy ); + floodlight2 = SUPER_FLOODLIGHT( sx, sy ); + if( *cluster < 0 || *floodlight2 <= 0.0f ) + continue; + + /* add it */ + average += *floodlight2; + samples += 1.0f; + } + + /* bail */ + if( samples <= 0.0f ) + break; + } + + /* bail */ + if( samples <= 0.0f ) + continue; + + /* scale dirt */ + *floodlight = average / samples; + } + } +#endif +} + +void FloodLightRawLightmap( int rawLightmapNum ) +{ + rawLightmap_t *lm; + + /* bail if this number exceeds the number of raw lightmaps */ + if( rawLightmapNum >= numRawLightmaps ) + return; + /* get lightmap */ + lm = &rawLightmaps[ rawLightmapNum ]; + + /* global pass */ + if (floodlighty && floodlightIntensity) + FloodLightRawLightmapPass(lm, floodlightRGB, floodlightIntensity, floodlightDistance, floodlight_lowquality, 0); + + /* custom pass */ + if (lm->floodlightIntensity) + { + FloodLightRawLightmapPass(lm, lm->floodlightRGB, lm->floodlightIntensity, lm->floodlightDistance, qfalse, lm->floodlightDirectionScale); + numSurfacesFloodlighten += 1; + } +} + +void FloodlightRawLightmaps() +{ + Sys_Printf( "--- FloodlightRawLightmap ---\n" ); + numSurfacesFloodlighten = 0; + RunThreadsOnIndividual( numRawLightmaps, qtrue, FloodLightRawLightmap ); + Sys_Printf( "%9d custom lightmaps floodlighted\n", numSurfacesFloodlighten ); +} + +/* +FloodLightIlluminate() +illuminate floodlight into lightmap luxels +*/ + +void FloodlightIlluminateLightmap( rawLightmap_t *lm ) +{ + float *luxel, *floodlight, *deluxel, *normal; + int *cluster; + float brightness; + vec3_t lightvector; + int x, y, lightmapNum; + + /* walk lightmaps */ + for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* early out */ + if( lm->superLuxels[ lightmapNum ] == NULL ) + continue; + + /* apply floodlight to each luxel */ + for( y = 0; y < lm->sh; y++ ) + { + for( x = 0; x < lm->sw; x++ ) + { + /* get floodlight */ + floodlight = SUPER_FLOODLIGHT( x, y ); + if (!floodlight[0] && !floodlight[1] && !floodlight[2]) + continue; + + /* get cluster */ + cluster = SUPER_CLUSTER( x, y ); + + /* only process mapped luxels */ + if( *cluster < 0 ) + continue; + + /* get particulars */ + luxel = SUPER_LUXEL( lightmapNum, x, y ); + deluxel = SUPER_DELUXEL( x, y ); + + /* add to lightmap */ + luxel[0]+=floodlight[0]; + luxel[1]+=floodlight[1]; + luxel[2]+=floodlight[2]; + + if (luxel[3]==0) luxel[3]=1; + + /* add to deluxemap */ + if (deluxemap && floodlight[3] > 0) + { + normal = SUPER_NORMAL( x, y ); + brightness = floodlight[ 0 ] * 0.3f + floodlight[ 1 ] * 0.59f + floodlight[ 2 ] * 0.11f; + brightness *= ( 1.0f / 255.0f ) * floodlight[3]; + VectorScale( normal, brightness, lightvector ); + VectorAdd( deluxel, lightvector, deluxel ); + } + } + } + } +} + + + + Index: lightmaps_ydnar.c =================================================================== --- lightmaps_ydnar.c (revision 158) +++ lightmaps_ydnar.c (working copy) @@ -414,6 +414,12 @@ lm->superNormals = safe_malloc( size ); memset( lm->superNormals, 0, size ); + /* allocate floodlight map storage */ + size = lm->sw * lm->sh * SUPER_FLOODLIGHT_SIZE * sizeof( float ); + if( lm->superFloodLight == NULL ) + lm->superFloodLight = safe_malloc( size ); + memset( lm->superFloodLight, 0, size ); + /* allocate cluster map storage */ size = lm->sw * lm->sh * sizeof( int ); if( lm->superClusters == NULL ) @@ -1087,17 +1093,25 @@ /* allocate a new raw lightmap */ lm = &rawLightmaps[ numRawLightmaps ]; numRawLightmaps++; - + /* set it up */ lm->splotchFix = info->si->splotchFix; lm->firstLightSurface = numLightSurfaces; lm->numLightSurfaces = 0; - lm->sampleSize = info->sampleSize; - lm->actualSampleSize = info->sampleSize; + /* vortex: multiply lightmap sample size by -samplescale */ + if (sampleScale > 0) + lm->sampleSize = info->sampleSize*sampleScale; + else + lm->sampleSize = info->sampleSize; + lm->actualSampleSize = lm->sampleSize; lm->entityNum = info->entityNum; lm->recvShadows = info->recvShadows; lm->brightness = info->si->lmBrightness; lm->filterRadius = info->si->lmFilterRadius; + VectorCopy(info->si->floodlightRGB, lm->floodlightRGB); + lm->floodlightDistance = info->si->floodlightDistance; + lm->floodlightIntensity = info->si->floodlightIntensity; + lm->floodlightDirectionScale = info->si->floodlightDirectionScale; VectorCopy( info->axis, lm->axis ); lm->plane = info->plane; VectorCopy( info->mins, lm->mins ); @@ -2254,7 +2268,6 @@ char *rgbGenValues[ 256 ]; char *alphaGenValues[ 256 ]; - /* note it */ Sys_Printf( "--- StoreSurfaceLightmaps ---\n"); @@ -2269,7 +2282,7 @@ ----------------------------------------------------------------- */ /* note it */ - Sys_FPrintf( SYS_VRB, "Subsampling..." ); + Sys_Printf( "Subsampling..." ); /* walk the list of raw lightmaps */ numUsed = 0; @@ -2437,11 +2450,11 @@ /* get luxels */ luxel = SUPER_LUXEL( lightmapNum, x, y ); deluxel = SUPER_DELUXEL( x, y ); - + /* copy light direction */ if( deluxemap && lightmapNum == 0 ) VectorCopy( deluxel, dirSample ); - + /* is this a valid sample? */ if( luxel[ 3 ] > 0.0f ) { @@ -2521,7 +2534,7 @@ /* store the sample in the bsp luxels */ bspLuxel = BSP_LUXEL( lightmapNum, x, y ); bspDeluxel = BSP_DELUXEL( x, y ); - + VectorAdd( bspLuxel, sample, bspLuxel ); if( deluxemap && lightmapNum == 0 ) VectorAdd( bspDeluxel, dirSample, bspDeluxel ); @@ -2562,7 +2575,7 @@ } } } - + /* wrap bsp luxels if necessary */ if( lm->wrap[ 0 ] ) { @@ -2604,15 +2617,144 @@ } } } - + /* ----------------------------------------------------------------- + convert modelspace deluxemaps to tangentspace + ----------------------------------------------------------------- */ + /* note it */ + if( !bouncing ) + { + if( deluxemap && deluxemode == 1) + { + vec3_t worldUp, myNormal, myTangent, myBinormal; + float dist; + + Sys_Printf( "converting..." ); + + for( i = 0; i < numRawLightmaps; i++ ) + { + /* get lightmap */ + lm = &rawLightmaps[ i ]; + + /* walk lightmap samples */ + for( y = 0; y < lm->sh; y++ ) + { + for( x = 0; x < lm->sw; x++ ) + { + /* get normal and deluxel */ + normal = SUPER_NORMAL(x, y); + cluster = SUPER_CLUSTER(x, y); + bspDeluxel = BSP_DELUXEL( x, y ); + deluxel = SUPER_DELUXEL( x, y ); + + /* get normal */ + VectorSet( myNormal, normal[0], normal[1], normal[2] ); + + /* get tangent vectors */ + if( myNormal[ 0 ] == 0.0f && myNormal[ 1 ] == 0.0f ) + { + if( myNormal[ 2 ] == 1.0f ) + { + VectorSet( myTangent, 1.0f, 0.0f, 0.0f ); + VectorSet( myBinormal, 0.0f, 1.0f, 0.0f ); + } + else if( myNormal[ 2 ] == -1.0f ) + { + VectorSet( myTangent, -1.0f, 0.0f, 0.0f ); + VectorSet( myBinormal, 0.0f, 1.0f, 0.0f ); + } + } + else + { + VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); + CrossProduct( myNormal, worldUp, myTangent ); + VectorNormalize( myTangent, myTangent ); + CrossProduct( myTangent, myNormal, myBinormal ); + VectorNormalize( myBinormal, myBinormal ); + } + + /* project onto plane */ + dist = -DotProduct(myTangent, myNormal); + VectorMA(myTangent, dist, myNormal, myTangent); + dist = -DotProduct(myBinormal, myNormal); + VectorMA(myBinormal, dist, myNormal, myBinormal); + + /* renormalize */ + VectorNormalize( myTangent, myTangent ); + VectorNormalize( myBinormal, myBinormal ); + + /* convert modelspace deluxel to tangentspace */ + dirSample[0] = bspDeluxel[0]; + dirSample[1] = bspDeluxel[1]; + dirSample[2] = bspDeluxel[2]; + VectorNormalize(dirSample, dirSample); + + /* fix tangents to world matrix */ + if (myNormal[0] > 0 || myNormal[1] < 0 || myNormal[2] < 0) + VectorNegate(myTangent, myTangent); + + /* build tangentspace vectors */ + bspDeluxel[0] = DotProduct(dirSample, myTangent); + bspDeluxel[1] = DotProduct(dirSample, myBinormal); + bspDeluxel[2] = DotProduct(dirSample, myNormal); + } + } + } + } + } + + /* ----------------------------------------------------------------- + blend lightmaps + ----------------------------------------------------------------- */ + +#ifdef sdfsdfwq312323 + /* note it */ + Sys_Printf( "blending..." ); + + for( i = 0; i < numRawLightmaps; i++ ) + { + vec3_t myColor; + float myBrightness; + + /* get lightmap */ + lm = &rawLightmaps[ i ]; + + /* walk individual lightmaps */ + for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* early outs */ + if( lm->superLuxels[ lightmapNum ] == NULL ) + continue; + + /* walk lightmap samples */ + for( y = 0; y < lm->sh; y++ ) + { + for( x = 0; x < lm->sw; x++ ) + { + /* get luxel */ + bspLuxel = BSP_LUXEL( lightmapNum, x, y ); + + /* get color */ + VectorNormalize(bspLuxel, myColor); + myBrightness = VectorLength(bspLuxel); + myBrightness *= (1 / 127.0f); + myBrightness = myBrightness*myBrightness; + myBrightness *= 127.0f; + VectorScale(myColor, myBrightness, bspLuxel); + } + } + } + } +#endif + + /* ----------------------------------------------------------------- collapse non-unique lightmaps ----------------------------------------------------------------- */ if( noCollapse == qfalse && deluxemap == qfalse ) { /* note it */ - Sys_FPrintf( SYS_VRB, "collapsing..." ); + Sys_Printf( "collapsing..." ); /* set all twin refs to null */ for( i = 0; i < numRawLightmaps; i++ ) @@ -2674,13 +2816,13 @@ } } } - + /* ----------------------------------------------------------------- sort raw lightmaps by shader ----------------------------------------------------------------- */ /* note it */ - Sys_FPrintf( SYS_VRB, "sorting..." ); + Sys_Printf( "sorting..." ); /* allocate a new sorted list */ if( sortLightmaps == NULL ) @@ -2696,7 +2838,7 @@ ----------------------------------------------------------------- */ /* note it */ - Sys_FPrintf( SYS_VRB, "allocating..." ); + Sys_Printf( "allocating..." ); /* kill all existing output lightmaps */ if( outLightmaps != NULL ) @@ -2749,7 +2891,7 @@ ----------------------------------------------------------------- */ /* note it */ - Sys_FPrintf( SYS_VRB, "storing..." ); + Sys_Printf( "storing..." ); /* count the bsp lightmaps and allocate space */ if( bspLightBytes != NULL ) @@ -2817,7 +2959,7 @@ } if( numExtLightmaps > 0 ) - Sys_FPrintf( SYS_VRB, "\n" ); + Sys_Printf( SYS_VRB, "\n" ); /* delete unused external lightmaps */ for( i = numExtLightmaps; i; i++ ) @@ -2836,7 +2978,7 @@ ----------------------------------------------------------------- */ /* note it */ - Sys_FPrintf( SYS_VRB, "projecting..." ); + Sys_Printf( "projecting..." ); /* walk the list of surfaces */ for( i = 0; i < numBSPDrawSurfaces; i++ ) @@ -3108,7 +3250,7 @@ } /* finish */ - Sys_FPrintf( SYS_VRB, "done.\n" ); + Sys_Printf( "done.\n" ); /* calc num stored */ numStored = numBSPLightBytes / 3; Index: main.c =================================================================== --- main.c (revision 158) +++ main.c (working copy) @@ -604,7 +604,7 @@ /* set exit call */ atexit( ExitQ3Map ); - + /* read general options first */ for( i = 1; i < argc; i++ ) { @@ -680,6 +680,10 @@ /* ydnar: new path initialization */ InitPaths( &argc, argv ); + + /* set game options */ + if (!patchSubdivisions) + patchSubdivisions = game->patchSubdivisions; /* check if we have enough options left to attempt something */ if( argc < 2 ) Index: q3map2.h =================================================================== --- q3map2.h (revision 158) +++ q3map2.h (working copy) @@ -35,8 +35,8 @@ /* version */ -#define Q3MAP_VERSION "2.5.17" -#define Q3MAP_MOTD "Last one turns the lights off" +#define Q3MAP_VERSION "2.5.17 base : FS_20g base : R5" +#define Q3MAP_MOTD "Sorry, it doesn't match my furniture." @@ -235,6 +235,7 @@ #define LIGHT_FAST_TEMP 512 #define LIGHT_FAST_ACTUAL (LIGHT_FAST | LIGHT_FAST_TEMP) #define LIGHT_NEGATIVE 1024 +#define LIGHT_UNNORMALIZED 2048 /* vortex: do not normalize _color */ #define LIGHT_SUN_DEFAULT (LIGHT_ATTEN_ANGLE | LIGHT_GRID | LIGHT_SURFACES) #define LIGHT_AREA_DEFAULT (LIGHT_ATTEN_ANGLE | LIGHT_ATTEN_DISTANCE | LIGHT_GRID | LIGHT_SURFACES) /* q3a and wolf are the same */ @@ -267,6 +268,7 @@ #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)) @@ -279,9 +281,8 @@ #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)) - - /* ------------------------------------------------------------------------------- abstracted bsp file @@ -543,7 +544,16 @@ qboolean wolfLight; /* when true, lights work like wolf q3map */ int lightmapSize; /* bsp lightmap width/height */ float lightmapGamma; /* default lightmap gamma */ + float lightmapExposure; /* default lightmap exposure */ float lightmapCompensate; /* default lightmap compensate value */ + float gridScale; /* vortex: default lightgrid scale (affects both directional and ambient spectres) */ + float gridAmbientScale; /* vortex: default lightgrid ambient spectre scale */ + qboolean noStyles; /* use lightstyles hack or not */ + qboolean keepLights; /* keep light entities on bsp */ + int patchSubdivisions; /* default patch subdivisions tolerance */ + qboolean patchShadows; /* patch casting enabled */ + qboolean deluxeMap; /* compile deluxemaps */ + int deluxeMode; /* deluxemap mode (0 - modelspace, 1 - tangentspace with renormalization, 2 - tangentspace without renormalization) */ char *bspIdent; /* 4-letter bsp file prefix */ int bspVersion; /* bsp version to use */ qboolean lumpSwap; /* cod-style len/ofs order */ @@ -662,6 +672,7 @@ char *backShader; /* for surfaces that generate different front and back passes */ char *cloneShader; /* ydnar: for cloning of a surface */ char *remapShader; /* ydnar: remap a shader in final stage */ + char *deprecateShader; /* vortex: shader is deprecated and replaced by this on use */ surfaceModel_t *surfaceModel; /* ydnar: for distribution of models */ foliage_t *foliage; /* ydnar/splash damage: wolf et foliage */ @@ -737,7 +748,13 @@ vec3_t color; /* normalized color */ vec3_t averageColor; - byte lightStyle; + byte lightStyle; + + /* vortex: per-surface floodlight */ + float floodlightDirectionScale; + vec3_t floodlightRGB; + float floodlightIntensity; + float floodlightDistance; qb_t lmMergable; /* ydnar */ int lmCustomWidth, lmCustomHeight; /* ydnar */ @@ -1013,7 +1030,7 @@ int maxIterations; int patchWidth, patchHeight; vec3_t bounds[ 2 ]; - + /* ydnar/sd: for foliage */ int numFoliageInstances; @@ -1061,6 +1078,7 @@ int mapEntityNum, firstDrawSurf; int firstBrush, numBrushes; /* only valid during BSP compile */ epair_t *epairs; + qboolean forceNormalSmoothing; /* vortex: true if entity has _smoothnormals/_sn/_smooth key */ } entity_t; @@ -1296,7 +1314,8 @@ /* 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 */ + /* output */ vec3_t hit; int compileFlags; /* for determining surface compile flags traced through */ @@ -1367,6 +1386,13 @@ int numLightClusters, *lightClusters; int sampleSize, actualSampleSize, axisNum; + + /* vortex: per-surface floodlight */ + float floodlightDirectionScale; + vec3_t floodlightRGB; + float floodlightIntensity; + float floodlightDistance; + int entityNum; int recvShadows; vec3_t mins, maxs, axis, origin, *vecs; @@ -1389,9 +1415,9 @@ float *superOrigins; float *superNormals; int *superClusters; - float *superDeluxels; /* average light direction */ float *bspDeluxels; + float *superFloodLight; /* floodlight color */ } rawLightmap_t; @@ -1421,8 +1447,6 @@ } surfaceInfo_t; - - /* ------------------------------------------------------------------------------- prototypes @@ -1556,6 +1580,7 @@ void ParsePatch( qboolean onlyLights ); mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ); void PatchMapDrawSurfs( entity_t *e ); +void TriangulatePatchSurface( entity_t *e , mapDrawSurface_t *ds ); /* tjunction.c */ @@ -1610,6 +1635,8 @@ void AddEntitySurfaceModels( entity_t *e ); int AddSurfaceModels( mapDrawSurface_t *ds ); void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ); +void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ); +static void EmitTriangleSurface( mapDrawSurface_t *ds ); /* surface_fur.c */ @@ -1704,6 +1732,12 @@ float DirtForSample( trace_t *trace ); void DirtyRawLightmap( int num ); +void SetupFloodLight(); +void FloodlightRawLightmaps(); +void FloodlightIlluminateLightmap( rawLightmap_t *lm ); +float FloodLightForSample( trace_t *trace , float floodLightDistance, qboolean floodLightLowQuality); +void FloodLightRawLightmap( int num ); + void IlluminateRawLightmap( int num ); void IlluminateVertexes( int num ); @@ -1731,7 +1765,6 @@ void StitchSurfaceLightmaps( void ); void StoreSurfaceLightmaps( void ); - /* image.c */ void ImageFree( image_t *image ); image_t *ImageFind( const char *filename ); @@ -1783,6 +1816,7 @@ void UnparseEntities( void ); void PrintEntity( const entity_t *ent ); void SetKeyValue( entity_t *ent, const char *key, const char *value ); +qboolean KeyExists( const entity_t *ent, const char *key ); /* VorteX: check if key exists */ const char *ValueForKey( const entity_t *ent, const char *key ); int IntForKey( const entity_t *ent, const char *key ); vec_t FloatForKey( const entity_t *ent, const char *key ); @@ -1845,6 +1879,12 @@ , #include "game_qfusion.h" /* qfusion game */ , + #include "game_darkplaces.h" /* vortex: darkplaces q1 engine */ + , + #include "game_dq.h" /* vortex: deluxe quake game ( darkplaces q1 engine) */ + , + #include "game_prophecy.h" /* vortex: prophecy game ( darkplaces q1 engine) */ + , { NULL } /* null game */ }; #endif @@ -1929,6 +1969,7 @@ Q_EXTERN char outbase[ 32 ]; Q_EXTERN int sampleSize; /* lightmap sample size in units */ +Q_EXTERN int sampleScale; /* vortex: lightmap sample scale (ie quality)*/ Q_EXTERN int mapEntityNum Q_ASSIGN( 0 ); @@ -2053,6 +2094,7 @@ Q_EXTERN qboolean wolfLight Q_ASSIGN( qfalse ); Q_EXTERN qboolean loMem Q_ASSIGN( qfalse ); Q_EXTERN qboolean noStyles Q_ASSIGN( qfalse ); +Q_EXTERN qboolean keepLights Q_ASSIGN( qfalse ); Q_EXTERN int sampleSize Q_ASSIGN( DEFAULT_LIGHTMAP_SAMPLE_SIZE ); Q_EXTERN qboolean noVertexLighting Q_ASSIGN( qfalse ); @@ -2065,6 +2107,7 @@ Q_EXTERN qboolean deluxemap Q_ASSIGN( qfalse ); Q_EXTERN qboolean debugDeluxemap Q_ASSIGN( qfalse ); +Q_EXTERN int deluxemode Q_ASSIGN( 0 ); /* deluxemap format (0 - modelspace, 1 - tangentspace with renormalization, 2 - tangentspace without renormalization) */ Q_EXTERN qboolean fast Q_ASSIGN( qfalse ); Q_EXTERN qboolean faster Q_ASSIGN( qfalse ); @@ -2098,6 +2141,14 @@ Q_EXTERN float dirtScale Q_ASSIGN( 1.0f ); Q_EXTERN float dirtGain Q_ASSIGN( 1.0f ); +/* 27: floodlighting */ +Q_EXTERN qboolean debugnormals Q_ASSIGN( qfalse ); +Q_EXTERN qboolean floodlighty Q_ASSIGN( qfalse ); +Q_EXTERN qboolean floodlight_lowquality Q_ASSIGN( qfalse ); +Q_EXTERN vec3_t floodlightRGB; +Q_EXTERN float floodlightIntensity Q_ASSIGN( 512.0f ); +Q_EXTERN float floodlightDistance Q_ASSIGN( 1024.0f ); + Q_EXTERN qboolean dump Q_ASSIGN( qfalse ); Q_EXTERN qboolean debug Q_ASSIGN( qfalse ); Q_EXTERN qboolean debugUnused Q_ASSIGN( qfalse ); @@ -2115,9 +2166,14 @@ Q_EXTERN float skyScale Q_ASSIGN( 1.0f ); Q_EXTERN float bounceScale Q_ASSIGN( 0.25f ); +/* vortex: gridscale and gridambientscale */ +Q_EXTERN float gridScale Q_ASSIGN( 1.0f ); +Q_EXTERN float gridAmbientScale Q_ASSIGN( 1.0f ); + /* ydnar: lightmap gamma/compensation */ Q_EXTERN float lightmapGamma Q_ASSIGN( 1.0f ); Q_EXTERN float lightmapCompensate Q_ASSIGN( 1.0f ); +Q_EXTERN float lightmapExposure Q_ASSIGN( 1.0f ); /* ydnar: for runtime tweaking of falloff tolerance */ Q_EXTERN float falloffTolerance Q_ASSIGN( 1.0f ); @@ -2221,6 +2277,9 @@ Q_EXTERN int numExtLightmaps Q_ASSIGN( 0 ); Q_EXTERN outLightmap_t *outLightmaps Q_ASSIGN( NULL ); +/* vortex: per surface floodlight statictics */ +Q_EXTERN int numSurfacesFloodlighten Q_ASSIGN( 0 ); + /* grid points */ Q_EXTERN int numRawGridPoints Q_ASSIGN( 0 ); Q_EXTERN rawGridPoint_t *rawGridPoints Q_ASSIGN( NULL ); Index: shaders.c =================================================================== --- shaders.c (revision 158) +++ shaders.c (working copy) @@ -793,8 +793,14 @@ } if( VectorLength( si->color ) <= 0.0f ) + { ColorNormalize( color, si->color ); - VectorScale( color, (1.0f / count), si->averageColor ); + VectorScale( color, (1.0f / count), si->averageColor ); + } + else + { + VectorCopy( si->color, si->averageColor ); + } } @@ -804,13 +810,15 @@ finds a shaderinfo for a named shader */ +#define MAX_SHADER_DEPRECATION_DEPTH 16 + shaderInfo_t *ShaderInfoForShader( const char *shaderName ) { int i; + int deprecationDepth; shaderInfo_t *si; char shader[ MAX_QPATH ]; - - + /* dummy check */ if( shaderName == NULL || shaderName[ 0 ] == '\0' ) { @@ -823,11 +831,27 @@ StripExtension( shader ); /* search for it */ + deprecationDepth = 0; for( i = 0; i < numShaderInfo; i++ ) { si = &shaderInfo[ i ]; if( !Q_stricmp( shader, si->shader ) ) { + /* check if shader is deprecated */ + if (deprecationDepth < MAX_SHADER_DEPRECATION_DEPTH && si->deprecateShader && si->deprecateShader[ 0 ] ) + { + /* override name */ + strcpy( shader, si->deprecateShader ); + StripExtension( shader ); + /* increase deprecation depth */ + deprecationDepth++; + if (deprecationDepth == MAX_SHADER_DEPRECATION_DEPTH) + Sys_Printf("WARNING: Max deprecation depth of %i is reached on shader '%s'\n", MAX_SHADER_DEPRECATION_DEPTH, shader); + /* search again from beginning */ + i = -1; + continue; + } + /* load image if necessary */ if( si->finished == qfalse ) { @@ -1340,7 +1364,6 @@ { surfaceModel_t *model; - /* allocate new model and attach it */ model = safe_malloc( sizeof( *model ) ); memset( model, 0, sizeof( *model ) ); @@ -1465,6 +1488,24 @@ GetTokenAppend( shaderText, qfalse ); si->backsplashDistance = atof( token ); } + + /* q3map_floodLight */ + else if( !Q_stricmp( token, "q3map_floodLight" ) ) + { + /* get color */ + GetTokenAppend( shaderText, qfalse ); + si->floodlightRGB[ 0 ] = atof( token ); + GetTokenAppend( shaderText, qfalse ); + si->floodlightRGB[ 1 ] = atof( token ); + GetTokenAppend( shaderText, qfalse ); + si->floodlightRGB[ 2 ] = atof( token ); + GetTokenAppend( shaderText, qfalse ); + si->floodlightDistance = atof( token ); + GetTokenAppend( shaderText, qfalse ); + si->floodlightIntensity = atof( token ); + GetTokenAppend( shaderText, qfalse ); + si->floodlightDirectionScale = atof( token ); + } /* q3map_lightmapSampleSize */ else if( !Q_stricmp( token, "q3map_lightmapSampleSize" ) ) @@ -1590,6 +1631,18 @@ strcpy( si->remapShader, token ); } } + + /* q3map_deprecateShader */ + else if( !Q_stricmp( token, "q3map_deprecateShader" ) ) + { + GetTokenAppend( shaderText, qfalse ); + if( token[ 0 ] != '\0' ) + { + + si->deprecateShader = safe_malloc( strlen( token ) + 1 ); + strcpy( si->deprecateShader, token ); + } + } /* ydnar: q3map_offset */ else if( !Q_stricmp( token, "q3map_offset" ) ) @@ -1896,12 +1949,14 @@ si->styleMarker = 2; /* ydnar: default to searching for q3map_ */ - else +#if 0 + else { - //% Sys_FPrintf( SYS_VRB, "Attempting to match %s with a known surfaceparm\n", token ); + Sys_FPrintf( SYS_VRB, "Attempting to match %s with a known surfaceparm\n", token ); if( ApplySurfaceParm( &token[ 6 ], &si->contentFlags, &si->surfaceFlags, &si->compileFlags ) == qfalse ) - ;//% Sys_Printf( "WARNING: Unknown q3map_* directive \"%s\"\n", token ); + Sys_Printf( "WARNING: Unknown q3map_* directive \"%s\"\n", token ); } +#endif } Index: surface.c =================================================================== --- surface.c (revision 158) +++ surface.c (working copy) @@ -304,7 +304,7 @@ out = &mapDrawSurfs[ i ]; /* walk the surface list again until a proper surface is found */ - for( j; j < numMapDrawSurfs; j++ ) + for( ; j < numMapDrawSurfs; j++ ) { /* get in surface */ in = &mapDrawSurfs[ j ]; @@ -484,7 +484,7 @@ /* walk the list of surfaces */ - for( numSurfs; numSurfs > 0; numSurfs--, ds++ ) + for( ; numSurfs > 0; numSurfs--, ds++ ) { /* ignore bogus (or flare) surfaces */ if( ds->type == SURFACE_BAD || ds->numVerts <= 0 ) @@ -2445,25 +2445,27 @@ numSurfacesByType[ ds->type ]++; } - - /* EmitPatchSurface() emits a bsp patch drawsurface */ -void EmitPatchSurface( mapDrawSurface_t *ds ) +void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ) { int i, j; bspDrawSurface_t *out; int surfaceFlags, contentFlags; + int forcePatchMeta; + + /* vortex: _patchMeta support */ + forcePatchMeta = IntForKey(e, "_patchMeta" ); + if (!forcePatchMeta) + forcePatchMeta = IntForKey(e, "patchMeta" ); - /* invert the surface if necessary */ if( ds->backSide || ds->shaderInfo->invert ) { bspDrawVert_t *dv1, *dv2, temp; - /* walk the verts, flip the normal */ for( i = 0; i < ds->numVerts; i++ ) @@ -2485,7 +2487,7 @@ /* invert facing */ VectorScale( ds->lightmapVecs[ 2 ], -1.0f, ds->lightmapVecs[ 2 ] ); } - + /* allocate a new surface */ if( numBSPDrawSurfaces == MAX_MAP_DRAW_SURFS ) Error( "MAX_MAP_DRAW_SURFS" ); @@ -2493,12 +2495,12 @@ ds->outputNum = numBSPDrawSurfaces; numBSPDrawSurfaces++; memset( out, 0, sizeof( *out ) ); - + /* set it up */ out->surfaceType = MST_PATCH; if( debugSurfaces ) out->shaderNum = EmitShader( "debugsurfaces", NULL, NULL ); - else if( patchMeta ) + else if( patchMeta || forcePatchMeta ) { /* patch meta requires that we have nodraw patches for collision */ surfaceFlags = ds->shaderInfo->surfaceFlags; @@ -2548,8 +2550,6 @@ numSurfacesByType[ ds->type ]++; } - - /* OptimizeTriangleSurface() - ydnar optimizes the vertex/index data in a triangle surface @@ -2677,8 +2677,7 @@ { int i, temp; bspDrawSurface_t *out; - - + /* invert the surface if necessary */ if( ds->backSide || ds->shaderInfo->invert ) { @@ -2689,15 +2688,15 @@ ds->indexes[ i ] = ds->indexes[ i + 1 ]; ds->indexes[ i + 1 ] = temp; } - + /* walk the verts, flip the normal */ for( i = 0; i < ds->numVerts; i++ ) VectorScale( ds->verts[ i ].normal, -1.0f, ds->verts[ i ].normal ); - + /* invert facing */ VectorScale( ds->lightmapVecs[ 2 ], -1.0f, ds->lightmapVecs[ 2 ] ); } - + /* allocate a new surface */ if( numBSPDrawSurfaces == MAX_MAP_DRAW_SURFS ) Error( "MAX_MAP_DRAW_SURFS" ); @@ -2804,15 +2803,14 @@ emits a bsp planar winding (brush face) drawsurface */ -static void EmitFaceSurface( mapDrawSurface_t *ds ) +static void EmitFaceSurface(mapDrawSurface_t *ds ) { /* strip/fan finding was moved elsewhere */ StripFaceSurface( ds ); - EmitTriangleSurface( ds ); + EmitTriangleSurface(ds); } - /* MakeDebugPortalSurfs_r() - ydnar generates drawsurfaces for passable portals in the bsp @@ -3502,7 +3500,7 @@ if( refs == 0 ) refs = FilterPatchIntoTree( ds, tree ); if( refs > 0 ) - EmitPatchSurface( ds ); + EmitPatchSurface( e, ds ); break; /* handle triangle surfaces */ Index: surface_meta.c =================================================================== --- surface_meta.c (revision 158) +++ surface_meta.c (working copy) @@ -312,23 +312,41 @@ creates triangles from a patch */ -void TriangulatePatchSurface( mapDrawSurface_t *ds ) +void TriangulatePatchSurface( entity_t *e , mapDrawSurface_t *ds ) { int iterations, x, y, pw[ 5 ], r; mapDrawSurface_t *dsNew; mesh_t src, *subdivided, *mesh; - - + int forcePatchMeta; + int patchQuality; + int patchSubdivision; + + /* vortex: _patchMeta, _patchQuality, _patchSubdivide support */ + forcePatchMeta = IntForKey(e, "_patchMeta" ); + if (!forcePatchMeta) + forcePatchMeta = IntForKey(e, "patchMeta" ); + patchQuality = IntForKey(e, "_patchQuality" ); + if (!patchQuality) + patchQuality = IntForKey(e, "patchQuality" ); + if (!patchQuality) + patchQuality = 1.0; + patchSubdivision = IntForKey(e, "_patchSubdivide" ); + if (!patchSubdivision) + patchSubdivision = IntForKey(e, "patchSubdivide" ); + /* try to early out */ - if( ds->numVerts == 0 || ds->type != SURFACE_PATCH || patchMeta == qfalse ) + if(ds->numVerts == 0 || ds->type != SURFACE_PATCH || ( patchMeta == qfalse && !forcePatchMeta) ) return; - /* make a mesh from the drawsurf */ src.width = ds->patchWidth; src.height = ds->patchHeight; src.verts = ds->verts; //% subdivided = SubdivideMesh( src, 8, 999 ); - iterations = IterationsForCurve( ds->longestCurve, patchSubdivisions ); + if (patchSubdivision) + iterations = IterationsForCurve( ds->longestCurve, patchSubdivision ); + else + iterations = IterationsForCurve( ds->longestCurve, patchSubdivisions / patchQuality ); + subdivided = SubdivideMesh2( src, iterations ); //% ds->maxIterations /* fit it to the curve and remove colinear verts on rows/columns */ @@ -652,12 +685,12 @@ break; case SURFACE_PATCH: - TriangulatePatchSurface( ds ); + TriangulatePatchSurface(e, ds ); break; case SURFACE_TRIANGLES: break; - + case SURFACE_FORCED_META: case SURFACE_META: SurfaceToMetaTriangles( ds ); @@ -972,8 +1005,8 @@ vec3_t average, diff; int indexes[ MAX_SAMPLES ]; vec3_t votes[ MAX_SAMPLES ]; + const char *classname; - /* note it */ Sys_FPrintf( SYS_VRB, "--- SmoothMetaTriangles ---\n" ); @@ -994,11 +1027,31 @@ and set per-vertex smoothing angle */ for( i = 0, tri = &metaTriangles[ i ]; i < numMetaTriangles; i++, tri++ ) { + /* vortex: try get smoothing from entity key */ + shadeAngle = FloatForKey(&entities[tri->entityNum], "_smoothnormals"); + if (shadeAngle <= 0.0f) + shadeAngle = FloatForKey(&entities[tri->entityNum], "_sn"); + if (shadeAngle <= 0.0f) + shadeAngle = FloatForKey(&entities[tri->entityNum], "_smooth"); + if (shadeAngle > 0.0f) + { + if (entities[tri->entityNum].forceNormalSmoothing == qfalse) + { + entities[tri->entityNum].forceNormalSmoothing = qtrue; + classname = ValueForKey( &entities[tri->entityNum], "classname" ); + Sys_Printf( "Entity %d (%s) has vertex normal smoothing with breaking angle of %3.0f\n", tri->entityNum, classname, shadeAngle ); + } + shadeAngle = DEG2RAD( shadeAngle ); + } + /* get shader for shade angle */ - if( tri->si->shadeAngleDegrees > 0.0f ) - shadeAngle = DEG2RAD( tri->si->shadeAngleDegrees ); - else - shadeAngle = defaultShadeAngle; + if (shadeAngle <= 0.0f) + { + if( tri->si->shadeAngleDegrees > 0.0f ) + shadeAngle = DEG2RAD( tri->si->shadeAngleDegrees ); + else + shadeAngle = defaultShadeAngle; + } if( shadeAngle > maxShadeAngle ) maxShadeAngle = shadeAngle; Index: writebsp.c =================================================================== --- writebsp.c (revision 158) +++ writebsp.c (working copy) @@ -136,7 +136,6 @@ bspLeaf_t *leaf_p; brush_t *b; drawSurfRef_t *dsr; - int i = 0; /* check limits */ @@ -278,18 +277,19 @@ void SetLightStyles( void ) { int i, j, style, numStyles; - qboolean keepLights; const char *t; entity_t *e; epair_t *ep, *next; char value[ 10 ]; char lightTargets[ MAX_SWITCHED_LIGHTS ][ 64 ]; int lightStyles[ MAX_SWITCHED_LIGHTS ]; - - + /* ydnar: determine if we keep lights in the bsp */ - t = ValueForKey( &entities[ 0 ], "_keepLights" ); - keepLights = (t[ 0 ] == '1') ? qtrue : qfalse; + if (KeyExists(&entities[ 0 ], "_keepLights") == qtrue) + { + t = ValueForKey( &entities[ 0 ], "_keepLights" ); + keepLights = (t[ 0 ] == '1') ? qtrue : qfalse; + } /* any light that is controlled (has a targetname) must have a unique style number generated for it */ numStyles = 0;