Add ortho lights (still has serious issues that make them unusable on regular maps).
First real attempt at lit water. Parsing rtlights is now aware of spotlights. Default cl_yieldcpu to 1, to save cpu for anyone who sets cl_maxfps lower. Added to menus. presets now include view angle clamping - maps made for quakespasm REQUIRE full pitch angles despite it otherwise being considered a cheat or glitchy (on servers that try to block the cheat). fix r_fullbrightSkins>=1 issue. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5274 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
1da1414e48
commit
0fee3a4aea
59 changed files with 1576 additions and 943 deletions
|
@ -832,6 +832,7 @@ endif
|
||||||
ifeq (1,$(USE_OPUS))
|
ifeq (1,$(USE_OPUS))
|
||||||
LIBOPUS_STATIC=-DOPUS_STATIC
|
LIBOPUS_STATIC=-DOPUS_STATIC
|
||||||
LIBOPUS_LDFLAGS=-lopus
|
LIBOPUS_LDFLAGS=-lopus
|
||||||
|
ALL_CFLAGS+=-I/usr/include/opus
|
||||||
endif
|
endif
|
||||||
ifeq (1,$(USE_SPEEX))
|
ifeq (1,$(USE_SPEEX))
|
||||||
LIBSPEEX_STATIC=-DSPEEX_STATIC
|
LIBSPEEX_STATIC=-DSPEEX_STATIC
|
||||||
|
|
|
@ -1765,9 +1765,9 @@ static void CL_SendUserinfoUpdate(void)
|
||||||
else if (cls.fteprotocolextensions2 & PEXT2_INFOBLOBS)
|
else if (cls.fteprotocolextensions2 & PEXT2_INFOBLOBS)
|
||||||
{ //only flood servers that actually support it.
|
{ //only flood servers that actually support it.
|
||||||
if (final)
|
if (final)
|
||||||
s = va("%ssetinfo \"%s\" \"%s\" %u", pl, enckey, encval, bloboffset);
|
s = va("%ssetinfo \"%s\" \"%s\" %u", pl, enckey, encval, (unsigned int)bloboffset);
|
||||||
else
|
else
|
||||||
s = va("%ssetinfo \"%s\" \"%s\" %u+", pl, enckey, encval, bloboffset);
|
s = va("%ssetinfo \"%s\" \"%s\" %u+", pl, enckey, encval, (unsigned int)bloboffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //server doesn't support it, just ignore the key
|
{ //server doesn't support it, just ignore the key
|
||||||
|
|
|
@ -57,9 +57,9 @@ cvar_t cl_shownet = CVARD("cl_shownet","0", "Debugging var. 0 shows nothing. 1 s
|
||||||
cvar_t cl_pure = CVARD("cl_pure", "0", "0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 is only reliable with total conversions.\nIf sv_pure is set, the client will prefer the highest value set.");
|
cvar_t cl_pure = CVARD("cl_pure", "0", "0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 is only reliable with total conversions.\nIf sv_pure is set, the client will prefer the highest value set.");
|
||||||
cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback);
|
cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback);
|
||||||
cvar_t cl_hudswap = CVARF("cl_hudswap", "0", CVAR_ARCHIVE);
|
cvar_t cl_hudswap = CVARF("cl_hudswap", "0", CVAR_ARCHIVE);
|
||||||
cvar_t cl_maxfps = CVARF("cl_maxfps", "500", CVAR_ARCHIVE);
|
cvar_t cl_maxfps = CVARFD("cl_maxfps", "500", CVAR_ARCHIVE, "Sets the maximum allowed framerate. If you're using vsync or want to uncap framerates entirely then you should probably set this to 0. Set cl_yieldcpu 0 if you're trying to benchmark.");
|
||||||
cvar_t cl_idlefps = CVARFD("cl_idlefps", "30", CVAR_ARCHIVE, "This is the maximum framerate to attain while idle/paused/unfocused.");
|
cvar_t cl_idlefps = CVARFD("cl_idlefps", "30", CVAR_ARCHIVE, "This is the maximum framerate to attain while idle/paused/unfocused.");
|
||||||
cvar_t cl_yieldcpu = CVARFD("cl_yieldcpu", "0", CVAR_ARCHIVE, "Attempt to yield between frames. This can resolve issues with certain drivers and background software, but can mean less consistant frame times. Will reduce power consumption/heat generation so should be set on laptops or similar (over-hot/battery powered) devices.");
|
cvar_t cl_yieldcpu = CVARFD("cl_yieldcpu", "1", CVAR_ARCHIVE, "Attempt to yield between frames. This can resolve issues with certain drivers and background software, but can mean less consistant frame times. Will reduce power consumption/heat generation so should be set on laptops or similar (over-hot/battery powered) devices.");
|
||||||
cvar_t cl_nopext = CVARF("cl_nopext", "0", CVAR_ARCHIVE);
|
cvar_t cl_nopext = CVARF("cl_nopext", "0", CVAR_ARCHIVE);
|
||||||
cvar_t cl_pext_mask = CVAR("cl_pext_mask", "0xffffffff");
|
cvar_t cl_pext_mask = CVAR("cl_pext_mask", "0xffffffff");
|
||||||
cvar_t cl_nolerp = CVARD("cl_nolerp", "0", "Disables interpolation. If set, missiles/monsters will be show exactly what was last received, which will be jerky. Does not affect players. A value of 2 means 'interpolate only in single-player/coop'.");
|
cvar_t cl_nolerp = CVARD("cl_nolerp", "0", "Disables interpolation. If set, missiles/monsters will be show exactly what was last received, which will be jerky. Does not affect players. A value of 2 means 'interpolate only in single-player/coop'.");
|
||||||
|
@ -1634,6 +1634,9 @@ void CL_ClearState (void)
|
||||||
|
|
||||||
InfoBuf_Clear(&cl.serverinfo, true);
|
InfoBuf_Clear(&cl.serverinfo, true);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
InfoBuf_Clear(&cl.players[i].userinfo, true);
|
||||||
|
|
||||||
// wipe the entire cl structure
|
// wipe the entire cl structure
|
||||||
memset (&cl, 0, sizeof(cl));
|
memset (&cl, 0, sizeof(cl));
|
||||||
|
|
||||||
|
@ -5567,7 +5570,7 @@ double Host_Frame (double time)
|
||||||
{
|
{
|
||||||
while(COM_DoWork(0, false))
|
while(COM_DoWork(0, false))
|
||||||
;
|
;
|
||||||
return (cl_yieldcpu.ival || vid.isminimized)? (1.0 / maxfps - (realtime - oldrealtime)) : 0;
|
return (cl_yieldcpu.ival || vid.isminimized || idle)? (1.0 / maxfps - (realtime - oldrealtime)) : 0;
|
||||||
}
|
}
|
||||||
if (spare < 0 || cls.state < ca_onserver)
|
if (spare < 0 || cls.state < ca_onserver)
|
||||||
spare = 0; //uncapped.
|
spare = 0; //uncapped.
|
||||||
|
|
|
@ -305,7 +305,7 @@ typedef struct
|
||||||
#define LFLAG_NOSHADOWS (1<<8)
|
#define LFLAG_NOSHADOWS (1<<8)
|
||||||
#define LFLAG_SHADOWMAP (1<<9)
|
#define LFLAG_SHADOWMAP (1<<9)
|
||||||
#define LFLAG_CREPUSCULAR (1<<10) //weird type of sun light that gives god rays
|
#define LFLAG_CREPUSCULAR (1<<10) //weird type of sun light that gives god rays
|
||||||
//#define LFLAG_ORTHO (1<<11) //sun-style -light
|
#define LFLAG_ORTHO (1<<11) //sun-style -light
|
||||||
|
|
||||||
#define LFLAG_INTERNAL (LFLAG_LIGHTMAP|LFLAG_FLASHBLEND) //these are internal to FTE, and never written to disk (ie: .rtlights files shouldn't contain these)
|
#define LFLAG_INTERNAL (LFLAG_LIGHTMAP|LFLAG_FLASHBLEND) //these are internal to FTE, and never written to disk (ie: .rtlights files shouldn't contain these)
|
||||||
#define LFLAG_DYNAMIC (LFLAG_LIGHTMAP | LFLAG_FLASHBLEND | LFLAG_NORMALMODE | LFLAG_REALTIMEMODE)
|
#define LFLAG_DYNAMIC (LFLAG_LIGHTMAP | LFLAG_FLASHBLEND | LFLAG_NORMALMODE | LFLAG_REALTIMEMODE)
|
||||||
|
|
|
@ -369,10 +369,10 @@ void PM_ValidatePackage(package_t *p)
|
||||||
}
|
}
|
||||||
else if (p->qhash)
|
else if (p->qhash)
|
||||||
{
|
{
|
||||||
char buf[8];
|
|
||||||
searchpathfuncs_t *archive;
|
searchpathfuncs_t *archive;
|
||||||
|
|
||||||
#ifdef PACKAGE_Q1PAK
|
#ifdef PACKAGE_Q1PAK
|
||||||
|
char buf[8];
|
||||||
if (!Q_strcasecmp(COM_FileExtension(n, buf, sizeof(buf)), "pak"))
|
if (!Q_strcasecmp(COM_FileExtension(n, buf, sizeof(buf)), "pak"))
|
||||||
archive = FSPAK_LoadArchive(pf, NULL, n, n, NULL);
|
archive = FSPAK_LoadArchive(pf, NULL, n, n, NULL);
|
||||||
else
|
else
|
||||||
|
@ -2852,6 +2852,10 @@ qboolean PM_FindUpdatedEngine(char *syspath, size_t syspathsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
qboolean PM_CanInstall(const char *packagename)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void PM_Command_f (void)
|
void PM_Command_f (void)
|
||||||
{
|
{
|
||||||
Con_Printf("Package Manager is not implemented in this build\n");
|
Con_Printf("Package Manager is not implemented in this build\n");
|
||||||
|
|
|
@ -341,6 +341,7 @@ void Media_WriteCurrentTrack(sizebuf_t *buf)
|
||||||
qboolean Media_NamedTrack(const char *track, const char *looptrack)
|
qboolean Media_NamedTrack(const char *track, const char *looptrack)
|
||||||
{
|
{
|
||||||
unsigned int tracknum;
|
unsigned int tracknum;
|
||||||
|
//FIXME: for q2, gog uses ../music/Track%02i.ogg, with various remapping requirements for the mission packs.
|
||||||
static char *path[] =
|
static char *path[] =
|
||||||
{
|
{
|
||||||
"music/",
|
"music/",
|
||||||
|
|
|
@ -793,6 +793,7 @@ const char *presetexec[] =
|
||||||
"seta cl_gibfilter 1;"
|
"seta cl_gibfilter 1;"
|
||||||
"if cl_deadbodyfilter == 0 then seta cl_deadbodyfilter 1;" //as useful as 2 is, some mods use death frames for crouching etc.
|
"if cl_deadbodyfilter == 0 then seta cl_deadbodyfilter 1;" //as useful as 2 is, some mods use death frames for crouching etc.
|
||||||
"seta gl_simpleitems 1;"
|
"seta gl_simpleitems 1;"
|
||||||
|
"seta cl_fullpitch 1;seta maxpitch \"\";seta minpitch \"\";" //mimic quakespasm where possible.
|
||||||
|
|
||||||
, // fast options
|
, // fast options
|
||||||
"gl_texturemode ln;"
|
"gl_texturemode ln;"
|
||||||
|
@ -838,8 +839,10 @@ const char *presetexec[] =
|
||||||
//"d_mipcap \"0 3\";" //logically correct, but will fuck up on ATI drivers if increased mid-map, because ATI will just ignore any levels that are not currently enabled.
|
//"d_mipcap \"0 3\";" //logically correct, but will fuck up on ATI drivers if increased mid-map, because ATI will just ignore any levels that are not currently enabled.
|
||||||
"cl_gibfilter 0;"
|
"cl_gibfilter 0;"
|
||||||
"seta cl_deadbodyfilter 0;"
|
"seta cl_deadbodyfilter 0;"
|
||||||
|
"cl_fullpitch 1;maxpitch 90;seta minpitch -90;" //QS has cheaty viewpitch range. some maps require it.
|
||||||
|
|
||||||
, //vanilla-esque options.
|
, //vanilla-esque options.
|
||||||
|
"cl_fullpitch 0;maxpitch \"\";seta minpitch \"\";" //quakespasm is not vanilla
|
||||||
"gl_texturemode nll;" //yup, we went there.
|
"gl_texturemode nll;" //yup, we went there.
|
||||||
"gl_texturemode2d n.l;" //yeah, 2d too.
|
"gl_texturemode2d n.l;" //yeah, 2d too.
|
||||||
"r_nolerp 1;"
|
"r_nolerp 1;"
|
||||||
|
@ -876,6 +879,7 @@ const char *presetexec[] =
|
||||||
"r_loadlit 1;"
|
"r_loadlit 1;"
|
||||||
"r_nolerp 0;"
|
"r_nolerp 0;"
|
||||||
"r_noframegrouplerp 0;"
|
"r_noframegrouplerp 0;"
|
||||||
|
"cl_fullpitch 1;maxpitch 90;seta minpitch -90;"
|
||||||
|
|
||||||
, // nice options
|
, // nice options
|
||||||
// "r_stains 0.75;"
|
// "r_stains 0.75;"
|
||||||
|
@ -1112,7 +1116,7 @@ void M_Menu_FPS_f (void)
|
||||||
menu_t *menu;
|
menu_t *menu;
|
||||||
fpsmenuinfo_t *info;
|
fpsmenuinfo_t *info;
|
||||||
|
|
||||||
extern cvar_t v_contentblend, show_fps, cl_r2g, cl_gibfilter, cl_expsprite, cl_deadbodyfilter, cl_lerp_players, cl_nolerp;
|
extern cvar_t v_contentblend, show_fps, cl_r2g, cl_gibfilter, cl_expsprite, cl_deadbodyfilter, cl_lerp_players, cl_nolerp, cl_maxfps, cl_yieldcpu;
|
||||||
static menuresel_t resel;
|
static menuresel_t resel;
|
||||||
int y;
|
int y;
|
||||||
menu = M_Options_Title(&y, sizeof(fpsmenuinfo_t));
|
menu = M_Options_Title(&y, sizeof(fpsmenuinfo_t));
|
||||||
|
@ -1129,6 +1133,8 @@ void M_Menu_FPS_f (void)
|
||||||
MB_CMD("Apply", M_PresetApply, "Applies selected preset."),
|
MB_CMD("Apply", M_PresetApply, "Applies selected preset."),
|
||||||
MB_SPACING(4),
|
MB_SPACING(4),
|
||||||
MB_COMBOCVAR("Show FPS", show_fps, fpsopts, fpsvalues, "Display FPS or frame millisecond values on screen. Settings except immediate are for values across 1 second."),
|
MB_COMBOCVAR("Show FPS", show_fps, fpsopts, fpsvalues, "Display FPS or frame millisecond values on screen. Settings except immediate are for values across 1 second."),
|
||||||
|
MB_EDITCVARSLIM("Framerate Limiter", cl_maxfps.name, "Limits the maximum framerate. Set to 0 for none."),
|
||||||
|
MB_CHECKBOXCVARTIP("Yield CPU", cl_yieldcpu, 1, "Reduce CPU usage between frames.\nShould probably be off when using vsync."),
|
||||||
MB_COMBOCVAR("Player lerping", cl_lerp_players, playerlerpopts, values_0_1, "Smooth movement of other players, but will increase effective latency. Does not affect all network protocols."),
|
MB_COMBOCVAR("Player lerping", cl_lerp_players, playerlerpopts, values_0_1, "Smooth movement of other players, but will increase effective latency. Does not affect all network protocols."),
|
||||||
MB_COMBOCVAR("Entity lerping", cl_nolerp, entlerpopts, values_0_1_2, "Smooth movement of entities, but will increase effective latency."),
|
MB_COMBOCVAR("Entity lerping", cl_nolerp, entlerpopts, values_0_1_2, "Smooth movement of entities, but will increase effective latency."),
|
||||||
MB_CHECKBOXCVAR("Content Blend", v_contentblend, 0),
|
MB_CHECKBOXCVAR("Content Blend", v_contentblend, 0),
|
||||||
|
@ -2782,6 +2788,18 @@ void M_Menu_Video_f (void)
|
||||||
};
|
};
|
||||||
static const char *scalevalues[] = { "1", "1.5", "2", "2.5", "3", "4", "5", "6", NULL};
|
static const char *scalevalues[] = { "1", "1.5", "2", "2.5", "3", "4", "5", "6", NULL};
|
||||||
|
|
||||||
|
static const char *vsyncopts[] =
|
||||||
|
{
|
||||||
|
"Off",
|
||||||
|
"Strict",
|
||||||
|
"Lax",
|
||||||
|
"Alternate Frames",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
static const char *vsyncvalues[] = { "0", "1", "-1", "2", NULL};
|
||||||
|
extern cvar_t vid_vsync;
|
||||||
|
extern cvar_t cl_maxfps;
|
||||||
|
extern cvar_t cl_yieldcpu;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static const char *vsyncoptions[] =
|
static const char *vsyncoptions[] =
|
||||||
|
@ -2849,6 +2867,7 @@ void M_Menu_Video_f (void)
|
||||||
MB_EDITCVARSLIMRETURN("Height", "vid_height", info->height),
|
MB_EDITCVARSLIMRETURN("Height", "vid_height", info->height),
|
||||||
MB_EDITCVARSLIMRETURN("Color Depth", "vid_bpp", info->bpp),
|
MB_EDITCVARSLIMRETURN("Color Depth", "vid_bpp", info->bpp),
|
||||||
MB_EDITCVARSLIMRETURN("Refresh Rate", "vid_displayfrequency", info->hz),
|
MB_EDITCVARSLIMRETURN("Refresh Rate", "vid_displayfrequency", info->hz),
|
||||||
|
|
||||||
MB_SPACING(4),
|
MB_SPACING(4),
|
||||||
MB_COMBORETURN("2D Mode", res2dmodeopts, res2dmodechoice, info->res2dmode, "Select method for determining or configuring 2D resolution and scaling. The default option matches the current display resolution, and the scale option scales by a factor of the display resolution."),
|
MB_COMBORETURN("2D Mode", res2dmodeopts, res2dmodechoice, info->res2dmode, "Select method for determining or configuring 2D resolution and scaling. The default option matches the current display resolution, and the scale option scales by a factor of the display resolution."),
|
||||||
// scale entry
|
// scale entry
|
||||||
|
@ -2874,6 +2893,11 @@ void M_Menu_Video_f (void)
|
||||||
MB_SLIDER("Gamma", v_gamma, 1.5, 0.25, -0.05, NULL),
|
MB_SLIDER("Gamma", v_gamma, 1.5, 0.25, -0.05, NULL),
|
||||||
MB_COMBOCVAR("Gamma Mode", vid_srgb, srgbopts, srgbvalues, "Controls the colour space to try to use."),
|
MB_COMBOCVAR("Gamma Mode", vid_srgb, srgbopts, srgbvalues, "Controls the colour space to try to use."),
|
||||||
MB_SLIDER("Contrast", v_contrast, 0.8, 3, 0.05, NULL),
|
MB_SLIDER("Contrast", v_contrast, 0.8, 3, 0.05, NULL),
|
||||||
|
|
||||||
|
MB_COMBOCVAR("VSync", vid_vsync, vsyncopts, vsyncvalues, "Controls whether to wait for rendering to finish."),
|
||||||
|
MB_EDITCVARSLIM("Framerate Limiter", cl_maxfps.name, "Limits the maximum framerate. Set to 0 for none."),
|
||||||
|
MB_CHECKBOXCVARTIP("Yield CPU", cl_yieldcpu, 1, "Reduce CPU usage between frames.\nShould probably be off when using vsync."),
|
||||||
|
|
||||||
MB_END()
|
MB_END()
|
||||||
};
|
};
|
||||||
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
|
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
|
//we need some types available elsewhere, but don't really want to have to include the entire vulkan api everywhere.
|
||||||
|
//unfortunately, vulkan's handle types are not well defined.
|
||||||
#if defined(__LP64__) || defined(_WIN64)
|
#if defined(__LP64__) || defined(_WIN64)
|
||||||
#define VulkanAPIRandomness void*
|
#define VulkanAPIRandomness void*
|
||||||
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
||||||
|
@ -6,12 +8,12 @@
|
||||||
#else
|
#else
|
||||||
#define VulkanAPIRandomness long long
|
#define VulkanAPIRandomness long long
|
||||||
#endif
|
#endif
|
||||||
#define VkRetardedDescriptorSet VulkanAPIRandomness
|
#define qVkDescriptorSet VulkanAPIRandomness
|
||||||
#define VkRetardedShaderModule VulkanAPIRandomness
|
#define qVkShaderModule VulkanAPIRandomness
|
||||||
#define VkRetardedPipelineLayout VulkanAPIRandomness
|
#define qVkPipelineLayout VulkanAPIRandomness
|
||||||
#define VkRetardedDescriptorSetLayout VulkanAPIRandomness
|
#define qVkDescriptorSetLayout VulkanAPIRandomness
|
||||||
#define VkRetardedBuffer VulkanAPIRandomness
|
#define qVkBuffer VulkanAPIRandomness
|
||||||
#define VkRetardedDeviceMemory VulkanAPIRandomness
|
#define qVkDeviceMemory VulkanAPIRandomness
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//These are defined later in the source tree. This file should probably be moved to a later spot.
|
//These are defined later in the source tree. This file should probably be moved to a later spot.
|
||||||
|
@ -248,7 +250,7 @@ typedef struct image_s
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
VkRetardedDescriptorSet vkdescriptor;
|
qVkDescriptorSet vkdescriptor;
|
||||||
struct vk_image_s *vkimage;
|
struct vk_image_s *vkimage;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -334,7 +336,7 @@ typedef union vboarray_s
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
VkRetardedBuffer buff;
|
qVkBuffer buff;
|
||||||
unsigned int offs;
|
unsigned int offs;
|
||||||
} vk;
|
} vk;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -940,7 +940,7 @@ static int PClassic_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
|
||||||
if (dir)
|
if (dir)
|
||||||
VectorCopy(dir, dl->axis[0]);
|
VectorCopy(dir, dl->axis[0]);
|
||||||
else
|
else
|
||||||
VectorSet(dir, 0, 0, 1);
|
VectorSet(dl->axis[0], 0, 0, 1);
|
||||||
VectorVectors(dl->axis[0], dl->axis[1], dl->axis[2]);
|
VectorVectors(dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||||
VectorInverse(dl->axis[1]);
|
VectorInverse(dl->axis[1]);
|
||||||
if (dir)
|
if (dir)
|
||||||
|
|
|
@ -975,4 +975,24 @@ void QCBUILTIN PF_cl_getgamedirinfo(pubprogfuncs_t *prinst, struct globalvars_s
|
||||||
G_INT(OFS_RETURN) = 0;
|
G_INT(OFS_RETURN) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This is consistent with vanilla quakeworld's 'packet' console command.
|
||||||
|
void QCBUILTIN PF_cl_SendPacket(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
{
|
||||||
|
netadr_t to;
|
||||||
|
const char *address = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||||
|
const char *contents = PF_VarString(prinst, 1, pr_globals);
|
||||||
|
|
||||||
|
G_FLOAT(OFS_RETURN) = NETERR_NOROUTE;
|
||||||
|
if (NET_StringToAdr(address, 0, &to))
|
||||||
|
{
|
||||||
|
char *send = Z_Malloc(4+strlen(contents));
|
||||||
|
send[0] = send[1] = send[2] = send[3] = 0xff;
|
||||||
|
memcpy(send+4, contents, strlen(contents));
|
||||||
|
//FIXME: NS_CLIENT is likely to change its port randomly...
|
||||||
|
G_FLOAT(OFS_RETURN) = NET_SendPacket(NS_CLIENT, 4+strlen(contents), send, &to);
|
||||||
|
Z_Free(send);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -522,7 +522,7 @@ typedef struct csqcedict_s
|
||||||
int lastruntime;
|
int lastruntime;
|
||||||
int solidsize;
|
int solidsize;
|
||||||
#ifdef USERBE
|
#ifdef USERBE
|
||||||
entityode_t ode;
|
entityrbe_t rbe;
|
||||||
#endif
|
#endif
|
||||||
/*the above is shared with ssqc*/
|
/*the above is shared with ssqc*/
|
||||||
|
|
||||||
|
@ -6207,7 +6207,7 @@ static struct {
|
||||||
|
|
||||||
{"checkpvs", PF_checkpvs, 240},
|
{"checkpvs", PF_checkpvs, 240},
|
||||||
// {"matchclientname", PF_matchclient, 241},
|
// {"matchclientname", PF_matchclient, 241},
|
||||||
{"sendpacket", PF_NoCSQC, 242}, //void(string dest, string content) sendpacket = #242; (FTE_QC_SENDPACKET)
|
{"sendpacket", PF_cl_SendPacket, 242}, //void(string dest, string content) sendpacket = #242; (FTE_QC_SENDPACKET)
|
||||||
|
|
||||||
// {"bulleten", PF_bulleten, 243}, (removed builtin)
|
// {"bulleten", PF_bulleten, 243}, (removed builtin)
|
||||||
{"rotatevectorsbytag", PF_rotatevectorsbytag, 244},
|
{"rotatevectorsbytag", PF_rotatevectorsbytag, 244},
|
||||||
|
|
|
@ -292,6 +292,7 @@ void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
||||||
G_FLOAT(OFS_RETURN) = slotnum;
|
G_FLOAT(OFS_RETURN) = slotnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOLEGACY
|
||||||
void CL_LoadFont_f(void)
|
void CL_LoadFont_f(void)
|
||||||
{
|
{
|
||||||
//console command for compat with dp/debug.
|
//console command for compat with dp/debug.
|
||||||
|
@ -405,6 +406,7 @@ void CL_LoadFont_f(void)
|
||||||
Cvar_Set(&gl_font, facename);
|
Cvar_Set(&gl_font, facename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//scrolling could be done with scissoring.
|
//scrolling could be done with scissoring.
|
||||||
//selection could be done with some substrings
|
//selection could be done with some substrings
|
||||||
|
@ -585,7 +587,7 @@ void QCBUILTIN PF_CL_drawrotpic (pubprogfuncs_t *prinst, struct globalvars_s *pr
|
||||||
|
|
||||||
r2d_be_flags = PF_SelectDPDrawFlag(flag);
|
r2d_be_flags = PF_SelectDPDrawFlag(flag);
|
||||||
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
||||||
R2D_Image2dQuad(points, tcoords, p);
|
R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, p);
|
||||||
r2d_be_flags = 0;
|
r2d_be_flags = 0;
|
||||||
|
|
||||||
G_FLOAT(OFS_RETURN) = 1;
|
G_FLOAT(OFS_RETURN) = 1;
|
||||||
|
@ -657,7 +659,7 @@ void QCBUILTIN PF_CL_drawrotsubpic (pubprogfuncs_t *prinst, struct globalvars_s
|
||||||
|
|
||||||
r2d_be_flags = PF_SelectDPDrawFlag(flag);
|
r2d_be_flags = PF_SelectDPDrawFlag(flag);
|
||||||
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
||||||
R2D_Image2dQuad(points, tcoords, p);
|
R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, p);
|
||||||
r2d_be_flags = 0;
|
r2d_be_flags = 0;
|
||||||
|
|
||||||
G_FLOAT(OFS_RETURN) = 1;
|
G_FLOAT(OFS_RETURN) = 1;
|
||||||
|
@ -2148,6 +2150,7 @@ static struct {
|
||||||
{"strtrim", PF_strtrim, 0},
|
{"strtrim", PF_strtrim, 0},
|
||||||
//gap
|
//gap
|
||||||
{"shaderforname", PF_shaderforname, 238},
|
{"shaderforname", PF_shaderforname, 238},
|
||||||
|
{"sendpacket", PF_cl_SendPacket, 242},
|
||||||
//gap
|
//gap
|
||||||
{"hash_createtab", PF_hash_createtab, 287},
|
{"hash_createtab", PF_hash_createtab, 287},
|
||||||
{"hash_destroytab", PF_hash_destroytab, 288},
|
{"hash_destroytab", PF_hash_destroytab, 288},
|
||||||
|
@ -2765,7 +2768,9 @@ void MP_RegisterCvarsAndCmds(void)
|
||||||
Cmd_AddCommand("coredump_menuqc", MP_CoreDump_f);
|
Cmd_AddCommand("coredump_menuqc", MP_CoreDump_f);
|
||||||
Cmd_AddCommand("menu_cmd", MP_GameCommand_f);
|
Cmd_AddCommand("menu_cmd", MP_GameCommand_f);
|
||||||
Cmd_AddCommand("breakpoint_menu", MP_Breakpoint_f);
|
Cmd_AddCommand("breakpoint_menu", MP_Breakpoint_f);
|
||||||
|
#ifndef NOLEGACY
|
||||||
Cmd_AddCommand("loadfont", CL_LoadFont_f);
|
Cmd_AddCommand("loadfont", CL_LoadFont_f);
|
||||||
|
#endif
|
||||||
|
|
||||||
Cmd_AddCommand("poke_menuqc", MP_Poke_f);
|
Cmd_AddCommand("poke_menuqc", MP_Poke_f);
|
||||||
|
|
||||||
|
|
|
@ -1115,6 +1115,39 @@ void skel_lookup(world_t *world, int skelidx, framestate_t *out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void skel_updateentbounds(world_t *w, wedict_t *ent)
|
||||||
|
{/*
|
||||||
|
float radius[MAX_BONES];
|
||||||
|
float maxr = 0;
|
||||||
|
size_t i, numbones;
|
||||||
|
skelobject_t *skel = skel_get(w, ent->xv->skeletonindex);
|
||||||
|
galiasbone_t *bones;
|
||||||
|
if (!skel)
|
||||||
|
return;
|
||||||
|
bones = Mod_GetBoneInfo(skel->model, &numbones);
|
||||||
|
if (!skel || numbones != skel->numbones)
|
||||||
|
return;
|
||||||
|
if (skel->type == SKEL_RELATIVE)
|
||||||
|
{
|
||||||
|
for (i = 0; i < skel->numbones; i++)
|
||||||
|
{
|
||||||
|
radius[i] = skel->bonematrix[i*12+3]*skel->bonematrix[i*12+3]+skel->bonematrix[i*12+7]*skel->bonematrix[i*12+7]+skel->bonematrix[i*12+11]*skel->bonematrix[i*12+11];
|
||||||
|
if (bones[i].parent >= 0)
|
||||||
|
radius[i] += radius[bones[i].parent];
|
||||||
|
if (maxr < radius[i] + bones[i].radius)
|
||||||
|
maxr = radius[i] + bones[i].radius;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (ent->v->absmin[i] > env->v->origin-maxr)
|
||||||
|
ent->v->absmin[i] = env->v->origin-maxr;
|
||||||
|
if (ent->v->absmax[i] < env->v->origin+maxr)
|
||||||
|
ent->v->absmax[i] = env->v->origin+maxr;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
void QCBUILTIN PF_skel_mmap(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
void QCBUILTIN PF_skel_mmap(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
world_t *world = prinst->parms->user;
|
world_t *world = prinst->parms->user;
|
||||||
|
|
|
@ -301,7 +301,9 @@ extern cvar_t com_protocolname;
|
||||||
extern cvar_t com_protocolversion;
|
extern cvar_t com_protocolversion;
|
||||||
extern cvar_t com_nogamedirnativecode;
|
extern cvar_t com_nogamedirnativecode;
|
||||||
extern cvar_t com_parseutf8;
|
extern cvar_t com_parseutf8;
|
||||||
|
#ifndef NOLEGACY
|
||||||
extern cvar_t com_parseezquake;
|
extern cvar_t com_parseezquake;
|
||||||
|
#endif
|
||||||
extern cvar_t sys_ticrate;
|
extern cvar_t sys_ticrate;
|
||||||
extern cvar_t sys_nostdout;
|
extern cvar_t sys_nostdout;
|
||||||
extern cvar_t developer;
|
extern cvar_t developer;
|
||||||
|
|
|
@ -3600,6 +3600,8 @@ void Surf_DeInit(void)
|
||||||
Z_Free(surf_frustumvis[i].buffer);
|
Z_Free(surf_frustumvis[i].buffer);
|
||||||
memset(surf_frustumvis, 0, sizeof(surf_frustumvis));
|
memset(surf_frustumvis, 0, sizeof(surf_frustumvis));
|
||||||
|
|
||||||
|
CL_FreeDlights();
|
||||||
|
|
||||||
lightmap=NULL;
|
lightmap=NULL;
|
||||||
numlightmaps=0;
|
numlightmaps=0;
|
||||||
|
|
||||||
|
@ -4286,6 +4288,7 @@ TRACE(("dbg: Surf_NewMap: tp\n"));
|
||||||
cl_static_entities[i].emit = NULL;
|
cl_static_entities[i].emit = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CL_InitDlights();
|
||||||
#ifdef RTLIGHTS
|
#ifdef RTLIGHTS
|
||||||
Sh_PreGenerateLights();
|
Sh_PreGenerateLights();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,6 +101,9 @@ cvar_t gl_shadeq1_name = CVARD ("gl_shadeq1_name", "*", "Rename all surfac
|
||||||
extern cvar_t r_vertexlight;
|
extern cvar_t r_vertexlight;
|
||||||
extern cvar_t r_forceprogramify;
|
extern cvar_t r_forceprogramify;
|
||||||
extern cvar_t dpcompat_nopremulpics;
|
extern cvar_t dpcompat_nopremulpics;
|
||||||
|
#ifdef PSKMODELS
|
||||||
|
cvar_t dpcompat_psa_ungroup = CVAR ("dpcompat_psa_ungroup", "0");
|
||||||
|
#endif
|
||||||
|
|
||||||
cvar_t mod_md3flags = CVARD ("mod_md3flags", "1", "The flags field of md3s was never officially defined. If this is set to 1, the flags will be treated identically to mdl files. Otherwise they will be ignored. Naturally, this is required to provide rotating pickups in quake.");
|
cvar_t mod_md3flags = CVARD ("mod_md3flags", "1", "The flags field of md3s was never officially defined. If this is set to 1, the flags will be treated identically to mdl files. Otherwise they will be ignored. Naturally, this is required to provide rotating pickups in quake.");
|
||||||
|
|
||||||
|
@ -418,7 +421,6 @@ cvar_t vid_triplebuffer = CVARAFD ("vid_triplebuffer", "1", "gl_triplebuffe
|
||||||
cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through.");
|
cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through.");
|
||||||
cvar_t r_portaldrawplanes = CVARD ("r_portaldrawplanes", "0", "Draw front and back planes in portals. Debug feature.");
|
cvar_t r_portaldrawplanes = CVARD ("r_portaldrawplanes", "0", "Draw front and back planes in portals. Debug feature.");
|
||||||
cvar_t r_portalonly = CVARD ("r_portalonly", "0", "Don't draw things which are not portals. Debug feature.");
|
cvar_t r_portalonly = CVARD ("r_portalonly", "0", "Don't draw things which are not portals. Debug feature.");
|
||||||
cvar_t dpcompat_psa_ungroup = CVAR ("dpcompat_psa_ungroup", "0");
|
|
||||||
cvar_t r_noaliasshadows = CVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE);
|
cvar_t r_noaliasshadows = CVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE);
|
||||||
cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blob shadows underneath entities without using realtime lighting.");
|
cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blob shadows underneath entities without using realtime lighting.");
|
||||||
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
|
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
|
||||||
|
@ -516,7 +518,9 @@ void GLRenderer_Init(void)
|
||||||
Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS);
|
Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS);
|
||||||
Cvar_Register (&gl_lerpimages, GLRENDEREROPTIONS);
|
Cvar_Register (&gl_lerpimages, GLRENDEREROPTIONS);
|
||||||
|
|
||||||
|
#ifdef PSKMODELS
|
||||||
Cvar_Register (&dpcompat_psa_ungroup, GLRENDEREROPTIONS);
|
Cvar_Register (&dpcompat_psa_ungroup, GLRENDEREROPTIONS);
|
||||||
|
#endif
|
||||||
Cvar_Register (&r_lerpmuzzlehack, GLRENDEREROPTIONS);
|
Cvar_Register (&r_lerpmuzzlehack, GLRENDEREROPTIONS);
|
||||||
Cvar_Register (&r_noframegrouplerp, GLRENDEREROPTIONS);
|
Cvar_Register (&r_noframegrouplerp, GLRENDEREROPTIONS);
|
||||||
Cvar_Register (&r_portalrecursion, GLRENDEREROPTIONS);
|
Cvar_Register (&r_portalrecursion, GLRENDEREROPTIONS);
|
||||||
|
@ -1004,7 +1008,9 @@ void Renderer_Init(void)
|
||||||
Cvar_Register (&r_polygonoffset_stencil_offset, GLRENDEREROPTIONS);
|
Cvar_Register (&r_polygonoffset_stencil_offset, GLRENDEREROPTIONS);
|
||||||
|
|
||||||
Cvar_Register (&r_forceprogramify, GLRENDEREROPTIONS);
|
Cvar_Register (&r_forceprogramify, GLRENDEREROPTIONS);
|
||||||
|
#ifndef NOLEGACY
|
||||||
Cvar_Register (&dpcompat_nopremulpics, GLRENDEREROPTIONS);
|
Cvar_Register (&dpcompat_nopremulpics, GLRENDEREROPTIONS);
|
||||||
|
#endif
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
Cvar_Register (&vk_stagingbuffers, VKRENDEREROPTIONS);
|
Cvar_Register (&vk_stagingbuffers, VKRENDEREROPTIONS);
|
||||||
Cvar_Register (&vk_submissionthread, VKRENDEREROPTIONS);
|
Cvar_Register (&vk_submissionthread, VKRENDEREROPTIONS);
|
||||||
|
@ -1792,12 +1798,16 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
|
||||||
|
|
||||||
void R_ReloadRenderer_f (void)
|
void R_ReloadRenderer_f (void)
|
||||||
{
|
{
|
||||||
|
#ifndef CLIENTONLY
|
||||||
void *portalblob = NULL;
|
void *portalblob = NULL;
|
||||||
size_t portalsize = 0;
|
size_t portalsize = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
float time = Sys_DoubleTime();
|
float time = Sys_DoubleTime();
|
||||||
if (qrenderer == QR_NONE || qrenderer == QR_HEADLESS)
|
if (qrenderer == QR_NONE || qrenderer == QR_HEADLESS)
|
||||||
return; //don't bother reloading the renderer if its not actually rendering anything anyway.
|
return; //don't bother reloading the renderer if its not actually rendering anything anyway.
|
||||||
|
|
||||||
|
#ifndef CLIENTONLY
|
||||||
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
|
@ -1805,6 +1815,7 @@ void R_ReloadRenderer_f (void)
|
||||||
if (portalsize && (portalblob = BZ_Malloc(portalsize)))
|
if (portalsize && (portalblob = BZ_Malloc(portalsize)))
|
||||||
memcpy(portalblob, t, portalsize);
|
memcpy(portalblob, t, portalsize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Cvar_ApplyLatches(CVAR_VIDEOLATCH|CVAR_RENDERERLATCH);
|
Cvar_ApplyLatches(CVAR_VIDEOLATCH|CVAR_RENDERERLATCH);
|
||||||
R_ShutdownRenderer(false);
|
R_ShutdownRenderer(false);
|
||||||
|
@ -1813,13 +1824,14 @@ void R_ReloadRenderer_f (void)
|
||||||
R_ApplyRenderer_Load(NULL);
|
R_ApplyRenderer_Load(NULL);
|
||||||
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
|
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
|
||||||
|
|
||||||
|
#ifndef CLIENTONLY
|
||||||
if (portalblob)
|
if (portalblob)
|
||||||
{
|
{
|
||||||
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
CM_ReadPortalState(sv.world.worldmodel, portalblob, portalsize);
|
CM_ReadPortalState(sv.world.worldmodel, portalblob, portalsize);
|
||||||
BZ_Free(portalblob);
|
BZ_Free(portalblob);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//use Cvar_ApplyLatches(CVAR_RENDERERLATCH) beforehand.
|
//use Cvar_ApplyLatches(CVAR_RENDERERLATCH) beforehand.
|
||||||
|
@ -2036,8 +2048,10 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
||||||
|
|
||||||
void R_RestartRenderer (rendererstate_t *newr)
|
void R_RestartRenderer (rendererstate_t *newr)
|
||||||
{
|
{
|
||||||
|
#ifndef CLIENTONLY
|
||||||
void *portalblob = NULL;
|
void *portalblob = NULL;
|
||||||
size_t portalsize = 0;
|
size_t portalsize = 0;
|
||||||
|
#endif
|
||||||
rendererstate_t oldr;
|
rendererstate_t oldr;
|
||||||
if (r_blockvidrestart)
|
if (r_blockvidrestart)
|
||||||
{
|
{
|
||||||
|
@ -2045,6 +2059,7 @@ void R_RestartRenderer (rendererstate_t *newr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CLIENTONLY
|
||||||
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
|
@ -2052,6 +2067,7 @@ void R_RestartRenderer (rendererstate_t *newr)
|
||||||
if (portalsize && (portalblob = BZ_Malloc(portalsize)))
|
if (portalsize && (portalblob = BZ_Malloc(portalsize)))
|
||||||
memcpy(portalblob, t, portalsize);
|
memcpy(portalblob, t, portalsize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TRACE(("dbg: R_RestartRenderer_f renderer %p\n", newr->renderer));
|
TRACE(("dbg: R_RestartRenderer_f renderer %p\n", newr->renderer));
|
||||||
|
|
||||||
|
@ -2127,12 +2143,14 @@ void R_RestartRenderer (rendererstate_t *newr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CLIENTONLY
|
||||||
if (portalblob)
|
if (portalblob)
|
||||||
{
|
{
|
||||||
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
CM_ReadPortalState(sv.world.worldmodel, portalblob, portalsize);
|
CM_ReadPortalState(sv.world.worldmodel, portalblob, portalsize);
|
||||||
BZ_Free(portalblob);
|
BZ_Free(portalblob);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
|
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
|
||||||
SCR_EndLoadingPlaque();
|
SCR_EndLoadingPlaque();
|
||||||
|
|
|
@ -2829,18 +2829,20 @@ static void S_UpdateSoundCard(soundcardinfo_t *sc, qboolean updateonly, channel_
|
||||||
target_chan->entchannel = entchannel;
|
target_chan->entchannel = entchannel;
|
||||||
SND_Spatialize(sc, target_chan);
|
SND_Spatialize(sc, target_chan);
|
||||||
|
|
||||||
if (!updateonly && !target_chan->vol[0] && !target_chan->vol[1] && !target_chan->vol[2] && !target_chan->vol[3] && !target_chan->vol[4] && !target_chan->vol[5] && sc->ChannelUpdate)
|
|
||||||
{
|
|
||||||
target_chan->sfx = NULL;
|
|
||||||
return; // not audible at all
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!S_LoadSound (sfx))
|
if (!S_LoadSound (sfx))
|
||||||
{
|
{
|
||||||
target_chan->sfx = NULL;
|
target_chan->sfx = NULL;
|
||||||
return; // couldn't load the sound's data
|
return; // couldn't load the sound's data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: why does this only filter for openal devices? its weird.
|
||||||
|
if (!updateonly && !target_chan->vol[0] && !target_chan->vol[1] && !target_chan->vol[2] && !target_chan->vol[3] && !target_chan->vol[4] && !target_chan->vol[5] && sc->ChannelUpdate)
|
||||||
|
if (sfx->loopstart == -1 && !(flags&CF_FORCELOOP)) //only skip if its not looping.
|
||||||
|
{
|
||||||
|
target_chan->sfx = NULL;
|
||||||
|
return; // not audible at all
|
||||||
|
}
|
||||||
|
|
||||||
target_chan->sfx = sfx;
|
target_chan->sfx = sfx;
|
||||||
|
|
||||||
if (updateonly && sc->ChannelUpdate)
|
if (updateonly && sc->ChannelUpdate)
|
||||||
|
|
|
@ -26,8 +26,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
cvar_t ruleset_allow_in = CVAR("ruleset_allow_in", "1");
|
cvar_t ruleset_allow_in = CVAR("ruleset_allow_in", "1");
|
||||||
cvar_t rcon_level = CVAR("rcon_level", "20");
|
cvar_t rcon_level = CVAR("rcon_level", "20");
|
||||||
cvar_t cmd_maxbuffersize = CVAR("cmd_maxbuffersize", "65536");
|
cvar_t cmd_maxbuffersize = CVAR("cmd_maxbuffersize", "65536");
|
||||||
|
#ifndef NOLEGACY
|
||||||
cvar_t dpcompat_set = CVAR("dpcompat_set", "0");
|
cvar_t dpcompat_set = CVAR("dpcompat_set", "0");
|
||||||
cvar_t dpcompat_console = CVARD("dpcompat_console", "0", "Enables hacks to emulate DP's console.");
|
cvar_t dpcompat_console = CVARD("dpcompat_console", "0", "Enables hacks to emulate DP's console.");
|
||||||
|
#else
|
||||||
|
static const cvar_t dpcompat_set = {0};
|
||||||
|
static const cvar_t dpcompat_console = {0};
|
||||||
|
#endif
|
||||||
int Cmd_ExecLevel;
|
int Cmd_ExecLevel;
|
||||||
qboolean cmd_didwait;
|
qboolean cmd_didwait;
|
||||||
qboolean cmd_blockwait;
|
qboolean cmd_blockwait;
|
||||||
|
@ -857,7 +862,11 @@ void Cmd_Echo_f (void)
|
||||||
Con_Printf ("%s", t);
|
Con_Printf ("%s", t);
|
||||||
#else
|
#else
|
||||||
t = TP_ParseFunChars(t);
|
t = TP_ParseFunChars(t);
|
||||||
|
#ifndef NOLEGACY
|
||||||
Con_PrintFlags (t, (com_parseezquake.ival?PFS_EZQUAKEMARKUP:0), 0);
|
Con_PrintFlags (t, (com_parseezquake.ival?PFS_EZQUAKEMARKUP:0), 0);
|
||||||
|
#else
|
||||||
|
Con_PrintFlags (t, 0, 0);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4222,12 +4231,12 @@ void Cmd_Init (void)
|
||||||
|
|
||||||
Cmd_AddCommand ("cmdlist", Cmd_List_f);
|
Cmd_AddCommand ("cmdlist", Cmd_List_f);
|
||||||
Cmd_AddCommand ("aliaslist", Cmd_AliasList_f);
|
Cmd_AddCommand ("aliaslist", Cmd_AliasList_f);
|
||||||
Cmd_AddCommand ("macrolist", Cmd_MacroList_f);
|
Cmd_AddCommandD ("macrolist", Cmd_MacroList_f, "Lists all available $macro expansions.");
|
||||||
Cmd_AddCommand ("cvarlist", Cvar_List_f);
|
Cmd_AddCommandD ("cvarlist", Cvar_List_f, "Lists all cvars. eg, 'cvarlist -cvd *' can be used to list all cvars with a value other than the mod's default.");
|
||||||
Cmd_AddCommand ("cvarreset", Cvar_Reset_f);
|
Cmd_AddCommandD ("cvarreset", Cvar_Reset_f, "Resets the named cvar to its default value.");
|
||||||
Cmd_AddCommandD ("cvarwatch", Cvar_Watch_f, "Prints a notification when the named cvar is changed. Also displays the start/end of configs. Alternatively, use '-watch foo' on the commandline.");
|
Cmd_AddCommandD ("cvarwatch", Cvar_Watch_f, "Prints a notification when the named cvar is changed. Also displays the start/end of configs. Alternatively, use '-watch foo' on the commandline.");
|
||||||
Cmd_AddCommand ("cvar_lockdefaults", Cvar_LockDefaults_f);
|
Cmd_AddCommand ("cvar_lockdefaults", Cvar_LockDefaults_f);
|
||||||
Cmd_AddCommand ("cvar_purgedefaults", Cvar_PurgeDefaults_f);
|
Cmd_AddCommandD ("cvar_purgedefaults", Cvar_PurgeDefaults_f, "Resets all cvar defaults to back to the engine's default. Does not change their active value.");
|
||||||
|
|
||||||
Cmd_AddCommandD ("apropos", Cmd_Apropos_f, "Lists all cvars or commands with the specified substring somewhere in their name or descrition.");
|
Cmd_AddCommandD ("apropos", Cmd_Apropos_f, "Lists all cvars or commands with the specified substring somewhere in their name or descrition.");
|
||||||
Cmd_AddCommandD ("find", Cmd_Apropos_f, "Lists all cvars or commands with the specified substring somewhere in their name or descrition.");
|
Cmd_AddCommandD ("find", Cmd_Apropos_f, "Lists all cvars or commands with the specified substring somewhere in their name or descrition.");
|
||||||
|
@ -4237,7 +4246,6 @@ void Cmd_Init (void)
|
||||||
Cmd_AddMacro("ukdate", Macro_UKDate, false);
|
Cmd_AddMacro("ukdate", Macro_UKDate, false);
|
||||||
Cmd_AddMacro("usdate", Macro_USDate, false);
|
Cmd_AddMacro("usdate", Macro_USDate, false);
|
||||||
Cmd_AddMacro("date", Macro_ProperDate, false);
|
Cmd_AddMacro("date", Macro_ProperDate, false);
|
||||||
Cmd_AddMacro("properdate", Macro_ProperDate, false);
|
|
||||||
Cmd_AddMacro("version", Macro_Version, false);
|
Cmd_AddMacro("version", Macro_Version, false);
|
||||||
Cmd_AddMacro("qt", Macro_Quote, false);
|
Cmd_AddMacro("qt", Macro_Quote, false);
|
||||||
Cmd_AddMacro("dedicated", Macro_Dedicated, false);
|
Cmd_AddMacro("dedicated", Macro_Dedicated, false);
|
||||||
|
@ -4247,8 +4255,10 @@ void Cmd_Init (void)
|
||||||
Cvar_Register(&ruleset_allow_in, "Console");
|
Cvar_Register(&ruleset_allow_in, "Console");
|
||||||
Cmd_AddCommandD ("in", Cmd_In_f, "Issues the given command after a time delay. Disabled if ruleset_allow_in is 0.");
|
Cmd_AddCommandD ("in", Cmd_In_f, "Issues the given command after a time delay. Disabled if ruleset_allow_in is 0.");
|
||||||
|
|
||||||
|
#ifndef NOLEGACY
|
||||||
Cvar_Register(&dpcompat_set, "Darkplaces compatibility");
|
Cvar_Register(&dpcompat_set, "Darkplaces compatibility");
|
||||||
Cvar_Register(&dpcompat_console, "Darkplaces compatibility");
|
Cvar_Register(&dpcompat_console, "Darkplaces compatibility");
|
||||||
|
#endif
|
||||||
Cvar_Register (&cl_warncmd, "Warnings");
|
Cvar_Register (&cl_warncmd, "Warnings");
|
||||||
Cvar_Register (&cfg_save_all, "client operation options");
|
Cvar_Register (&cfg_save_all, "client operation options");
|
||||||
Cvar_Register (&cfg_save_auto, "client operation options");
|
Cvar_Register (&cfg_save_auto, "client operation options");
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qboolean r_loadbumpmapping;
|
qboolean r_loadbumpmapping;
|
||||||
extern cvar_t dpcompat_psa_ungroup;
|
|
||||||
extern cvar_t r_noframegrouplerp;
|
extern cvar_t r_noframegrouplerp;
|
||||||
cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE);
|
cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE);
|
||||||
static void QDECL r_meshpitch_callback(cvar_t *var, char *oldvalue)
|
static void QDECL r_meshpitch_callback(cvar_t *var, char *oldvalue)
|
||||||
|
@ -2029,9 +2028,11 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader)
|
||||||
#else
|
#else
|
||||||
if (!mod->numanimations)
|
if (!mod->numanimations)
|
||||||
{
|
{
|
||||||
|
#ifdef SKELETALMODELS
|
||||||
if (mod->ofs_skel_xyz)
|
if (mod->ofs_skel_xyz)
|
||||||
posedata = mod->ofs_skel_xyz;
|
posedata = mod->ofs_skel_xyz;
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5551,6 +5552,7 @@ qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fsize)
|
||||||
//psk
|
//psk
|
||||||
#ifdef PSKMODELS
|
#ifdef PSKMODELS
|
||||||
/*Typedefs copied from DarkPlaces*/
|
/*Typedefs copied from DarkPlaces*/
|
||||||
|
extern cvar_t dpcompat_psa_ungroup;
|
||||||
|
|
||||||
typedef struct pskchunk_s
|
typedef struct pskchunk_s
|
||||||
{
|
{
|
||||||
|
@ -6061,6 +6063,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
|
||||||
}
|
}
|
||||||
num_animinfo = numgroups;
|
num_animinfo = numgroups;
|
||||||
}
|
}
|
||||||
|
#ifdef NOLEGACY
|
||||||
else if (dpcompat_psa_ungroup.ival)
|
else if (dpcompat_psa_ungroup.ival)
|
||||||
{
|
{
|
||||||
/*unpack each frame of each animation to be a separate framegroup*/
|
/*unpack each frame of each animation to be a separate framegroup*/
|
||||||
|
@ -6086,6 +6089,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
|
||||||
}
|
}
|
||||||
num_animinfo = iframe;
|
num_animinfo = iframe;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*keep each framegroup as a group*/
|
/*keep each framegroup as a group*/
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct galiasbone_s
|
||||||
{
|
{
|
||||||
char name[32];
|
char name[32];
|
||||||
int parent;
|
int parent;
|
||||||
|
// float radius;
|
||||||
float inverse[12];
|
float inverse[12];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
#ifdef USE_INTERNAL_BULLET
|
||||||
#define FTEENGINE
|
#define FTEENGINE
|
||||||
#undef FTEPLUGIN
|
#undef FTEPLUGIN
|
||||||
#include "../../plugins/bullet/bulletplug.cpp"
|
#include "../../plugins/bullet/bulletplug.cpp"
|
||||||
|
#endif
|
|
@ -1371,53 +1371,53 @@ static void QDECL World_ODE_End(world_t *world)
|
||||||
|
|
||||||
static void QDECL World_ODE_RemoveJointFromEntity(world_t *world, wedict_t *ed)
|
static void QDECL World_ODE_RemoveJointFromEntity(world_t *world, wedict_t *ed)
|
||||||
{
|
{
|
||||||
ed->ode.ode_joint_type = 0;
|
ed->rbe.joint_type = 0;
|
||||||
if(ed->ode.ode_joint)
|
if(ed->rbe.joint.joint)
|
||||||
dJointDestroy((dJointID)ed->ode.ode_joint);
|
dJointDestroy((dJointID)ed->rbe.joint.joint);
|
||||||
ed->ode.ode_joint = NULL;
|
ed->rbe.joint.joint = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QDECL World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed)
|
static void QDECL World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed)
|
||||||
{
|
{
|
||||||
if (!ed->ode.ode_physics)
|
if (!ed->rbe.physics)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// entity is not physics controlled, free any physics data
|
// entity is not physics controlled, free any physics data
|
||||||
ed->ode.ode_physics = false;
|
ed->rbe.physics = false;
|
||||||
if (ed->ode.ode_geom)
|
if (ed->rbe.body.geom)
|
||||||
dGeomDestroy((dGeomID)ed->ode.ode_geom);
|
dGeomDestroy((dGeomID)ed->rbe.body.geom);
|
||||||
ed->ode.ode_geom = NULL;
|
ed->rbe.body.geom = NULL;
|
||||||
if (ed->ode.ode_body)
|
if (ed->rbe.body.body)
|
||||||
{
|
{
|
||||||
dJointID j;
|
dJointID j;
|
||||||
dBodyID b1, b2;
|
dBodyID b1, b2;
|
||||||
wedict_t *ed2;
|
wedict_t *ed2;
|
||||||
while(dBodyGetNumJoints((dBodyID)ed->ode.ode_body))
|
while(dBodyGetNumJoints((dBodyID)ed->rbe.body.body))
|
||||||
{
|
{
|
||||||
j = dBodyGetJoint((dBodyID)ed->ode.ode_body, 0);
|
j = dBodyGetJoint((dBodyID)ed->rbe.body.body, 0);
|
||||||
ed2 = (wedict_t *) dJointGetData(j);
|
ed2 = (wedict_t *) dJointGetData(j);
|
||||||
b1 = dJointGetBody(j, 0);
|
b1 = dJointGetBody(j, 0);
|
||||||
b2 = dJointGetBody(j, 1);
|
b2 = dJointGetBody(j, 1);
|
||||||
if(b1 == (dBodyID)ed->ode.ode_body)
|
if(b1 == (dBodyID)ed->rbe.body.body)
|
||||||
{
|
{
|
||||||
b1 = 0;
|
b1 = 0;
|
||||||
ed2->ode.ode_joint_enemy = 0;
|
ed2->rbe.joint_enemy = 0;
|
||||||
}
|
}
|
||||||
if(b2 == (dBodyID)ed->ode.ode_body)
|
if(b2 == (dBodyID)ed->rbe.body.body)
|
||||||
{
|
{
|
||||||
b2 = 0;
|
b2 = 0;
|
||||||
ed2->ode.ode_joint_aiment = 0;
|
ed2->rbe.joint_aiment = 0;
|
||||||
}
|
}
|
||||||
dJointAttach(j, b1, b2);
|
dJointAttach(j, b1, b2);
|
||||||
}
|
}
|
||||||
dBodyDestroy((dBodyID)ed->ode.ode_body);
|
dBodyDestroy((dBodyID)ed->rbe.body.body);
|
||||||
}
|
}
|
||||||
ed->ode.ode_body = NULL;
|
ed->rbe.body.body = NULL;
|
||||||
|
|
||||||
rbefuncs->ReleaseCollisionMesh(ed);
|
rbefuncs->ReleaseCollisionMesh(ed);
|
||||||
if(ed->ode.ode_massbuf)
|
if(ed->rbe.massbuf)
|
||||||
BZ_Free(ed->ode.ode_massbuf);
|
BZ_Free(ed->rbe.massbuf);
|
||||||
ed->ode.ode_massbuf = NULL;
|
ed->rbe.massbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
|
@ -1427,7 +1427,7 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
const dReal *o;
|
const dReal *o;
|
||||||
const dReal *r; // for some reason dBodyGetRotation returns a [3][4] matrix
|
const dReal *r; // for some reason dBodyGetRotation returns a [3][4] matrix
|
||||||
const dReal *vel;
|
const dReal *vel;
|
||||||
dBodyID body = (dBodyID)ed->ode.ode_body;
|
dBodyID body = (dBodyID)ed->rbe.body.body;
|
||||||
int movetype;
|
int movetype;
|
||||||
float bodymatrix[16];
|
float bodymatrix[16];
|
||||||
float entitymatrix[16];
|
float entitymatrix[16];
|
||||||
|
@ -1479,7 +1479,7 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
VectorCopy(vel, velocity);
|
VectorCopy(vel, velocity);
|
||||||
VectorCopy(avel, spinvelocity);
|
VectorCopy(avel, spinvelocity);
|
||||||
Matrix4x4_RM_FromVectors(bodymatrix, forward, left, up, origin);
|
Matrix4x4_RM_FromVectors(bodymatrix, forward, left, up, origin);
|
||||||
Matrix4_Multiply(ed->ode.ode_offsetimatrix, bodymatrix, entitymatrix);
|
Matrix4_Multiply(ed->rbe.offsetimatrix, bodymatrix, entitymatrix);
|
||||||
Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
|
Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
|
||||||
|
|
||||||
VectorAngles(forward, up, angles, false);
|
VectorAngles(forward, up, angles, false);
|
||||||
|
@ -1507,11 +1507,11 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
VectorCopy(avelocity, ed->v->avelocity);
|
VectorCopy(avelocity, ed->v->avelocity);
|
||||||
|
|
||||||
// values for BodyFromEntity to check if the qc modified anything later
|
// values for BodyFromEntity to check if the qc modified anything later
|
||||||
VectorCopy(origin, ed->ode.ode_origin);
|
VectorCopy(origin, ed->rbe.origin);
|
||||||
VectorCopy(velocity, ed->ode.ode_velocity);
|
VectorCopy(velocity, ed->rbe.velocity);
|
||||||
VectorCopy(angles, ed->ode.ode_angles);
|
VectorCopy(angles, ed->rbe.angles);
|
||||||
VectorCopy(avelocity, ed->ode.ode_avelocity);
|
VectorCopy(avelocity, ed->rbe.avelocity);
|
||||||
ed->ode.ode_gravity = dBodyGetGravityMode(body);
|
ed->rbe.gravity = dBodyGetGravityMode(body);
|
||||||
|
|
||||||
rbefuncs->LinkEdict(world, ed, true);
|
rbefuncs->LinkEdict(world, ed, true);
|
||||||
}
|
}
|
||||||
|
@ -1544,10 +1544,10 @@ static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
jointtype = 0; // can't have both
|
jointtype = 0; // can't have both
|
||||||
|
|
||||||
o = (wedict_t*)PROG_TO_EDICT(world->progs, enemy);
|
o = (wedict_t*)PROG_TO_EDICT(world->progs, enemy);
|
||||||
if(ED_ISFREE(o) || o->ode.ode_body == 0)
|
if(ED_ISFREE(o) || o->rbe.body.body == 0)
|
||||||
enemy = 0;
|
enemy = 0;
|
||||||
o = (wedict_t*)PROG_TO_EDICT(world->progs, aiment);
|
o = (wedict_t*)PROG_TO_EDICT(world->progs, aiment);
|
||||||
if(ED_ISFREE(o) || o->ode.ode_body == 0)
|
if(ED_ISFREE(o) || o->rbe.body.body == 0)
|
||||||
aiment = 0;
|
aiment = 0;
|
||||||
// see http://www.ode.org/old_list_archives/2006-January/017614.html
|
// see http://www.ode.org/old_list_archives/2006-January/017614.html
|
||||||
// we want to set ERP? make it fps independent and work like a spring constant
|
// we want to set ERP? make it fps independent and work like a spring constant
|
||||||
|
@ -1579,7 +1579,7 @@ static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
FMax = 0;
|
FMax = 0;
|
||||||
Stop = dInfinity;
|
Stop = dInfinity;
|
||||||
}
|
}
|
||||||
if(jointtype == ed->ode.ode_joint_type && VectorCompare(origin, ed->ode.ode_joint_origin) && VectorCompare(velocity, ed->ode.ode_joint_velocity) && VectorCompare(angles, ed->ode.ode_joint_angles) && enemy == ed->ode.ode_joint_enemy && aiment == ed->ode.ode_joint_aiment && VectorCompare(movedir, ed->ode.ode_joint_movedir))
|
if(jointtype == ed->rbe.joint_type && VectorCompare(origin, ed->rbe.joint_origin) && VectorCompare(velocity, ed->rbe.joint_velocity) && VectorCompare(angles, ed->rbe.joint_angles) && enemy == ed->rbe.joint_enemy && aiment == ed->rbe.joint_aiment && VectorCompare(movedir, ed->rbe.joint_movedir))
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
AngleVectorsFLU(angles, forward, left, up);
|
AngleVectorsFLU(angles, forward, left, up);
|
||||||
switch(jointtype)
|
switch(jointtype)
|
||||||
|
@ -1608,28 +1608,28 @@ static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
j = 0;
|
j = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(ed->ode.ode_joint)
|
if(ed->rbe.joint.joint)
|
||||||
{
|
{
|
||||||
//Con_Printf("deleted old joint %i\n", (int) (ed - prog->edicts));
|
//Con_Printf("deleted old joint %i\n", (int) (ed - prog->edicts));
|
||||||
dJointAttach(ed->ode.ode_joint, 0, 0);
|
dJointAttach(ed->rbe.joint.joint, 0, 0);
|
||||||
dJointDestroy(ed->ode.ode_joint);
|
dJointDestroy(ed->rbe.joint.joint);
|
||||||
}
|
}
|
||||||
ed->ode.ode_joint = (void *) j;
|
ed->rbe.joint.joint = (void *) j;
|
||||||
ed->ode.ode_joint_type = jointtype;
|
ed->rbe.joint_type = jointtype;
|
||||||
ed->ode.ode_joint_enemy = enemy;
|
ed->rbe.joint_enemy = enemy;
|
||||||
ed->ode.ode_joint_aiment = aiment;
|
ed->rbe.joint_aiment = aiment;
|
||||||
VectorCopy(origin, ed->ode.ode_joint_origin);
|
VectorCopy(origin, ed->rbe.joint_origin);
|
||||||
VectorCopy(velocity, ed->ode.ode_joint_velocity);
|
VectorCopy(velocity, ed->rbe.joint_velocity);
|
||||||
VectorCopy(angles, ed->ode.ode_joint_angles);
|
VectorCopy(angles, ed->rbe.joint_angles);
|
||||||
VectorCopy(movedir, ed->ode.ode_joint_movedir);
|
VectorCopy(movedir, ed->rbe.joint_movedir);
|
||||||
if(j)
|
if(j)
|
||||||
{
|
{
|
||||||
//Con_Printf("made new joint %i\n", (int) (ed - prog->edicts));
|
//Con_Printf("made new joint %i\n", (int) (ed - prog->edicts));
|
||||||
dJointSetData(j, (void *) ed);
|
dJointSetData(j, (void *) ed);
|
||||||
if(enemy)
|
if(enemy)
|
||||||
b1 = (dBodyID)((WEDICT_NUM_UB(world->progs, enemy))->ode.ode_body);
|
b1 = (dBodyID)((WEDICT_NUM_UB(world->progs, enemy))->rbe.body.body);
|
||||||
if(aiment)
|
if(aiment)
|
||||||
b2 = (dBodyID)((WEDICT_NUM_UB(world->progs, aiment))->ode.ode_body);
|
b2 = (dBodyID)((WEDICT_NUM_UB(world->progs, aiment))->rbe.body.body);
|
||||||
dJointAttach(j, b1, b2);
|
dJointAttach(j, b1, b2);
|
||||||
|
|
||||||
switch(jointtype)
|
switch(jointtype)
|
||||||
|
@ -1995,7 +1995,7 @@ static void QDECL World_ODE_RagDestroyJoint(world_t *world, rbejoint_t *joint)
|
||||||
static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
{
|
{
|
||||||
struct odectx_s *ctx = (struct odectx_s*)world->rbe;
|
struct odectx_s *ctx = (struct odectx_s*)world->rbe;
|
||||||
dBodyID body = (dBodyID)ed->ode.ode_body;
|
dBodyID body = (dBodyID)ed->rbe.body.body;
|
||||||
dMass mass;
|
dMass mass;
|
||||||
float test;
|
float test;
|
||||||
void *dataID;
|
void *dataID;
|
||||||
|
@ -2090,7 +2090,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// case GEOMTYPE_NONE:
|
// case GEOMTYPE_NONE:
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_ODE_RemoveFromEntity(world, ed);
|
World_ODE_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2099,7 +2099,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
if (DotProduct(geomsize,geomsize) == 0)
|
if (DotProduct(geomsize,geomsize) == 0)
|
||||||
{
|
{
|
||||||
// we don't allow point-size physics objects...
|
// we don't allow point-size physics objects...
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_ODE_RemoveFromEntity(world, ed);
|
World_ODE_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2108,21 +2108,21 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
massval = 1.0f;
|
massval = 1.0f;
|
||||||
|
|
||||||
// check if we need to create or replace the geom
|
// check if we need to create or replace the geom
|
||||||
if (!ed->ode.ode_physics
|
if (!ed->rbe.physics
|
||||||
|| !VectorCompare(ed->ode.ode_mins, entmins)
|
|| !VectorCompare(ed->rbe.mins, entmins)
|
||||||
|| !VectorCompare(ed->ode.ode_maxs, entmaxs)
|
|| !VectorCompare(ed->rbe.maxs, entmaxs)
|
||||||
|| ed->ode.ode_mass != massval
|
|| ed->rbe.mass != massval
|
||||||
|| ed->ode.ode_modelindex != modelindex)
|
|| ed->rbe.modelindex != modelindex)
|
||||||
{
|
{
|
||||||
modified = true;
|
modified = true;
|
||||||
World_ODE_RemoveFromEntity(world, ed);
|
World_ODE_RemoveFromEntity(world, ed);
|
||||||
ed->ode.ode_physics = true;
|
ed->rbe.physics = true;
|
||||||
VectorCopy(entmins, ed->ode.ode_mins);
|
VectorCopy(entmins, ed->rbe.mins);
|
||||||
VectorCopy(entmaxs, ed->ode.ode_maxs);
|
VectorCopy(entmaxs, ed->rbe.maxs);
|
||||||
ed->ode.ode_mass = massval;
|
ed->rbe.mass = massval;
|
||||||
ed->ode.ode_modelindex = modelindex;
|
ed->rbe.modelindex = modelindex;
|
||||||
VectorAvg(entmins, entmaxs, geomcenter);
|
VectorAvg(entmins, entmaxs, geomcenter);
|
||||||
ed->ode.ode_movelimit = min(geomsize[0], min(geomsize[1], geomsize[2]));
|
ed->rbe.movelimit = min(geomsize[0], min(geomsize[1], geomsize[2]));
|
||||||
|
|
||||||
if (massval * geomsize[0] * geomsize[1] * geomsize[2] == 0)
|
if (massval * geomsize[0] * geomsize[1] * geomsize[2] == 0)
|
||||||
{
|
{
|
||||||
|
@ -2135,37 +2135,37 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
switch(geomtype)
|
switch(geomtype)
|
||||||
{
|
{
|
||||||
case GEOMTYPE_TRIMESH:
|
case GEOMTYPE_TRIMESH:
|
||||||
Matrix4x4_Identity(ed->ode.ode_offsetmatrix);
|
Matrix4x4_Identity(ed->rbe.offsetmatrix);
|
||||||
ed->ode.ode_geom = NULL;
|
ed->rbe.body.geom = NULL;
|
||||||
if (!model)
|
if (!model)
|
||||||
{
|
{
|
||||||
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
|
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_ODE_RemoveFromEntity(world, ed);
|
World_ODE_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
|
if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
|
||||||
{
|
{
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_ODE_RemoveFromEntity(world, ed);
|
World_ODE_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
Matrix4x4_RM_CreateTranslate(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
||||||
// now create the geom
|
// now create the geom
|
||||||
dataID = dGeomTriMeshDataCreate();
|
dataID = dGeomTriMeshDataCreate();
|
||||||
dGeomTriMeshDataBuildSingle(dataID, (void*)ed->ode.ode_vertex3f, sizeof(float[3]), ed->ode.ode_numvertices, ed->ode.ode_element3i, ed->ode.ode_numtriangles*3, sizeof(int[3]));
|
dGeomTriMeshDataBuildSingle(dataID, (void*)ed->rbe.vertex3f, sizeof(float[3]), ed->rbe.numvertices, ed->rbe.element3i, ed->rbe.numtriangles*3, sizeof(int[3]));
|
||||||
ed->ode.ode_geom = (void *)dCreateTriMesh(ctx->space, dataID, NULL, NULL, NULL);
|
ed->rbe.body.geom = (void *)dCreateTriMesh(ctx->space, dataID, NULL, NULL, NULL);
|
||||||
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
|
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
|
||||||
break;
|
break;
|
||||||
case GEOMTYPE_BOX:
|
case GEOMTYPE_BOX:
|
||||||
Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
Matrix4x4_RM_CreateTranslate(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
||||||
ed->ode.ode_geom = (void *)dCreateBox(ctx->space, geomsize[0], geomsize[1], geomsize[2]);
|
ed->rbe.body.geom = (void *)dCreateBox(ctx->space, geomsize[0], geomsize[1], geomsize[2]);
|
||||||
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
|
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
|
||||||
break;
|
break;
|
||||||
case GEOMTYPE_SPHERE:
|
case GEOMTYPE_SPHERE:
|
||||||
Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
Matrix4x4_RM_CreateTranslate(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
||||||
ed->ode.ode_geom = (void *)dCreateSphere(ctx->space, geomsize[0] * 0.5f);
|
ed->rbe.body.geom = (void *)dCreateSphere(ctx->space, geomsize[0] * 0.5f);
|
||||||
dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
|
dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
|
||||||
break;
|
break;
|
||||||
case GEOMTYPE_CAPSULE:
|
case GEOMTYPE_CAPSULE:
|
||||||
|
@ -2188,17 +2188,17 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
// transform to it
|
// transform to it
|
||||||
if (axisindex == 0)
|
if (axisindex == 0)
|
||||||
{
|
{
|
||||||
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
|
Matrix4x4_CM_ModelMatrix(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
|
||||||
radius = min(geomsize[1], geomsize[2]) * 0.5f;
|
radius = min(geomsize[1], geomsize[2]) * 0.5f;
|
||||||
}
|
}
|
||||||
else if (axisindex == 1)
|
else if (axisindex == 1)
|
||||||
{
|
{
|
||||||
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
|
Matrix4x4_CM_ModelMatrix(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
|
||||||
radius = min(geomsize[0], geomsize[2]) * 0.5f;
|
radius = min(geomsize[0], geomsize[2]) * 0.5f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
|
Matrix4x4_CM_ModelMatrix(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
|
||||||
radius = min(geomsize[0], geomsize[1]) * 0.5f;
|
radius = min(geomsize[0], geomsize[1]) * 0.5f;
|
||||||
}
|
}
|
||||||
length = geomsize[axisindex] - radius*2;
|
length = geomsize[axisindex] - radius*2;
|
||||||
|
@ -2210,7 +2210,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
// because we want to support more than one axisindex, we have to
|
// because we want to support more than one axisindex, we have to
|
||||||
// create a transform, and turn on its cleanup setting (which will
|
// create a transform, and turn on its cleanup setting (which will
|
||||||
// cause the child to be destroyed when it is destroyed)
|
// cause the child to be destroyed when it is destroyed)
|
||||||
ed->ode.ode_geom = (void *)dCreateCapsule(ctx->space, radius, length);
|
ed->rbe.body.geom = (void *)dCreateCapsule(ctx->space, radius, length);
|
||||||
dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length);
|
dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length);
|
||||||
break;
|
break;
|
||||||
case GEOMTYPE_CYLINDER:
|
case GEOMTYPE_CYLINDER:
|
||||||
|
@ -2233,17 +2233,17 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
// transform to it
|
// transform to it
|
||||||
if (axisindex == 0)
|
if (axisindex == 0)
|
||||||
{
|
{
|
||||||
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
|
Matrix4x4_CM_ModelMatrix(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
|
||||||
radius = min(geomsize[1], geomsize[2]) * 0.5f;
|
radius = min(geomsize[1], geomsize[2]) * 0.5f;
|
||||||
}
|
}
|
||||||
else if (axisindex == 1)
|
else if (axisindex == 1)
|
||||||
{
|
{
|
||||||
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
|
Matrix4x4_CM_ModelMatrix(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
|
||||||
radius = min(geomsize[0], geomsize[2]) * 0.5f;
|
radius = min(geomsize[0], geomsize[2]) * 0.5f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Matrix4x4_CM_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
|
Matrix4x4_CM_ModelMatrix(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
|
||||||
radius = min(geomsize[0], geomsize[1]) * 0.5f;
|
radius = min(geomsize[0], geomsize[1]) * 0.5f;
|
||||||
}
|
}
|
||||||
length = geomsize[axisindex] - radius*2;
|
length = geomsize[axisindex] - radius*2;
|
||||||
|
@ -2255,38 +2255,38 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
// because we want to support more than one axisindex, we have to
|
// because we want to support more than one axisindex, we have to
|
||||||
// create a transform, and turn on its cleanup setting (which will
|
// create a transform, and turn on its cleanup setting (which will
|
||||||
// cause the child to be destroyed when it is destroyed)
|
// cause the child to be destroyed when it is destroyed)
|
||||||
ed->ode.ode_geom = (void *)dCreateCylinder(ctx->space, radius, length);
|
ed->rbe.body.geom = (void *)dCreateCylinder(ctx->space, radius, length);
|
||||||
dMassSetCylinderTotal(&mass, massval, axisindex+1, radius, length);
|
dMassSetCylinderTotal(&mass, massval, axisindex+1, radius, length);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Sys_Errorf("World_ODE_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
|
Sys_Errorf("World_ODE_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
|
||||||
}
|
}
|
||||||
Matrix3x4_InvertTo4x4_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix);
|
Matrix3x4_InvertTo4x4_Simple(ed->rbe.offsetmatrix, ed->rbe.offsetimatrix);
|
||||||
ed->ode.ode_massbuf = BZ_Malloc(sizeof(dMass));
|
ed->rbe.massbuf = BZ_Malloc(sizeof(dMass));
|
||||||
memcpy(ed->ode.ode_massbuf, &mass, sizeof(dMass));
|
memcpy(ed->rbe.massbuf, &mass, sizeof(dMass));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ed->ode.ode_geom)
|
if(ed->rbe.body.geom)
|
||||||
dGeomSetData(ed->ode.ode_geom, (void*)ed);
|
dGeomSetData(ed->rbe.body.geom, (void*)ed);
|
||||||
if (movetype == MOVETYPE_PHYSICS && ed->ode.ode_geom)
|
if (movetype == MOVETYPE_PHYSICS && ed->rbe.body.geom)
|
||||||
{
|
{
|
||||||
if (ed->ode.ode_body == NULL)
|
if (ed->rbe.body.body == NULL)
|
||||||
{
|
{
|
||||||
ed->ode.ode_body = (void *)(body = dBodyCreate(ctx->dworld));
|
ed->rbe.body.body = (void *)(body = dBodyCreate(ctx->dworld));
|
||||||
dGeomSetBody(ed->ode.ode_geom, body);
|
dGeomSetBody(ed->rbe.body.geom, body);
|
||||||
dBodySetData(body, (void*)ed);
|
dBodySetData(body, (void*)ed);
|
||||||
dBodySetMass(body, (dMass *) ed->ode.ode_massbuf);
|
dBodySetMass(body, (dMass *) ed->rbe.massbuf);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ed->ode.ode_body != NULL)
|
if (ed->rbe.body.body != NULL)
|
||||||
{
|
{
|
||||||
if(ed->ode.ode_geom)
|
if(ed->rbe.body.geom)
|
||||||
dGeomSetBody(ed->ode.ode_geom, 0);
|
dGeomSetBody(ed->rbe.body.geom, 0);
|
||||||
dBodyDestroy((dBodyID) ed->ode.ode_body);
|
dBodyDestroy((dBodyID) ed->rbe.body.body);
|
||||||
ed->ode.ode_body = NULL;
|
ed->rbe.body.body = NULL;
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2371,16 +2371,16 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the qc edited any position data
|
// check if the qc edited any position data
|
||||||
if (!VectorCompare(origin, ed->ode.ode_origin)
|
if (!VectorCompare(origin, ed->rbe.origin)
|
||||||
|| !VectorCompare(velocity, ed->ode.ode_velocity)
|
|| !VectorCompare(velocity, ed->rbe.velocity)
|
||||||
|| !VectorCompare(angles, ed->ode.ode_angles)
|
|| !VectorCompare(angles, ed->rbe.angles)
|
||||||
|| !VectorCompare(avelocity, ed->ode.ode_avelocity)
|
|| !VectorCompare(avelocity, ed->rbe.avelocity)
|
||||||
|| gravity != ed->ode.ode_gravity)
|
|| gravity != ed->rbe.gravity)
|
||||||
modified = true;
|
modified = true;
|
||||||
|
|
||||||
// store the qc values into the physics engine
|
// store the qc values into the physics engine
|
||||||
body = ed->ode.ode_body;
|
body = ed->rbe.body.body;
|
||||||
if (modified && ed->ode.ode_geom)
|
if (modified && ed->rbe.body.geom)
|
||||||
{
|
{
|
||||||
dVector3 r[3];
|
dVector3 r[3];
|
||||||
float entitymatrix[16];
|
float entitymatrix[16];
|
||||||
|
@ -2388,27 +2388,27 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
Con_Printf("entity %i got changed by QC\n", (int) (ed - prog->edicts));
|
Con_Printf("entity %i got changed by QC\n", (int) (ed - prog->edicts));
|
||||||
if(!VectorCompare(origin, ed->ode.ode_origin))
|
if(!VectorCompare(origin, ed->rbe.origin))
|
||||||
Con_Printf(" origin: %f %f %f -> %f %f %f\n", ed->ode.ode_origin[0], ed->ode.ode_origin[1], ed->ode.ode_origin[2], origin[0], origin[1], origin[2]);
|
Con_Printf(" origin: %f %f %f -> %f %f %f\n", ed->rbe.origin[0], ed->rbe.origin[1], ed->rbe.origin[2], origin[0], origin[1], origin[2]);
|
||||||
if(!VectorCompare(velocity, ed->ode.ode_velocity))
|
if(!VectorCompare(velocity, ed->rbe.velocity))
|
||||||
Con_Printf(" velocity: %f %f %f -> %f %f %f\n", ed->ode.ode_velocity[0], ed->ode.ode_velocity[1], ed->ode.ode_velocity[2], velocity[0], velocity[1], velocity[2]);
|
Con_Printf(" velocity: %f %f %f -> %f %f %f\n", ed->rbe.velocity[0], ed->rbe.velocity[1], ed->rbe.velocity[2], velocity[0], velocity[1], velocity[2]);
|
||||||
if(!VectorCompare(angles, ed->ode.ode_angles))
|
if(!VectorCompare(angles, ed->rbe.angles))
|
||||||
Con_Printf(" angles: %f %f %f -> %f %f %f\n", ed->ode.ode_angles[0], ed->ode.ode_angles[1], ed->ode.ode_angles[2], angles[0], angles[1], angles[2]);
|
Con_Printf(" angles: %f %f %f -> %f %f %f\n", ed->rbe.angles[0], ed->rbe.angles[1], ed->rbe.angles[2], angles[0], angles[1], angles[2]);
|
||||||
if(!VectorCompare(avelocity, ed->ode.ode_avelocity))
|
if(!VectorCompare(avelocity, ed->rbe.avelocity))
|
||||||
Con_Printf(" avelocity: %f %f %f -> %f %f %f\n", ed->ode.ode_avelocity[0], ed->ode.ode_avelocity[1], ed->ode.ode_avelocity[2], avelocity[0], avelocity[1], avelocity[2]);
|
Con_Printf(" avelocity: %f %f %f -> %f %f %f\n", ed->rbe.avelocity[0], ed->rbe.avelocity[1], ed->rbe.avelocity[2], avelocity[0], avelocity[1], avelocity[2]);
|
||||||
if(gravity != ed->ode.ode_gravity)
|
if(gravity != ed->rbe.gravity)
|
||||||
Con_Printf(" gravity: %i -> %i\n", ed->ide.ode_gravity, gravity);
|
Con_Printf(" gravity: %i -> %i\n", ed->ide.ode_gravity, gravity);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// values for BodyFromEntity to check if the qc modified anything later
|
// values for BodyFromEntity to check if the qc modified anything later
|
||||||
VectorCopy(origin, ed->ode.ode_origin);
|
VectorCopy(origin, ed->rbe.origin);
|
||||||
VectorCopy(velocity, ed->ode.ode_velocity);
|
VectorCopy(velocity, ed->rbe.velocity);
|
||||||
VectorCopy(angles, ed->ode.ode_angles);
|
VectorCopy(angles, ed->rbe.angles);
|
||||||
VectorCopy(avelocity, ed->ode.ode_avelocity);
|
VectorCopy(avelocity, ed->rbe.avelocity);
|
||||||
ed->ode.ode_gravity = gravity;
|
ed->rbe.gravity = gravity;
|
||||||
|
|
||||||
Matrix4x4_RM_FromVectors(entitymatrix, forward, left, up, origin);
|
Matrix4x4_RM_FromVectors(entitymatrix, forward, left, up, origin);
|
||||||
Matrix4_Multiply(ed->ode.ode_offsetmatrix, entitymatrix, bodymatrix);
|
Matrix4_Multiply(ed->rbe.offsetmatrix, entitymatrix, bodymatrix);
|
||||||
Matrix3x4_RM_ToVectors(bodymatrix, forward, left, up, origin);
|
Matrix3x4_RM_ToVectors(bodymatrix, forward, left, up, origin);
|
||||||
r[0][0] = forward[0];
|
r[0][0] = forward[0];
|
||||||
r[1][0] = forward[1];
|
r[1][0] = forward[1];
|
||||||
|
@ -2423,7 +2423,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
{
|
{
|
||||||
if(movetype == MOVETYPE_PHYSICS)
|
if(movetype == MOVETYPE_PHYSICS)
|
||||||
{
|
{
|
||||||
dGeomSetBody(ed->ode.ode_geom, body);
|
dGeomSetBody(ed->rbe.body.geom, body);
|
||||||
dBodySetPosition(body, origin[0], origin[1], origin[2]);
|
dBodySetPosition(body, origin[0], origin[1], origin[2]);
|
||||||
dBodySetRotation(body, r[0]);
|
dBodySetRotation(body, r[0]);
|
||||||
dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
|
dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
|
||||||
|
@ -2432,21 +2432,21 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dGeomSetBody(ed->ode.ode_geom, body);
|
dGeomSetBody(ed->rbe.body.geom, body);
|
||||||
dBodySetPosition(body, origin[0], origin[1], origin[2]);
|
dBodySetPosition(body, origin[0], origin[1], origin[2]);
|
||||||
dBodySetRotation(body, r[0]);
|
dBodySetRotation(body, r[0]);
|
||||||
dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
|
dBodySetLinearVel(body, velocity[0], velocity[1], velocity[2]);
|
||||||
dBodySetAngularVel(body, spinvelocity[0], spinvelocity[1], spinvelocity[2]);
|
dBodySetAngularVel(body, spinvelocity[0], spinvelocity[1], spinvelocity[2]);
|
||||||
dBodySetGravityMode(body, gravity);
|
dBodySetGravityMode(body, gravity);
|
||||||
dGeomSetBody(ed->ode.ode_geom, 0);
|
dGeomSetBody(ed->rbe.body.geom, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no body... then let's adjust the parameters of the geom directly
|
// no body... then let's adjust the parameters of the geom directly
|
||||||
dGeomSetBody(ed->ode.ode_geom, 0); // just in case we previously HAD a body (which should never happen)
|
dGeomSetBody(ed->rbe.body.geom, 0); // just in case we previously HAD a body (which should never happen)
|
||||||
dGeomSetPosition(ed->ode.ode_geom, origin[0], origin[1], origin[2]);
|
dGeomSetPosition(ed->rbe.body.geom, origin[0], origin[1], origin[2]);
|
||||||
dGeomSetRotation(ed->ode.ode_geom, r[0]);
|
dGeomSetRotation(ed->rbe.body.geom, r[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2527,7 +2527,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
|
||||||
//ragdolls don't make contact with the bbox of the doll entity
|
//ragdolls don't make contact with the bbox of the doll entity
|
||||||
//the origional entity should probably not be solid anyway.
|
//the origional entity should probably not be solid anyway.
|
||||||
//these bodies should probably not collide against bboxes of other entities with ragdolls either, but meh.
|
//these bodies should probably not collide against bboxes of other entities with ragdolls either, but meh.
|
||||||
if (ed1->ode.ode_body == b1 || ed2->ode.ode_body == b2)
|
if (ed1->rbe.body.body == b1 || ed2->rbe.body.body == b2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!ed1 || ED_ISFREE(ed1))
|
if(!ed1 || ED_ISFREE(ed1))
|
||||||
|
@ -2791,25 +2791,25 @@ static void World_ODE_RunCmd(world_t *world, rbecommandqueue_t *cmd)
|
||||||
switch(cmd->command)
|
switch(cmd->command)
|
||||||
{
|
{
|
||||||
case RBECMD_ENABLE:
|
case RBECMD_ENABLE:
|
||||||
if (cmd->edict->ode.ode_body)
|
if (cmd->edict->rbe.body.body)
|
||||||
dBodyEnable(cmd->edict->ode.ode_body);
|
dBodyEnable(cmd->edict->rbe.body.body);
|
||||||
break;
|
break;
|
||||||
case RBECMD_DISABLE:
|
case RBECMD_DISABLE:
|
||||||
if (cmd->edict->ode.ode_body)
|
if (cmd->edict->rbe.body.body)
|
||||||
dBodyDisable(cmd->edict->ode.ode_body);
|
dBodyDisable(cmd->edict->rbe.body.body);
|
||||||
break;
|
break;
|
||||||
case RBECMD_FORCE:
|
case RBECMD_FORCE:
|
||||||
if (cmd->edict->ode.ode_body)
|
if (cmd->edict->rbe.body.body)
|
||||||
{
|
{
|
||||||
dBodyEnable(cmd->edict->ode.ode_body);
|
dBodyEnable(cmd->edict->rbe.body.body);
|
||||||
dBodyAddForceAtPos(cmd->edict->ode.ode_body, cmd->v1[0], cmd->v1[1], cmd->v1[2], cmd->v2[0], cmd->v2[1], cmd->v2[2]);
|
dBodyAddForceAtPos(cmd->edict->rbe.body.body, cmd->v1[0], cmd->v1[1], cmd->v1[2], cmd->v2[0], cmd->v2[1], cmd->v2[2]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RBECMD_TORQUE:
|
case RBECMD_TORQUE:
|
||||||
if (cmd->edict->ode.ode_body)
|
if (cmd->edict->rbe.body.body)
|
||||||
{
|
{
|
||||||
dBodyEnable(cmd->edict->ode.ode_body);
|
dBodyEnable(cmd->edict->rbe.body.body);
|
||||||
dBodyAddTorque(cmd->edict->ode.ode_body, cmd->v1[0], cmd->v1[1], cmd->v1[2]);
|
dBodyAddTorque(cmd->edict->rbe.body.body, cmd->v1[0], cmd->v1[1], cmd->v1[2]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,9 @@ cvar_t fs_gamename = CVARAFD("com_fullgamename", NULL, "fs_gamename", CVAR_NOSET
|
||||||
cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The protocol game name used for dpmaster queries. For compatibility with DP, you can set this to 'DarkPlaces-Quake' in order to be listed in DP's master server, and to list DP servers.");
|
cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The protocol game name used for dpmaster queries. For compatibility with DP, you can set this to 'DarkPlaces-Quake' in order to be listed in DP's master server, and to list DP servers.");
|
||||||
cvar_t com_protocolversion = CVARAD("com_protocolversion", "3", NULL, "The protocol version used for dpmaster queries."); //3 by default, for compat with DP/NQ, even if our QW protocol uses different versions entirely. really it only matters for master servers.
|
cvar_t com_protocolversion = CVARAD("com_protocolversion", "3", NULL, "The protocol version used for dpmaster queries."); //3 by default, for compat with DP/NQ, even if our QW protocol uses different versions entirely. really it only matters for master servers.
|
||||||
cvar_t com_parseutf8 = CVARD("com_parseutf8", "1", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
|
cvar_t com_parseutf8 = CVARD("com_parseutf8", "1", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
|
||||||
|
#ifndef NOLEGACY
|
||||||
cvar_t com_parseezquake = CVARD("com_parseezquake", "0", "Treat chevron chars from configs as a per-character flag. You should use this only for compat with nquake's configs.");
|
cvar_t com_parseezquake = CVARD("com_parseezquake", "0", "Treat chevron chars from configs as a per-character flag. You should use this only for compat with nquake's configs.");
|
||||||
|
#endif
|
||||||
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
|
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
|
||||||
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.\n");
|
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.\n");
|
||||||
cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
|
cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
|
||||||
|
@ -135,7 +137,9 @@ void COM_Locate_f (void);
|
||||||
#define PAK0_COUNT 339
|
#define PAK0_COUNT 339
|
||||||
#define PAK0_CRC 52883
|
#define PAK0_CRC 52883
|
||||||
|
|
||||||
qboolean standard_quake = true, rogue, hipnotic;
|
#ifdef NQPROT
|
||||||
|
qboolean standard_quake = true; //unfortunately, the vanilla NQ protocol(and 666) subtly changes when -rogue or -hipnotic are used (and by extension -quoth). QW/FTE protocols don't not need to care, but compat...
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -3239,13 +3243,13 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
||||||
conchar_t *oldout = out;
|
conchar_t *oldout = out;
|
||||||
#ifndef NOLEGACY
|
#ifndef NOLEGACY
|
||||||
extern cvar_t dpcompat_console;
|
extern cvar_t dpcompat_console;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (flags & PFS_EZQUAKEMARKUP)
|
if (flags & PFS_EZQUAKEMARKUP)
|
||||||
{
|
{
|
||||||
ezquakemess = true;
|
ezquakemess = true;
|
||||||
utf8 = 0;
|
utf8 = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (flags & PFS_FORCEUTF8)
|
if (flags & PFS_FORCEUTF8)
|
||||||
utf8 = 2;
|
utf8 = 2;
|
||||||
|
|
||||||
|
@ -3970,7 +3974,9 @@ skipwhite:
|
||||||
//same as COM_Parse, but parses two quotes next to each other as a single quote as part of the string
|
//same as COM_Parse, but parses two quotes next to each other as a single quote as part of the string
|
||||||
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize)
|
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize)
|
||||||
{
|
{
|
||||||
|
#ifndef NOLEGACY
|
||||||
extern cvar_t dpcompat_console;
|
extern cvar_t dpcompat_console;
|
||||||
|
#endif
|
||||||
int c;
|
int c;
|
||||||
int len;
|
int len;
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -4038,6 +4044,7 @@ skipwhite:
|
||||||
if (c == '\"')
|
if (c == '\"')
|
||||||
{
|
{
|
||||||
data++;
|
data++;
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (dpcompat_console.ival)
|
if (dpcompat_console.ival)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -4066,6 +4073,7 @@ skipwhite:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -4330,7 +4338,11 @@ skipwhite:
|
||||||
|
|
||||||
const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean omitquotes)
|
const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean omitquotes)
|
||||||
{
|
{
|
||||||
|
#ifndef NOLEGACY
|
||||||
extern cvar_t dpcompat_console;
|
extern cvar_t dpcompat_console;
|
||||||
|
#else
|
||||||
|
static const cvar_t dpcompat_console = {0};
|
||||||
|
#endif
|
||||||
const char *result = buf;
|
const char *result = buf;
|
||||||
if (strchr(string, '\r') || strchr(string, '\n') || (!dpcompat_console.ival && strchr(string, '\"')))
|
if (strchr(string, '\r') || strchr(string, '\n') || (!dpcompat_console.ival && strchr(string, '\"')))
|
||||||
{
|
{
|
||||||
|
@ -5713,7 +5725,9 @@ void COM_Init (void)
|
||||||
Cvar_Register (&gameversion_max, "Gamecode");
|
Cvar_Register (&gameversion_max, "Gamecode");
|
||||||
Cvar_Register (&com_nogamedirnativecode, "Gamecode");
|
Cvar_Register (&com_nogamedirnativecode, "Gamecode");
|
||||||
Cvar_Register (&com_parseutf8, "Internationalisation");
|
Cvar_Register (&com_parseutf8, "Internationalisation");
|
||||||
|
#ifndef NOLEGACY
|
||||||
Cvar_Register (&com_parseezquake, NULL);
|
Cvar_Register (&com_parseezquake, NULL);
|
||||||
|
#endif
|
||||||
Cvar_Register (&com_highlightcolor, "Internationalisation");
|
Cvar_Register (&com_highlightcolor, "Internationalisation");
|
||||||
com_parseutf8.ival = 1;
|
com_parseutf8.ival = 1;
|
||||||
|
|
||||||
|
|
|
@ -397,7 +397,9 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q
|
||||||
#define PFS_KEEPMARKUP 1 //leave markup in the final string (but do parse it)
|
#define PFS_KEEPMARKUP 1 //leave markup in the final string (but do parse it)
|
||||||
#define PFS_FORCEUTF8 2 //force utf-8 decoding
|
#define PFS_FORCEUTF8 2 //force utf-8 decoding
|
||||||
#define PFS_NOMARKUP 4 //strip markup completely
|
#define PFS_NOMARKUP 4 //strip markup completely
|
||||||
|
#ifndef NOLEGACY
|
||||||
#define PFS_EZQUAKEMARKUP 8 //aim for compat with ezquake instead of q3 compat
|
#define PFS_EZQUAKEMARKUP 8 //aim for compat with ezquake instead of q3 compat
|
||||||
|
#endif
|
||||||
#define PFS_CENTERED 16 //flag used by console prints (text should remain centered)
|
#define PFS_CENTERED 16 //flag used by console prints (text should remain centered)
|
||||||
#define PFS_NONOTIFY 32 //flag used by console prints (text won't be visible other than by looking at the console)
|
#define PFS_NONOTIFY 32 //flag used by console prints (text won't be visible other than by looking at the console)
|
||||||
conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, int keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator
|
conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, int keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator
|
||||||
|
|
|
@ -175,6 +175,7 @@ char *Cvar_FlagToName(int flag)
|
||||||
#define CLF_LATCHES 0x20
|
#define CLF_LATCHES 0x20
|
||||||
#define CLF_FLAGS 0x40
|
#define CLF_FLAGS 0x40
|
||||||
#define CLF_FLAGMASK 0x80
|
#define CLF_FLAGMASK 0x80
|
||||||
|
#define CLF_CHANGEDONLY 0x100
|
||||||
void Cvar_List_f (void)
|
void Cvar_List_f (void)
|
||||||
{
|
{
|
||||||
cvar_group_t *grp;
|
cvar_group_t *grp;
|
||||||
|
@ -186,6 +187,7 @@ void Cvar_List_f (void)
|
||||||
static char *cvarlist_help =
|
static char *cvarlist_help =
|
||||||
"cvarlist list all cvars matching given parameters\n"
|
"cvarlist list all cvars matching given parameters\n"
|
||||||
"Syntax: cvarlist [-FLdhlrv] [-f flag] [-g group] [cvar]\n"
|
"Syntax: cvarlist [-FLdhlrv] [-f flag] [-g group] [cvar]\n"
|
||||||
|
" -c includes only the cvars that have been changed from their defaults\n"
|
||||||
" -F shows cvar flags\n"
|
" -F shows cvar flags\n"
|
||||||
" -L shows latched values\n"
|
" -L shows latched values\n"
|
||||||
" -a shows cvar alternate names\n"
|
" -a shows cvar alternate names\n"
|
||||||
|
@ -225,6 +227,9 @@ void Cvar_List_f (void)
|
||||||
|
|
||||||
gsearch = Cmd_Argv(i);
|
gsearch = Cmd_Argv(i);
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
listflags |= CLF_CHANGEDONLY;
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
listflags |= CLF_ALTNAME;
|
listflags |= CLF_ALTNAME;
|
||||||
break;
|
break;
|
||||||
|
@ -358,6 +363,9 @@ showhelp:
|
||||||
if ((listflags & CLF_FLAGMASK) && !(cmd->flags & cvarflags))
|
if ((listflags & CLF_FLAGMASK) && !(cmd->flags & cvarflags))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if ((listflags & CLF_CHANGEDONLY) && cmd->defaultstr && !strcmp(cmd->string, cmd->defaultstr))
|
||||||
|
continue;
|
||||||
|
|
||||||
// print cvar list header
|
// print cvar list header
|
||||||
if (!(listflags & CLF_RAW) && !num)
|
if (!(listflags & CLF_RAW) && !num)
|
||||||
Con_TPrintf("CVar list:\n");
|
Con_TPrintf("CVar list:\n");
|
||||||
|
|
|
@ -3683,6 +3683,9 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
i = COM_CheckNextParm ("-basepack", i);
|
i = COM_CheckNextParm ("-basepack", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NQPROT
|
||||||
|
standard_quake = true;
|
||||||
|
#endif
|
||||||
for (i = 0; i < sizeof(fs_manifest->gamepath) / sizeof(fs_manifest->gamepath[0]); i++)
|
for (i = 0; i < sizeof(fs_manifest->gamepath) / sizeof(fs_manifest->gamepath[0]); i++)
|
||||||
{
|
{
|
||||||
char *dir = fs_manifest->gamepath[i].path;
|
char *dir = fs_manifest->gamepath[i].path;
|
||||||
|
@ -3697,12 +3700,20 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Q_strncasecmp(dir, "downloads", 9))
|
//some gamedirs should never be used...
|
||||||
|
if (!Q_strncasecmp(dir, "downloads", 9) || !Q_strncasecmp(dir, "docs", 4) || !Q_strncasecmp(dir, "help", 4))
|
||||||
{
|
{
|
||||||
Con_Printf ("Gamedir should not be \"%s\"\n", dir);
|
Con_Printf ("Gamedir should not be \"%s\"\n", dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NQPROT
|
||||||
|
//vanilla NQ uses a slightly different protocol when started with -rogue or -hipnotic (and by extension -quoth).
|
||||||
|
//QW+FTE protocols don't care so we can get away with being a little loose here
|
||||||
|
if (!strcmp(dir, "rogue") || !strcmp(dir, "hipnotic") || !strcmp(dir, "quoth"))
|
||||||
|
standard_quake = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
//paths equal to '*' actually result in loading packages without an actual gamedir. note that this does not imply that we can write anything.
|
//paths equal to '*' actually result in loading packages without an actual gamedir. note that this does not imply that we can write anything.
|
||||||
if (!strcmp(dir, "*"))
|
if (!strcmp(dir, "*"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2555,6 +2555,28 @@ static qboolean CModQ3_LoadFogs (model_t *mod, qbyte *mod_base, lump_t *l)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texid_t *Mod_CubemapForOrigin(model_t *wmodel, vec3_t org)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
menvmap_t *e;
|
||||||
|
float bestdist = FLT_MAX, dist;
|
||||||
|
texid_t *ret = NULL;
|
||||||
|
vec3_t move;
|
||||||
|
if (!wmodel || wmodel->loadstate != MLS_LOADED)
|
||||||
|
return NULL;
|
||||||
|
for ( i=0 , e=wmodel->envmaps ; i<wmodel->numenvmaps ; i++, e++)
|
||||||
|
{
|
||||||
|
VectorSubtract(org, e->origin, move);
|
||||||
|
dist = DotProduct(move,move);
|
||||||
|
if (bestdist > dist)
|
||||||
|
{
|
||||||
|
bestdist = dist;
|
||||||
|
ret = e->image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org)
|
mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
|
@ -34,7 +34,7 @@ struct wedict_s
|
||||||
int solidsize;
|
int solidsize;
|
||||||
|
|
||||||
#ifdef USERBE
|
#ifdef USERBE
|
||||||
entityode_t ode;
|
entityrbe_t rbe;
|
||||||
#endif
|
#endif
|
||||||
/*the above is shared with ssqc*/
|
/*the above is shared with ssqc*/
|
||||||
};
|
};
|
||||||
|
@ -289,6 +289,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
||||||
void skel_dodelete(world_t *world);
|
void skel_dodelete(world_t *world);
|
||||||
void skel_reset(world_t *world);
|
void skel_reset(world_t *world);
|
||||||
void skel_reload(void);
|
void skel_reload(void);
|
||||||
|
void skel_updateentbounds();
|
||||||
#endif
|
#endif
|
||||||
void QCBUILTIN PF_physics_supported(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_physics_supported(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_physics_enable(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_physics_enable(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
@ -458,6 +459,7 @@ void QCBUILTIN PF_cl_sprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
||||||
void QCBUILTIN PF_cl_bprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_cl_bprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_cl_clientcount (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_cl_clientcount (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_cl_localsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_cl_localsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
void QCBUILTIN PF_cl_SendPacket(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
|
||||||
void search_close_progs(pubprogfuncs_t *prinst, qboolean complain);
|
void search_close_progs(pubprogfuncs_t *prinst, qboolean complain);
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,8 @@ typedef struct
|
||||||
void (QDECL *RagDestroyJoint)(struct world_s *world, rbejoint_t *joint);
|
void (QDECL *RagDestroyJoint)(struct world_s *world, rbejoint_t *joint);
|
||||||
void (QDECL *RunFrame)(struct world_s *world, double frametime, double gravity);
|
void (QDECL *RunFrame)(struct world_s *world, double frametime, double gravity);
|
||||||
void (QDECL *PushCommand)(struct world_s *world, rbecommandqueue_t *cmd);
|
void (QDECL *PushCommand)(struct world_s *world, rbecommandqueue_t *cmd);
|
||||||
|
// void (QDECL *ExpandBodyAABB)(struct world_s *world, rbebody_t *bodyptr, float *mins, float *maxs); //expands an aabb to include the size of the body.
|
||||||
|
// void (QDECL *Trace) ();
|
||||||
} rigidbodyengine_t;
|
} rigidbodyengine_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1536,6 +1536,10 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
|
||||||
ambientlight[0] = ambientlight[1] = ambientlight[2] = 1;
|
ambientlight[0] = ambientlight[1] = ambientlight[2] = 1;
|
||||||
shadelight[0] = shadelight[1] = shadelight[2] = 1;
|
shadelight[0] = shadelight[1] = shadelight[2] = 1;
|
||||||
|
|
||||||
|
VectorSet(e->light_dir, 1, 0, 0);
|
||||||
|
VectorClear(e->light_range);
|
||||||
|
VectorScale(shadelight, fb, e->light_avg);
|
||||||
|
|
||||||
e->light_known = 2;
|
e->light_known = 2;
|
||||||
return e->light_known-1;
|
return e->light_known-1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,7 @@ struct {
|
||||||
|
|
||||||
int lightmode;
|
int lightmode;
|
||||||
vec3_t lightorg;
|
vec3_t lightorg;
|
||||||
|
vec3_t lightdir;
|
||||||
vec3_t lightcolours;
|
vec3_t lightcolours;
|
||||||
vec3_t lightcolourscale;
|
vec3_t lightcolourscale;
|
||||||
float lightradius;
|
float lightradius;
|
||||||
|
@ -3669,6 +3670,14 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
|
||||||
qglUniform3fvARB(ph, 1, t2);
|
qglUniform3fvARB(ph, 1, t2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SP_LIGHTDIRECTION:
|
||||||
|
{
|
||||||
|
/*light position in model space*/
|
||||||
|
vec3_t t2;
|
||||||
|
Matrix4x4_CM_Transform3x3(shaderstate.modelmatrixinv, shaderstate.lightdir, t2);
|
||||||
|
qglUniform3fvARB(ph, 1, t2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SP_LIGHTCOLOURSCALE:
|
case SP_LIGHTCOLOURSCALE:
|
||||||
qglUniform3fvARB(ph, 1, shaderstate.lightcolourscale);
|
qglUniform3fvARB(ph, 1, shaderstate.lightcolourscale);
|
||||||
break;
|
break;
|
||||||
|
@ -3742,6 +3751,39 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
|
||||||
int perm;
|
int perm;
|
||||||
|
|
||||||
perm = 0;
|
perm = 0;
|
||||||
|
#if 0
|
||||||
|
if (shaderstate.sourcevbo->numbones)
|
||||||
|
perm |= PERMUTATION_SKELETAL;
|
||||||
|
#ifdef NONSKELETALMODELS
|
||||||
|
if (shaderstate.sourcevbo->coord2.gl.addr)
|
||||||
|
perm |= PERMUTATION_FRAMEBLEND;
|
||||||
|
#endif
|
||||||
|
if (TEXLOADED(shaderstate.curtexnums->bump))
|
||||||
|
perm |= PERMUTATION_BUMPMAP;
|
||||||
|
if (TEXLOADED(shaderstate.curtexnums->fullbright))
|
||||||
|
perm |= PERMUTATION_FULLBRIGHT;
|
||||||
|
if ((TEXLOADED(shaderstate.curtexnums->loweroverlay) || TEXLOADED(shaderstate.curtexnums->upperoverlay)))
|
||||||
|
perm |= PERMUTATION_UPPERLOWER;
|
||||||
|
if (r_refdef.globalfog.density)
|
||||||
|
perm |= PERMUTATION_FOG;
|
||||||
|
// if (p->permu[perm|PERMUTATION_DELUXE].handle.glsl.handle && TEXLOADED(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
|
||||||
|
// perm |= PERMUTATION_DELUXE;
|
||||||
|
if ((TEXLOADED(shaderstate.curtexnums->reflectcube) || TEXLOADED(shaderstate.curtexnums->reflectmask)))
|
||||||
|
perm |= PERMUTATION_REFLECTCUBEMASK;
|
||||||
|
#if MAXRLIGHTMAPS > 1
|
||||||
|
if (shaderstate.curbatch->lightmap[1] >= 0)
|
||||||
|
perm |= PERMUTATION_LIGHTSTYLES;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
perm &= p->supportedpermutations;
|
||||||
|
if (!p->permu[perm].h.loaded)
|
||||||
|
{
|
||||||
|
perm = 0;
|
||||||
|
if (!p->permu[perm].h.loaded)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
if (shaderstate.sourcevbo->numbones)
|
if (shaderstate.sourcevbo->numbones)
|
||||||
{
|
{
|
||||||
if (p->permu[perm|PERMUTATION_SKELETAL].h.loaded)
|
if (p->permu[perm|PERMUTATION_SKELETAL].h.loaded)
|
||||||
|
@ -3769,6 +3811,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
|
||||||
#if MAXRLIGHTMAPS > 1
|
#if MAXRLIGHTMAPS > 1
|
||||||
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded)
|
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded)
|
||||||
perm |= PERMUTATION_LIGHTSTYLES;
|
perm |= PERMUTATION_LIGHTSTYLES;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GL_SelectProgram(p->permu[perm].h.glsl.handle);
|
GL_SelectProgram(p->permu[perm].h.glsl.handle);
|
||||||
|
@ -4096,6 +4139,7 @@ qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, vec3_t axis[3], unsigned
|
||||||
/*simple info*/
|
/*simple info*/
|
||||||
shaderstate.lightradius = dl->radius;
|
shaderstate.lightradius = dl->radius;
|
||||||
VectorCopy(dl->origin, shaderstate.lightorg);
|
VectorCopy(dl->origin, shaderstate.lightorg);
|
||||||
|
VectorCopy(axis[0], shaderstate.lightdir);
|
||||||
VectorCopy(colour, shaderstate.lightcolours);
|
VectorCopy(colour, shaderstate.lightcolours);
|
||||||
#ifdef RTLIGHTS
|
#ifdef RTLIGHTS
|
||||||
VectorCopy(dl->lightcolourscales, shaderstate.lightcolourscale);
|
VectorCopy(dl->lightcolourscales, shaderstate.lightcolourscale);
|
||||||
|
@ -4113,13 +4157,17 @@ qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, vec3_t axis[3], unsigned
|
||||||
/*generate light projection information*/
|
/*generate light projection information*/
|
||||||
if (shaderstate.lightmode & LSHADER_ORTHO)
|
if (shaderstate.lightmode & LSHADER_ORTHO)
|
||||||
{
|
{
|
||||||
|
float view[16];
|
||||||
|
float proj[16];
|
||||||
float xmin = -dl->radius;
|
float xmin = -dl->radius;
|
||||||
float ymin = -dl->radius;
|
float ymin = -dl->radius;
|
||||||
float znear = -dl->radius;
|
float znear = -dl->radius;
|
||||||
float xmax = dl->radius;
|
float xmax = dl->radius;
|
||||||
float ymax = dl->radius;
|
float ymax = dl->radius;
|
||||||
float zfar = dl->radius;
|
float zfar = dl->radius;
|
||||||
Matrix4x4_CM_Orthographic(shaderstate.lightprojmatrix, xmin, xmax, ymax, ymin, znear, zfar);
|
Matrix4x4_CM_Orthographic(proj, xmin, xmax, ymax, ymin, znear, zfar);
|
||||||
|
Matrix4x4_CM_ModelViewMatrixFromAxis(view, axis[0], axis[2], axis[1], dl->origin);
|
||||||
|
Matrix4_Multiply(proj, view, shaderstate.lightprojmatrix);
|
||||||
// Matrix4x4_CM_LightMatrixFromAxis(shaderstate.lightprojmatrix, axis[0], axis[1], axis[2], dl->origin);
|
// Matrix4x4_CM_LightMatrixFromAxis(shaderstate.lightprojmatrix, axis[0], axis[1], axis[2], dl->origin);
|
||||||
}
|
}
|
||||||
else if (shaderstate.lightmode & LSHADER_SPOT)
|
else if (shaderstate.lightmode & LSHADER_SPOT)
|
||||||
|
@ -5058,74 +5106,17 @@ static void GLBE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
|
static qboolean GLBE_GenerateBatchTextures(batch_t *batch, shader_t *bs)
|
||||||
{
|
{
|
||||||
batch_t *batch;
|
|
||||||
shader_t *bs;
|
|
||||||
for (batch = sortlist; batch; batch = batch->next)
|
|
||||||
{
|
|
||||||
if (batch->meshes == batch->firstmesh)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batch->flags & BEF_NODLIGHT)
|
|
||||||
if (shaderstate.mode == BEM_LIGHT)
|
|
||||||
continue;
|
|
||||||
if (batch->flags & BEF_NOSHADOWS)
|
|
||||||
if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) //fixme: depthonly is not just shadows.
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//buildmeshes updates shaders and generates pose information for sufaces that need it.
|
|
||||||
//the shader flags checked *after* this call may be a performance issue if it generated lots of new mesh data.
|
|
||||||
//FIXME: should we assume that the batch's shader will have the same flags?
|
|
||||||
if (batch->buildmeshes)
|
|
||||||
{
|
|
||||||
TRACE(("GLBE_SubmitMeshesSortList: build\n"));
|
|
||||||
batch->buildmeshes(batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
bs = batch->shader;
|
|
||||||
|
|
||||||
TRACE(("GLBE_SubmitMeshesSortList: shader %s\n", bs->name));
|
|
||||||
|
|
||||||
//FIXME:!!
|
|
||||||
if (!bs)
|
|
||||||
{
|
|
||||||
Con_Printf("Shader not set...\n");
|
|
||||||
if (batch->texture)
|
|
||||||
bs = R_TextureAnimation(0, batch->texture)->shader;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bs->flags & SHADER_NODRAW) || !batch->meshes)
|
|
||||||
continue;
|
|
||||||
if (bs->flags & SHADER_NODLIGHT)
|
|
||||||
if (shaderstate.mode == BEM_LIGHT)
|
|
||||||
continue;
|
|
||||||
if (bs->flags & SHADER_NOSHADOWS)
|
|
||||||
if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) //fixme: depthonly is not just shadows.
|
|
||||||
continue;
|
|
||||||
if (bs->flags & SHADER_SKY)
|
|
||||||
{
|
|
||||||
if (shaderstate.mode == BEM_STANDARD || shaderstate.mode == BEM_DEPTHDARK)// || shaderstate.mode == BEM_WIREFRAME)
|
|
||||||
{
|
|
||||||
if (R_DrawSkyChain(batch))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (/*shaderstate.mode != BEM_FOG &&*/ shaderstate.mode != BEM_CREPUSCULAR && shaderstate.mode != BEM_WIREFRAME)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bs->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP)) && shaderstate.mode != BEM_WIREFRAME)
|
|
||||||
{
|
|
||||||
int oldfbo;
|
int oldfbo;
|
||||||
float oldil;
|
float oldil;
|
||||||
int oldbem;
|
int oldbem;
|
||||||
if (r_refdef.recurse == r_portalrecursion.ival || r_refdef.recurse == R_MAX_RECURSE)
|
if (r_refdef.recurse == r_portalrecursion.ival || r_refdef.recurse == R_MAX_RECURSE)
|
||||||
continue;
|
return false;
|
||||||
//these flags require rendering some view as an fbo
|
//these flags require rendering some view as an fbo
|
||||||
|
//(BEM_DEPTHDARK is used when lightmap scale is 0, but still shows any emissive stuff)
|
||||||
if (shaderstate.mode != BEM_STANDARD && shaderstate.mode != BEM_DEPTHDARK)
|
if (shaderstate.mode != BEM_STANDARD && shaderstate.mode != BEM_DEPTHDARK)
|
||||||
continue;
|
return false;
|
||||||
oldbem = shaderstate.mode;
|
oldbem = shaderstate.mode;
|
||||||
oldil = shaderstate.identitylighting;
|
oldil = shaderstate.identitylighting;
|
||||||
|
|
||||||
|
@ -5312,8 +5303,70 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
|
||||||
}
|
}
|
||||||
BE_SelectMode(oldbem);
|
BE_SelectMode(oldbem);
|
||||||
shaderstate.identitylighting = oldil;
|
shaderstate.identitylighting = oldil;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
|
||||||
|
{
|
||||||
|
batch_t *batch;
|
||||||
|
shader_t *bs;
|
||||||
|
for (batch = sortlist; batch; batch = batch->next)
|
||||||
|
{
|
||||||
|
if (batch->meshes == batch->firstmesh)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (batch->flags & BEF_NODLIGHT)
|
||||||
|
if (shaderstate.mode == BEM_LIGHT)
|
||||||
|
continue;
|
||||||
|
if (batch->flags & BEF_NOSHADOWS)
|
||||||
|
if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) //fixme: depthonly is not just shadows.
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//buildmeshes updates shaders and generates pose information for sufaces that need it.
|
||||||
|
//the shader flags checked *after* this call may be a performance issue if it generated lots of new mesh data.
|
||||||
|
//FIXME: should we assume that the batch's shader will have the same flags?
|
||||||
|
if (batch->buildmeshes)
|
||||||
|
{
|
||||||
|
TRACE(("GLBE_SubmitMeshesSortList: build\n"));
|
||||||
|
batch->buildmeshes(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bs = batch->shader;
|
||||||
|
|
||||||
|
TRACE(("GLBE_SubmitMeshesSortList: shader %s\n", bs->name));
|
||||||
|
|
||||||
|
//FIXME:!!
|
||||||
|
if (!bs)
|
||||||
|
{
|
||||||
|
Con_Printf("Shader not set...\n");
|
||||||
|
if (batch->texture)
|
||||||
|
bs = R_TextureAnimation(0, batch->texture)->shader;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bs->flags & SHADER_NODRAW) || !batch->meshes)
|
||||||
|
continue;
|
||||||
|
if (bs->flags & SHADER_NODLIGHT)
|
||||||
|
if (shaderstate.mode == BEM_LIGHT)
|
||||||
|
continue;
|
||||||
|
if (bs->flags & SHADER_NOSHADOWS)
|
||||||
|
if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) //fixme: depthonly is not just shadows.
|
||||||
|
continue;
|
||||||
|
if (bs->flags & SHADER_SKY)
|
||||||
|
{
|
||||||
|
if (shaderstate.mode == BEM_STANDARD || shaderstate.mode == BEM_DEPTHDARK)// || shaderstate.mode == BEM_WIREFRAME)
|
||||||
|
{
|
||||||
|
if (R_DrawSkyChain(batch))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (/*shaderstate.mode != BEM_FOG &&*/ shaderstate.mode != BEM_CREPUSCULAR && shaderstate.mode != BEM_WIREFRAME)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bs->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP)) && shaderstate.mode != BEM_WIREFRAME)
|
||||||
|
if (!GLBE_GenerateBatchTextures(batch, bs))
|
||||||
|
continue;
|
||||||
|
|
||||||
GLBE_SubmitBatch(batch);
|
GLBE_SubmitBatch(batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2718,7 +2718,8 @@ static int Mod_Batches_Generate(model_t *mod)
|
||||||
lbatch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) &&
|
lbatch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) &&
|
||||||
lbatch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) &&
|
lbatch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) &&
|
||||||
#endif
|
#endif
|
||||||
lbatch->fog == surf->fog))
|
lbatch->fog == surf->fog &&
|
||||||
|
lbatch->envmap == surf->envmap))
|
||||||
batch = lbatch;
|
batch = lbatch;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2735,7 +2736,8 @@ static int Mod_Batches_Generate(model_t *mod)
|
||||||
batch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) &&
|
batch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) &&
|
||||||
batch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) &&
|
batch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) &&
|
||||||
#endif
|
#endif
|
||||||
batch->fog == surf->fog)
|
batch->fog == surf->fog &&
|
||||||
|
batch->envmap == surf->envmap)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2772,6 +2774,7 @@ static int Mod_Batches_Generate(model_t *mod)
|
||||||
batch->next = mod->batches[sortid];
|
batch->next = mod->batches[sortid];
|
||||||
batch->ent = &r_worldentity;
|
batch->ent = &r_worldentity;
|
||||||
batch->fog = surf->fog;
|
batch->fog = surf->fog;
|
||||||
|
batch->envmap = surf->envmap;
|
||||||
Vector4Copy(plane, batch->plane);
|
Vector4Copy(plane, batch->plane);
|
||||||
|
|
||||||
mod->batches[sortid] = batch;
|
mod->batches[sortid] = batch;
|
||||||
|
@ -2938,7 +2941,7 @@ static void Mod_LightmapAllocSurf(lmalloc_t *lmallocator, msurface_t *surf, int
|
||||||
|
|
||||||
if (isDedicated ||
|
if (isDedicated ||
|
||||||
(surf->texinfo->texture->shader && !(surf->texinfo->texture->shader->flags & SHADER_HASLIGHTMAP)) || //fte
|
(surf->texinfo->texture->shader && !(surf->texinfo->texture->shader->flags & SHADER_HASLIGHTMAP)) || //fte
|
||||||
(surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) || //q1
|
(surf->flags & (SURF_DRAWSKY|SURF_DRAWTILED)) || //q1
|
||||||
(surf->texinfo->flags & TEX_SPECIAL) || //the original 'no lightmap'
|
(surf->texinfo->flags & TEX_SPECIAL) || //the original 'no lightmap'
|
||||||
(surf->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP)) || //q2 surfaces
|
(surf->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP)) || //q2 surfaces
|
||||||
smax > lmallocator->width || tmax > lmallocator->height || smax < 0 || tmax < 0) //bugs/bounds/etc
|
smax > lmallocator->width || tmax > lmallocator->height || smax < 0 || tmax < 0) //bugs/bounds/etc
|
||||||
|
@ -3683,8 +3686,18 @@ static qboolean Mod_LoadTexinfo (model_t *loadmodel, qbyte *mod_base, lump_t *l)
|
||||||
out->texture = r_notexture_mip; // texture not found
|
out->texture = r_notexture_mip; // texture not found
|
||||||
out->flags = 0;
|
out->flags = 0;
|
||||||
}
|
}
|
||||||
else if (!strncmp(out->texture->name, "scroll", 6) || ((*out->texture->name == '*' || *out->texture->name == '{' || *out->texture->name == '!') && !strncmp(out->texture->name+1, "scroll", 6)))
|
else
|
||||||
|
{
|
||||||
|
if (*out->texture->name == '*' || (*out->texture->name == '!' && loadmodel->fromgame == fg_halflife)) // turbulent
|
||||||
|
{
|
||||||
|
if (!(out->flags & TEX_SPECIAL) && !strchr(out->texture->name, '#'))
|
||||||
|
Q_strncatz(out->texture->name, "#LIT", sizeof(out->texture->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(out->texture->name, "scroll", 6) || ((*out->texture->name == '*' || *out->texture->name == '{' || *out->texture->name == '!') && !strncmp(out->texture->name+1, "scroll", 6)))
|
||||||
out->flags |= TI_FLOWING;
|
out->flags |= TI_FLOWING;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3896,15 +3909,18 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, l
|
||||||
out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
|
out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*out->texinfo->texture->name == '*' || (*out->texinfo->texture->name == '!' && loadmodel->fromgame == fg_halflife)) // turbulent
|
if (*out->texinfo->texture->name == '*' || (*out->texinfo->texture->name == '!' && loadmodel->fromgame == fg_halflife)) // turbulent
|
||||||
{
|
{
|
||||||
out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
|
out->flags |= SURF_DRAWTURB;
|
||||||
|
if (out->texinfo->flags & TEX_SPECIAL)
|
||||||
|
{
|
||||||
|
out->flags |= SURF_DRAWTILED;
|
||||||
for (i=0 ; i<2 ; i++)
|
for (i=0 ; i<2 ; i++)
|
||||||
{
|
{
|
||||||
out->extents[i] = 16384;
|
out->extents[i] = 16384;
|
||||||
out->texturemins[i] = -8192;
|
out->texturemins[i] = -8192;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ typedef struct batch_s
|
||||||
struct vbo_s *vbo;
|
struct vbo_s *vbo;
|
||||||
entity_t *ent; /*used for shader properties*/
|
entity_t *ent; /*used for shader properties*/
|
||||||
struct mfog_s *fog;
|
struct mfog_s *fog;
|
||||||
|
image_t *envmap;
|
||||||
|
|
||||||
short lightmap[MAXRLIGHTMAPS]; /*used for shader lightmap textures*/
|
short lightmap[MAXRLIGHTMAPS]; /*used for shader lightmap textures*/
|
||||||
unsigned char lmlightstyle[MAXRLIGHTMAPS];
|
unsigned char lmlightstyle[MAXRLIGHTMAPS];
|
||||||
|
@ -390,6 +391,14 @@ typedef struct mfog_s
|
||||||
mplane_t **planes;
|
mplane_t **planes;
|
||||||
} mfog_t;
|
} mfog_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vec3_t origin;
|
||||||
|
int cubesize; //pixels
|
||||||
|
|
||||||
|
texid_t *image;
|
||||||
|
} menvmap_t;
|
||||||
|
|
||||||
#define LMSHIFT_DEFAULT 4
|
#define LMSHIFT_DEFAULT 4
|
||||||
typedef struct msurface_s
|
typedef struct msurface_s
|
||||||
{
|
{
|
||||||
|
@ -405,6 +414,7 @@ typedef struct msurface_s
|
||||||
|
|
||||||
unsigned short light_s[MAXRLIGHTMAPS], light_t[MAXRLIGHTMAPS]; // gl lightmap coordinates
|
unsigned short light_s[MAXRLIGHTMAPS], light_t[MAXRLIGHTMAPS]; // gl lightmap coordinates
|
||||||
|
|
||||||
|
image_t *envmap;
|
||||||
mfog_t *fog;
|
mfog_t *fog;
|
||||||
mesh_t *mesh;
|
mesh_t *mesh;
|
||||||
|
|
||||||
|
@ -972,6 +982,8 @@ typedef struct model_s
|
||||||
q3lightgridinfo_t *lightgrid;
|
q3lightgridinfo_t *lightgrid;
|
||||||
mfog_t *fogs;
|
mfog_t *fogs;
|
||||||
int numfogs;
|
int numfogs;
|
||||||
|
menvmap_t *envmaps;
|
||||||
|
unsigned numenvmaps;
|
||||||
struct {unsigned int id; char *keyvals;} *entityinfo;
|
struct {unsigned int id; char *keyvals;} *entityinfo;
|
||||||
size_t numentityinfo;
|
size_t numentityinfo;
|
||||||
const char *entities_raw;
|
const char *entities_raw;
|
||||||
|
|
|
@ -736,15 +736,19 @@ void R_PushDlights (void)
|
||||||
#ifdef RTLIGHTS
|
#ifdef RTLIGHTS
|
||||||
qboolean R_ImportRTLights(const char *entlump)
|
qboolean R_ImportRTLights(const char *entlump)
|
||||||
{
|
{
|
||||||
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_NONE, LIGHTTYPE_SUN, LIGHTTYPE_MINUSXX} lighttype_t;
|
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_INFINITE, LIGHTTYPE_LOCALMIN, LIGHTTYPE_RECIPXX2, LIGHTTYPE_SUN} lighttype_t;
|
||||||
|
|
||||||
/*I'm using the DP code so I know I'll get the DP results*/
|
/*I'm using the DP code so I know I'll get the DP results*/
|
||||||
int entnum, style, islight, skin, pflags, n;
|
int entnum, style, islight, skin, pflags, n;
|
||||||
lighttype_t type;
|
lighttype_t type;
|
||||||
float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], colourscales[3], vec[4];
|
float origin[3], angles[3], mangle[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], colourscales[3], vec[4];
|
||||||
char key[256], value[8192];
|
char key[256], value[8192];
|
||||||
|
char targetname[256], target[256];
|
||||||
int nest;
|
int nest;
|
||||||
qboolean okay = false;
|
qboolean okay = false;
|
||||||
|
infobuf_t targets;
|
||||||
|
const char *lmp;
|
||||||
|
memset(&targets, 0, sizeof(targets));
|
||||||
|
|
||||||
//a quick note about tenebrae:
|
//a quick note about tenebrae:
|
||||||
//by default, tenebrae's rtlights come from the server via static entities, which is all fancy and posh and actually fairly nice... if all servers actually did it.
|
//by default, tenebrae's rtlights come from the server via static entities, which is all fancy and posh and actually fairly nice... if all servers actually did it.
|
||||||
|
@ -753,6 +757,7 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
//such lights are ONLY created if they're not near some other existing light (like a static entity one).
|
//such lights are ONLY created if they're not near some other existing light (like a static entity one).
|
||||||
//this can result in FTE having noticably more and bigger lights than tenebrae. shadowmapping doesn't help performance either.
|
//this can result in FTE having noticably more and bigger lights than tenebrae. shadowmapping doesn't help performance either.
|
||||||
|
|
||||||
|
//handle doom3's header
|
||||||
COM_Parse(entlump);
|
COM_Parse(entlump);
|
||||||
if (!strcmp(com_token, "Version"))
|
if (!strcmp(com_token, "Version"))
|
||||||
{
|
{
|
||||||
|
@ -760,6 +765,55 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
entlump = COM_Parse(entlump);
|
entlump = COM_Parse(entlump);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//find targetnames, and store their origins so that we can deal with spotlights.
|
||||||
|
for (lmp = entlump; ;)
|
||||||
|
{
|
||||||
|
lmp = COM_Parse(lmp);
|
||||||
|
if (com_token[0] != '{')
|
||||||
|
break;
|
||||||
|
|
||||||
|
*targetname = 0;
|
||||||
|
VectorClear(origin);
|
||||||
|
|
||||||
|
nest = 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
lmp = COM_ParseOut(lmp, key, sizeof(key));
|
||||||
|
if (!lmp)
|
||||||
|
break; // error
|
||||||
|
if (key[0] == '{')
|
||||||
|
{
|
||||||
|
nest++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key[0] == '}')
|
||||||
|
{
|
||||||
|
nest--;
|
||||||
|
if (!nest)
|
||||||
|
break; // end of entity
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nest!=1)
|
||||||
|
continue;
|
||||||
|
if (key[0] == '_')
|
||||||
|
memmove(key, key+1, strlen(key));
|
||||||
|
while (key[strlen(key)-1] == ' ') // remove trailing spaces
|
||||||
|
key[strlen(key)-1] = 0;
|
||||||
|
lmp = COM_ParseOut(lmp, value, sizeof(value));
|
||||||
|
if (!lmp)
|
||||||
|
break; // error
|
||||||
|
|
||||||
|
// now that we have the key pair worked out...
|
||||||
|
if (!strcmp("targetname", key))
|
||||||
|
Q_strncpyz(targetname, value, sizeof(targetname));
|
||||||
|
else if (!strcmp("origin", key))
|
||||||
|
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
|
||||||
|
}
|
||||||
|
//if we found an ent with a targetname and an origin, then record where it was.
|
||||||
|
if (*targetname && (origin[0] || origin[1] || origin[2]))
|
||||||
|
InfoBuf_SetStarKey(&targets, targetname, va("%f %f %f", origin[0], origin[1], origin[2]));
|
||||||
|
}
|
||||||
|
|
||||||
for (entnum = 0; ;entnum++)
|
for (entnum = 0; ;entnum++)
|
||||||
{
|
{
|
||||||
entlump = COM_Parse(entlump);
|
entlump = COM_Parse(entlump);
|
||||||
|
@ -770,11 +824,13 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
origin[0] = origin[1] = origin[2] = 0;
|
origin[0] = origin[1] = origin[2] = 0;
|
||||||
originhack[0] = originhack[1] = originhack[2] = 0;
|
originhack[0] = originhack[1] = originhack[2] = 0;
|
||||||
angles[0] = angles[1] = angles[2] = 0;
|
angles[0] = angles[1] = angles[2] = 0;
|
||||||
|
mangle[0] = mangle[1] = mangle[2] = 0;
|
||||||
color[0] = color[1] = color[2] = 1;
|
color[0] = color[1] = color[2] = 1;
|
||||||
light[0] = light[1] = light[2] = 1;light[3] = 300;
|
light[0] = light[1] = light[2] = 1;light[3] = 300;
|
||||||
overridecolor[0] = overridecolor[1] = overridecolor[2] = 1;
|
overridecolor[0] = overridecolor[1] = overridecolor[2] = 1;
|
||||||
fadescale = 1;
|
fadescale = 1;
|
||||||
lightscale = 1;
|
lightscale = 1;
|
||||||
|
*target = 0;
|
||||||
style = 0;
|
style = 0;
|
||||||
skin = 0;
|
skin = 0;
|
||||||
pflags = 0;
|
pflags = 0;
|
||||||
|
@ -837,14 +893,22 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
type = atoi(value);
|
type = atoi(value);
|
||||||
else if (!strcmp("origin", key))
|
else if (!strcmp("origin", key))
|
||||||
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
|
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
|
||||||
else if (!strcmp("angle", key))
|
else if (!strcmp("angle", key)) //orientation for cubemaps (or angle of spot lights)
|
||||||
angles[0] = 0, angles[1] = atof(value), angles[2] = 0;
|
angles[0] = 0, angles[1] = atof(value), angles[2] = 0;
|
||||||
else if (!strcmp("angles", key))
|
else if (!strcmp("mangle", key)) //orientation for cubemaps (or angle of spot lights)
|
||||||
|
{
|
||||||
|
sscanf(value, "%f %f %f", &mangle[1], &mangle[0], &mangle[2]); //FIXME: order is fucked.
|
||||||
|
mangle[0] = 360-mangle[0]; //FIXME: pitch is fucked too.
|
||||||
|
}
|
||||||
|
//_softangle -- the inner cone angle of a spotlight.
|
||||||
|
else if (!strcmp("angles", key)) //richer cubemap orientation.
|
||||||
sscanf(value, "%f %f %f", &angles[0], &angles[1], &angles[2]);
|
sscanf(value, "%f %f %f", &angles[0], &angles[1], &angles[2]);
|
||||||
else if (!strcmp("color", key))
|
else if (!strcmp("color", key))
|
||||||
sscanf(value, "%f %f %f", &color[0], &color[1], &color[2]);
|
sscanf(value, "%f %f %f", &color[0], &color[1], &color[2]);
|
||||||
else if (!strcmp("wait", key))
|
else if (!strcmp("wait", key))
|
||||||
fadescale = atof(value);
|
fadescale = atof(value);
|
||||||
|
else if (!strcmp("target", key))
|
||||||
|
Q_strncpyz(target, value, sizeof(target));
|
||||||
else if (!strcmp("classname", key))
|
else if (!strcmp("classname", key))
|
||||||
{
|
{
|
||||||
if (!strncmp(value, "light", 5))
|
if (!strncmp(value, "light", 5))
|
||||||
|
@ -989,32 +1053,55 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
color[0] = color[0] * light[0];
|
color[0] = color[0] * light[0];
|
||||||
color[1] = color[1] * light[1];
|
color[1] = color[1] * light[1];
|
||||||
color[2] = color[2] * light[2];
|
color[2] = color[2] * light[2];
|
||||||
|
#define CUTOFF (128.0/255)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case LIGHTTYPE_MINUSX:
|
case LIGHTTYPE_MINUSX:
|
||||||
break;
|
break;
|
||||||
case LIGHTTYPE_RECIPX:
|
case LIGHTTYPE_RECIPX:
|
||||||
|
#if 1
|
||||||
radius *= 2;
|
radius *= 2;
|
||||||
VectorScale(color, (1.0f / 16.0f), color);
|
// VectorScale(color, (1.0f / 16.0f), color);
|
||||||
|
#else
|
||||||
|
//light util uses something like: cutoff == light/((scaledist*fadescale*radius)/128)
|
||||||
|
//radius = light/(cutoff*128*scaledist*fadescale)
|
||||||
|
radius = lightscale*r_editlights_import_radius.value*256/(1*fadescale);
|
||||||
|
radius = min(radius, 300);
|
||||||
|
VectorScale(color, 255/light[3], color);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case LIGHTTYPE_RECIPXX:
|
case LIGHTTYPE_RECIPXX:
|
||||||
|
case LIGHTTYPE_RECIPXX2:
|
||||||
|
#if 1
|
||||||
radius *= 2;
|
radius *= 2;
|
||||||
VectorScale(color, (1.0f / 16.0f), color);
|
// VectorScale(color, (1.0f / 16.0f), color);
|
||||||
|
#else
|
||||||
|
//light util uses something like: cutoff == light/((scaledist*scaledist*fadescale*fadescale*radius*radius)/(128*128))
|
||||||
|
radius = lightscale*r_editlights_import_radius.value*sqrt(1/CUTOFF*128*128*1*1*fadescale*fadescale);
|
||||||
|
radius = min(radius, 300);
|
||||||
|
VectorScale(color, 255/light[3], color);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case LIGHTTYPE_NONE:
|
case LIGHTTYPE_INFINITE:
|
||||||
|
radius = FLT_MAX; //close enough
|
||||||
|
break;
|
||||||
|
case LIGHTTYPE_LOCALMIN: //can't support, treat like LIGHTTYPE_MINUSX
|
||||||
break;
|
break;
|
||||||
case LIGHTTYPE_SUN:
|
case LIGHTTYPE_SUN:
|
||||||
break;
|
break;
|
||||||
case LIGHTTYPE_MINUSXX:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (radius < 50) //some mappers insist on many tiny lights. such lights can usually get away with no shadows..
|
||||||
|
pflags |= PFLAGS_NOSHADOW;
|
||||||
|
|
||||||
VectorAdd(origin, originhack, origin);
|
VectorAdd(origin, originhack, origin);
|
||||||
if (radius >= 1 && !(cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, origin) & FTECONTENTS_SOLID))
|
if (radius >= 1 && !(cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, origin) & FTECONTENTS_SOLID))
|
||||||
{
|
{
|
||||||
dlight_t *dl = CL_AllocSlight();
|
dlight_t *dl = CL_AllocSlight();
|
||||||
if (!dl)
|
if (!dl)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
VectorCopy(origin, dl->origin);
|
VectorCopy(origin, dl->origin);
|
||||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||||
VectorInverse(dl->axis[1]);
|
VectorInverse(dl->axis[1]);
|
||||||
|
@ -1026,6 +1113,34 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
|
dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
|
||||||
dl->style = style+1;
|
dl->style = style+1;
|
||||||
VectorCopy(colourscales, dl->lightcolourscales);
|
VectorCopy(colourscales, dl->lightcolourscales);
|
||||||
|
|
||||||
|
//handle spotlights.
|
||||||
|
if (mangle[0] || mangle[1] || mangle[2])
|
||||||
|
{
|
||||||
|
dl->fov = angles[1];
|
||||||
|
if (!dl->fov) //default is 40, supposedly
|
||||||
|
dl->fov = 40;
|
||||||
|
|
||||||
|
AngleVectors(mangle, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||||
|
VectorInverse(dl->axis[1]);
|
||||||
|
}
|
||||||
|
else if (*target)
|
||||||
|
{
|
||||||
|
lmp = InfoBuf_ValueForKey(&targets, target);
|
||||||
|
if (*lmp)
|
||||||
|
{
|
||||||
|
dl->fov = angles[1];
|
||||||
|
if (!dl->fov) //default is 40, supposedly
|
||||||
|
dl->fov = 40;
|
||||||
|
sscanf(lmp, "%f %f %f", &angles[0], &angles[1], &angles[2]);
|
||||||
|
VectorSubtract(angles, origin, dl->axis[0]);
|
||||||
|
VectorNormalize(dl->axis[0]);
|
||||||
|
VectorVectors(dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||||
|
VectorInverse(dl->axis[1]);
|
||||||
|
//we don't have any control over the inner cone.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (skin >= 16)
|
if (skin >= 16)
|
||||||
R_LoadNumberedLightTexture(dl, skin);
|
R_LoadNumberedLightTexture(dl, skin);
|
||||||
|
|
||||||
|
@ -1033,6 +1148,8 @@ qboolean R_ImportRTLights(const char *entlump)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InfoBuf_Clear(&targets, true);
|
||||||
|
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2045,6 +2045,7 @@ struct shader_field_names_s shader_unif_names[] =
|
||||||
/**/{"l_lightradius", SP_LIGHTRADIUS}, //radius of the current rtlight
|
/**/{"l_lightradius", SP_LIGHTRADIUS}, //radius of the current rtlight
|
||||||
/**/{"l_lightcolour", SP_LIGHTCOLOUR}, //rgb values of the current rtlight
|
/**/{"l_lightcolour", SP_LIGHTCOLOUR}, //rgb values of the current rtlight
|
||||||
/**/{"l_lightposition", SP_LIGHTPOSITION}, //light position in modelspace
|
/**/{"l_lightposition", SP_LIGHTPOSITION}, //light position in modelspace
|
||||||
|
{"l_lightdirection", SP_LIGHTDIRECTION}, //light direction in modelspace (ortho lights only, instead of position)
|
||||||
/**/{"l_lightcolourscale", SP_LIGHTCOLOURSCALE},//ambient/diffuse/specular scalers
|
/**/{"l_lightcolourscale", SP_LIGHTCOLOURSCALE},//ambient/diffuse/specular scalers
|
||||||
/**/{"l_cubematrix", SP_LIGHTCUBEMATRIX},//matrix used to control the rtlight's cubemap projection
|
/**/{"l_cubematrix", SP_LIGHTCUBEMATRIX},//matrix used to control the rtlight's cubemap projection
|
||||||
/**/{"l_shadowmapproj", SP_LIGHTSHADOWMAPPROJ}, //compacted projection matrix for shadowmaps
|
/**/{"l_shadowmapproj", SP_LIGHTSHADOWMAPPROJ}, //compacted projection matrix for shadowmaps
|
||||||
|
@ -2181,167 +2182,6 @@ static void Shader_HLSL11ProgramName (shader_t *shader, shaderpass_t *pass, char
|
||||||
Shader_SLProgramName(shader,pass,ptr,QR_DIRECT3D11);
|
Shader_SLProgramName(shader,pass,ptr,QR_DIRECT3D11);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
Con_DPrintf("shader %s: 'param' no longer supported\n", shader->name);
|
|
||||||
#elif defined(GLQUAKE)
|
|
||||||
cvar_t *cv = NULL;
|
|
||||||
enum shaderprogparmtype_e parmtype = SP_BAD;
|
|
||||||
char *token;
|
|
||||||
qboolean silent = false;
|
|
||||||
char *forcename = NULL;
|
|
||||||
|
|
||||||
token = Shader_ParseString(ptr);
|
|
||||||
if (!Q_stricmp(token, "opt"))
|
|
||||||
{
|
|
||||||
silent = true;
|
|
||||||
token = Shader_ParseString(ptr);
|
|
||||||
}
|
|
||||||
if (!Q_stricmp(token, "texture"))
|
|
||||||
{
|
|
||||||
token = Shader_ParseString(ptr);
|
|
||||||
specialint = atoi(token);
|
|
||||||
parmtype = SP_TEXTURE;
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(token, "consti"))
|
|
||||||
{
|
|
||||||
token = Shader_ParseSensString(ptr);
|
|
||||||
specialint = atoi(token);
|
|
||||||
parmtype = SP_CONSTI;
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(token, "constf"))
|
|
||||||
{
|
|
||||||
token = Shader_ParseSensString(ptr);
|
|
||||||
specialfloat = atof(token);
|
|
||||||
parmtype = SP_CONSTF;
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(token, "cvari"))
|
|
||||||
{
|
|
||||||
token = Shader_ParseSensString(ptr);
|
|
||||||
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
|
|
||||||
if (!cv)
|
|
||||||
return;
|
|
||||||
parmtype = SP_CVARI;
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(token, "cvarf"))
|
|
||||||
{
|
|
||||||
token = Shader_ParseSensString(ptr);
|
|
||||||
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
|
|
||||||
if (!cv)
|
|
||||||
return;
|
|
||||||
parmtype = SP_CVARF;
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(token, "cvar3f"))
|
|
||||||
{
|
|
||||||
token = Shader_ParseSensString(ptr);
|
|
||||||
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
|
|
||||||
if (!cv)
|
|
||||||
return;
|
|
||||||
parmtype = SP_CVAR3F;
|
|
||||||
}
|
|
||||||
else if (!Q_stricmp(token, "time"))
|
|
||||||
parmtype = SP_E_TIME;
|
|
||||||
else if (!Q_stricmp(token, "eyepos"))
|
|
||||||
parmtype = SP_E_EYEPOS;
|
|
||||||
else if (!Q_stricmp(token, "entmatrix"))
|
|
||||||
parmtype = SP_M_MODEL;
|
|
||||||
else if (!Q_stricmp(token, "colours") || !Q_stricmp(token, "colors"))
|
|
||||||
parmtype = SP_E_COLOURS;
|
|
||||||
else if (!Q_stricmp(token, "upper"))
|
|
||||||
parmtype = SP_E_TOPCOLOURS;
|
|
||||||
else if (!Q_stricmp(token, "lower"))
|
|
||||||
parmtype = SP_E_BOTTOMCOLOURS;
|
|
||||||
else if (!Q_stricmp(token, "lightradius"))
|
|
||||||
parmtype = SP_LIGHTRADIUS;
|
|
||||||
else if (!Q_stricmp(token, "lightcolour"))
|
|
||||||
parmtype = SP_LIGHTCOLOUR;
|
|
||||||
else if (!Q_stricmp(token, "lightpos"))
|
|
||||||
parmtype = SP_LIGHTPOSITION;
|
|
||||||
else if (!Q_stricmp(token, "rendertexturescale"))
|
|
||||||
parmtype = SP_RENDERTEXTURESCALE;
|
|
||||||
else
|
|
||||||
Con_Printf("shader %s: parameter type \"%s\" not known\n", shader->name, token);
|
|
||||||
|
|
||||||
if (forcename)
|
|
||||||
token = forcename;
|
|
||||||
else
|
|
||||||
token = Shader_ParseSensString(ptr);
|
|
||||||
|
|
||||||
if (qrenderer == QR_OPENGL)
|
|
||||||
{
|
|
||||||
int specialint = 0;
|
|
||||||
float specialfloat = 0;
|
|
||||||
vec3_t specialvec = {0};
|
|
||||||
|
|
||||||
int p;
|
|
||||||
qboolean foundone;
|
|
||||||
unsigned int uniformloc;
|
|
||||||
program_t *prog = shader->prog;
|
|
||||||
if (!prog)
|
|
||||||
{
|
|
||||||
Con_Printf("shader %s: param without program set\n", shader->name);
|
|
||||||
}
|
|
||||||
else if (prog->numparams == SHADER_PROGPARMS_MAX)
|
|
||||||
Con_Printf("shader %s: too many parms\n", shader->name);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (prog->refs != 1)
|
|
||||||
Con_Printf("shader %s: parms on shared shader\n", shader->name);
|
|
||||||
|
|
||||||
foundone = false;
|
|
||||||
prog->parm[prog->numparams].type = parmtype;
|
|
||||||
for (p = 0; p < PERMUTATIONS; p++)
|
|
||||||
{
|
|
||||||
if (!prog->permu[p].handle.glsl.handle)
|
|
||||||
continue;
|
|
||||||
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
|
|
||||||
|
|
||||||
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, token);
|
|
||||||
prog->permu[p].parm[prog->numparams] = uniformloc;
|
|
||||||
|
|
||||||
if (uniformloc != -1)
|
|
||||||
{
|
|
||||||
foundone = true;
|
|
||||||
switch(parmtype)
|
|
||||||
{
|
|
||||||
case SP_BAD:
|
|
||||||
foundone = false;
|
|
||||||
break;
|
|
||||||
case SP_TEXTURE:
|
|
||||||
case SP_CONSTI:
|
|
||||||
prog->parm[prog->numparams].ival = specialint;
|
|
||||||
break;
|
|
||||||
case SP_CONSTF:
|
|
||||||
prog->parm[prog->numparams].fval = specialfloat;
|
|
||||||
break;
|
|
||||||
case SP_CVARF:
|
|
||||||
case SP_CVARI:
|
|
||||||
prog->parm[prog->numparams].pval = cv;
|
|
||||||
break;
|
|
||||||
case SP_CVAR3F:
|
|
||||||
prog->parm[prog->numparams].pval = cv;
|
|
||||||
qglUniform3fvARB(uniformloc, 1, specialvec);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundone)
|
|
||||||
{
|
|
||||||
if (!silent)
|
|
||||||
Con_Printf("shader %s: param \"%s\" not found\n", shader->name, token);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
prog->numparams++;
|
|
||||||
|
|
||||||
GLSlang_UseProgram(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Shader_ReflectCube(shader_t *shader, shaderpass_t *pass, char **ptr)
|
static void Shader_ReflectCube(shader_t *shader, shaderpass_t *pass, char **ptr)
|
||||||
{
|
{
|
||||||
char *token = Shader_ParseString(ptr);
|
char *token = Shader_ParseString(ptr);
|
||||||
|
@ -2662,7 +2502,6 @@ static shaderkey_t shaderkeys[] =
|
||||||
{"glslprogram", Shader_GLSLProgramName, "fte"}, //for renderers that accept embedded glsl
|
{"glslprogram", Shader_GLSLProgramName, "fte"}, //for renderers that accept embedded glsl
|
||||||
{"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d with embedded hlsl
|
{"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d with embedded hlsl
|
||||||
{"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d with embedded hlsl
|
{"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d with embedded hlsl
|
||||||
{"param", Shader_ProgramParam, "fte"}, //legacy
|
|
||||||
{"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode.
|
{"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode.
|
||||||
{"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass).
|
{"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass).
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ typedef struct shadowmesh_s
|
||||||
{
|
{
|
||||||
SMT_STENCILVOLUME, //build edges mesh (and surface list)
|
SMT_STENCILVOLUME, //build edges mesh (and surface list)
|
||||||
SMT_SHADOWMAP, //build front faces mesh (and surface list)
|
SMT_SHADOWMAP, //build front faces mesh (and surface list)
|
||||||
|
SMT_ORTHO, //bounded by a box and with a single direction rather than an origin.
|
||||||
SMT_SHADOWLESS, //build vis+surface list only
|
SMT_SHADOWLESS, //build vis+surface list only
|
||||||
SMT_DEFERRED //build vis without caring about any surfaces at all.
|
SMT_DEFERRED //build vis without caring about any surfaces at all.
|
||||||
} type;
|
} type;
|
||||||
|
@ -216,6 +217,46 @@ static void SHM_MeshFrontOnly(int numverts, vecV_t *verts, int numidx, index_t *
|
||||||
vecV_t *outv;
|
vecV_t *outv;
|
||||||
index_t *outi;
|
index_t *outi;
|
||||||
|
|
||||||
|
/*make sure there's space*/
|
||||||
|
v = (sh_shmesh->numverts+numverts + inc)&~(inc-1); //and a bit of padding
|
||||||
|
if (sh_shmesh->maxverts < v)
|
||||||
|
{
|
||||||
|
v *= 2;
|
||||||
|
v += 1024;
|
||||||
|
sh_shmesh->maxverts = v;
|
||||||
|
sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, v * sizeof(*sh_shmesh->verts));
|
||||||
|
}
|
||||||
|
|
||||||
|
outv = sh_shmesh->verts + sh_shmesh->numverts;
|
||||||
|
for (v = 0; v < numverts; v++)
|
||||||
|
{
|
||||||
|
VectorCopy(verts[v], outv[v]);
|
||||||
|
}
|
||||||
|
|
||||||
|
v = (sh_shmesh->numindicies+numidx + inc)&~(inc-1); //and a bit of padding
|
||||||
|
if (sh_shmesh->maxindicies < v)
|
||||||
|
{
|
||||||
|
v *= 2;
|
||||||
|
v += 1024;
|
||||||
|
sh_shmesh->maxindicies = v;
|
||||||
|
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, v * sizeof(*sh_shmesh->indicies));
|
||||||
|
}
|
||||||
|
outi = sh_shmesh->indicies + sh_shmesh->numindicies;
|
||||||
|
for (i = 0; i < numidx; i++)
|
||||||
|
{
|
||||||
|
outi[i] = first + idx[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
sh_shmesh->numverts += numverts;
|
||||||
|
sh_shmesh->numindicies += numidx;
|
||||||
|
}
|
||||||
|
static void SHM_MeshBackOnly(int numverts, vecV_t *verts, int numidx, index_t *idx)
|
||||||
|
{
|
||||||
|
int first = sh_shmesh->numverts;
|
||||||
|
int v, i;
|
||||||
|
vecV_t *outv;
|
||||||
|
index_t *outi;
|
||||||
|
|
||||||
/*make sure there's space*/
|
/*make sure there's space*/
|
||||||
v = (sh_shmesh->numverts+numverts + inc)&~(inc-1); //and a bit of padding
|
v = (sh_shmesh->numverts+numverts + inc)&~(inc-1); //and a bit of padding
|
||||||
if (sh_shmesh->maxverts < v)
|
if (sh_shmesh->maxverts < v)
|
||||||
|
@ -239,9 +280,11 @@ static void SHM_MeshFrontOnly(int numverts, vecV_t *verts, int numidx, index_t *
|
||||||
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, v * sizeof(*sh_shmesh->indicies));
|
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, v * sizeof(*sh_shmesh->indicies));
|
||||||
}
|
}
|
||||||
outi = sh_shmesh->indicies + sh_shmesh->numindicies;
|
outi = sh_shmesh->indicies + sh_shmesh->numindicies;
|
||||||
for (i = 0; i < numidx; i++)
|
for (i = 0; i < numidx; i+=3)
|
||||||
{
|
{
|
||||||
outi[i] = first + idx[i];
|
outi[i+0] = first + idx[i+2];
|
||||||
|
outi[i+1] = first + idx[i+1];
|
||||||
|
outi[i+2] = first + idx[i+0];
|
||||||
}
|
}
|
||||||
|
|
||||||
sh_shmesh->numverts += numverts;
|
sh_shmesh->numverts += numverts;
|
||||||
|
@ -776,6 +819,129 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
|
||||||
SHM_RecursiveWorldNodeQ1_r (dl, node->children[!side]);
|
SHM_RecursiveWorldNodeQ1_r (dl, node->children[!side]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CategorizePlane ( mplane_t *plane );
|
||||||
|
static void SHM_OrthoWorldLeafsQ1 (dlight_t *dl)
|
||||||
|
{
|
||||||
|
int c, i;
|
||||||
|
msurface_t *surf, **mark;
|
||||||
|
mleaf_t *pleaf, *plastleaf;
|
||||||
|
float dot;
|
||||||
|
|
||||||
|
mplane_t orthoplanes[5];
|
||||||
|
|
||||||
|
sh_shadowframe++;
|
||||||
|
|
||||||
|
VectorCopy(dl->axis[0], orthoplanes[0].normal);
|
||||||
|
VectorNegate(dl->axis[0], orthoplanes[1].normal);
|
||||||
|
VectorCopy(dl->axis[1], orthoplanes[2].normal);
|
||||||
|
VectorNegate(dl->axis[1], orthoplanes[3].normal);
|
||||||
|
VectorNegate(dl->axis[0], orthoplanes[4].normal);
|
||||||
|
|
||||||
|
for (i = 0; i < countof(orthoplanes); i++)
|
||||||
|
{
|
||||||
|
orthoplanes[i].dist = DotProduct(dl->origin, orthoplanes[i].normal) - dl->radius;
|
||||||
|
CategorizePlane(&orthoplanes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pleaf = cl.worldmodel->leafs+1, plastleaf = cl.worldmodel->leafs+cl.worldmodel->submodels[0].visleafs; pleaf <= plastleaf; pleaf++)
|
||||||
|
{
|
||||||
|
for (i = 0; i < countof(orthoplanes); i++)
|
||||||
|
if (BOX_ON_PLANE_SIDE (pleaf->minmaxs, pleaf->minmaxs+3, &orthoplanes[i]) == 2)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
SHM_Shadow_Cache_Leaf(pleaf);
|
||||||
|
|
||||||
|
mark = pleaf->firstmarksurface;
|
||||||
|
c = pleaf->nummarksurfaces;
|
||||||
|
|
||||||
|
while (c --> 0)
|
||||||
|
{
|
||||||
|
surf = *mark++;
|
||||||
|
|
||||||
|
if (surf->flags & (SURF_DRAWALPHA | SURF_DRAWTILED | SURF_DRAWSKY))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (surf->shadowframe != sh_shadowframe)
|
||||||
|
{
|
||||||
|
surf->shadowframe = sh_shadowframe;
|
||||||
|
|
||||||
|
dot = DotProduct(surf->plane->normal, dl->axis[0]);
|
||||||
|
if (surf->flags & SURF_PLANEBACK)
|
||||||
|
dot = -dot;
|
||||||
|
|
||||||
|
if (dot < 0)
|
||||||
|
{
|
||||||
|
SHM_Shadow_Cache_Surface(surf);
|
||||||
|
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// SHM_MeshBackOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
|
||||||
|
SHM_MeshFrontOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SHM_OrthoWorldLeafsQ3 (dlight_t *dl)
|
||||||
|
{
|
||||||
|
int c, i;
|
||||||
|
msurface_t *surf, **mark;
|
||||||
|
mleaf_t *pleaf, *plastleaf;
|
||||||
|
|
||||||
|
mplane_t orthoplanes[5];
|
||||||
|
|
||||||
|
sh_shadowframe++;
|
||||||
|
|
||||||
|
VectorCopy(dl->axis[0], orthoplanes[0].normal);
|
||||||
|
VectorNegate(dl->axis[0], orthoplanes[1].normal);
|
||||||
|
VectorCopy(dl->axis[1], orthoplanes[2].normal);
|
||||||
|
VectorNegate(dl->axis[1], orthoplanes[3].normal);
|
||||||
|
VectorNegate(dl->axis[0], orthoplanes[4].normal);
|
||||||
|
|
||||||
|
for (i = 0; i < countof(orthoplanes); i++)
|
||||||
|
{
|
||||||
|
orthoplanes[i].dist = DotProduct(dl->origin, orthoplanes[i].normal) - dl->radius;
|
||||||
|
CategorizePlane(&orthoplanes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pleaf = cl.worldmodel->leafs+1, plastleaf = cl.worldmodel->leafs+cl.worldmodel->numleafs; pleaf <= plastleaf; pleaf++)
|
||||||
|
{
|
||||||
|
for (i = 0; i < countof(orthoplanes); i++)
|
||||||
|
if (BOX_ON_PLANE_SIDE (pleaf->minmaxs, pleaf->minmaxs+3, &orthoplanes[i]) == 2)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
SHM_Shadow_Cache_Leaf(pleaf);
|
||||||
|
|
||||||
|
mark = pleaf->firstmarksurface;
|
||||||
|
c = pleaf->nummarksurfaces;
|
||||||
|
|
||||||
|
while (c --> 0)
|
||||||
|
{
|
||||||
|
surf = *mark++;
|
||||||
|
|
||||||
|
if (surf->flags & (SURF_DRAWALPHA | SURF_DRAWTILED | SURF_DRAWSKY))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (surf->shadowframe != sh_shadowframe)
|
||||||
|
{
|
||||||
|
surf->shadowframe = sh_shadowframe;
|
||||||
|
|
||||||
|
// if (dot < 0)
|
||||||
|
{
|
||||||
|
SHM_Shadow_Cache_Surface(surf);
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// SHM_MeshBackOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
|
||||||
|
SHM_MeshFrontOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q2BSPS
|
#ifdef Q2BSPS
|
||||||
static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
|
static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
|
||||||
{
|
{
|
||||||
|
@ -1407,7 +1573,9 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
|
||||||
if (!lvis)
|
if (!lvis)
|
||||||
{
|
{
|
||||||
int clus;
|
int clus;
|
||||||
if ((type == SMT_SHADOWLESS || dl->lightcolourscales[0]) && cl.worldmodel->funcs.ClustersInSphere)
|
if (type == SMT_ORTHO)
|
||||||
|
;
|
||||||
|
else if ((type == SMT_SHADOWLESS || dl->lightcolourscales[0]) && cl.worldmodel->funcs.ClustersInSphere)
|
||||||
//shadowless lights don't cast shadows, so they're seen through everything - their vis must reflect that.
|
//shadowless lights don't cast shadows, so they're seen through everything - their vis must reflect that.
|
||||||
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb, NULL);
|
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb, NULL);
|
||||||
else
|
else
|
||||||
|
@ -1446,9 +1614,14 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
|
||||||
{
|
{
|
||||||
SHM_BeginShadowMesh(dl, type);
|
SHM_BeginShadowMesh(dl, type);
|
||||||
|
|
||||||
|
if (type == SMT_ORTHO)
|
||||||
|
SHM_OrthoWorldLeafsQ1(dl);
|
||||||
|
else
|
||||||
|
{
|
||||||
SHM_MarkLeavesQ1(dl, lvis);
|
SHM_MarkLeavesQ1(dl, lvis);
|
||||||
SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes);
|
SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef Q2BSPS
|
#ifdef Q2BSPS
|
||||||
case fg_quake2:
|
case fg_quake2:
|
||||||
|
@ -1462,8 +1635,13 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
|
||||||
/*q3 doesn't have edge info*/
|
/*q3 doesn't have edge info*/
|
||||||
SHM_BeginShadowMesh(dl, type);
|
SHM_BeginShadowMesh(dl, type);
|
||||||
|
|
||||||
|
if (type == SMT_ORTHO)
|
||||||
|
SHM_OrthoWorldLeafsQ3(dl);
|
||||||
|
else
|
||||||
|
{
|
||||||
sh_shadowframe++;
|
sh_shadowframe++;
|
||||||
SHM_RecursiveWorldNodeQ3_r(dl, cl.worldmodel->nodes);
|
SHM_RecursiveWorldNodeQ3_r(dl, cl.worldmodel->nodes);
|
||||||
|
}
|
||||||
if (type == SMT_STENCILVOLUME)
|
if (type == SMT_STENCILVOLUME)
|
||||||
SHM_ComposeVolume_BruteForce(dl);
|
SHM_ComposeVolume_BruteForce(dl);
|
||||||
break;
|
break;
|
||||||
|
@ -2146,6 +2324,12 @@ static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowm
|
||||||
|
|
||||||
R_SetFrustum(proj, r_refdef.m_view);
|
R_SetFrustum(proj, r_refdef.m_view);
|
||||||
|
|
||||||
|
if (lighttype & LSHADER_ORTHO)
|
||||||
|
{
|
||||||
|
r_refdef.frustum_numplanes = 4; //kill the near clip plane - we allow ANYTHING nearer through.
|
||||||
|
qglEnable(GL_DEPTH_CLAMP_ARB);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SHADOWDBG_COLOURNOTDEPTH
|
#ifdef SHADOWDBG_COLOURNOTDEPTH
|
||||||
BE_SelectMode(BEM_STANDARD);
|
BE_SelectMode(BEM_STANDARD);
|
||||||
#else
|
#else
|
||||||
|
@ -2218,6 +2402,9 @@ static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowm
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lighttype & LSHADER_ORTHO)
|
||||||
|
qglDisable(GL_DEPTH_CLAMP_ARB);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -2310,7 +2497,7 @@ qboolean Sh_GenShadowMap (dlight_t *l, int lighttype, vec3_t axis[3], qbyte *lvi
|
||||||
memcpy(oprojv, r_refdef.m_projection_view, sizeof(oprojv));
|
memcpy(oprojv, r_refdef.m_projection_view, sizeof(oprojv));
|
||||||
memcpy(oview, r_refdef.m_view, sizeof(oview));
|
memcpy(oview, r_refdef.m_view, sizeof(oview));
|
||||||
oprect = r_refdef.pxrect;
|
oprect = r_refdef.pxrect;
|
||||||
smesh = SHM_BuildShadowMesh(l, lvis, SMT_SHADOWMAP);
|
smesh = SHM_BuildShadowMesh(l, lvis, (lighttype & LSHADER_ORTHO)?SMT_ORTHO:SMT_SHADOWMAP);
|
||||||
|
|
||||||
if (lighttype & LSHADER_SPOT)
|
if (lighttype & LSHADER_SPOT)
|
||||||
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, l->fov, l->fov, r_shadow_shadowmapping_nearclip.value, l->radius, false);
|
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, l->fov, l->fov, r_shadow_shadowmapping_nearclip.value, l->radius, false);
|
||||||
|
@ -3708,7 +3895,20 @@ void Sh_DrawLights(qbyte *vis)
|
||||||
axis = dl->axis;
|
axis = dl->axis;
|
||||||
|
|
||||||
drawdlightnum++;
|
drawdlightnum++;
|
||||||
if (dl->flags & LFLAG_CREPUSCULAR)
|
if (dl->flags & LFLAG_ORTHO)
|
||||||
|
{
|
||||||
|
vec3_t saveorg = {dl->origin[0], dl->origin[1], dl->origin[2]}, neworg;
|
||||||
|
vec3_t saveaxis[3];
|
||||||
|
memcpy(saveaxis, dl->axis, sizeof(saveaxis));
|
||||||
|
memcpy(dl->axis, axis, sizeof(saveaxis));
|
||||||
|
VectorMA(r_origin, dl->radius/3, vpn, neworg);
|
||||||
|
VectorCopy(neworg, dl->origin);
|
||||||
|
dl->rebuildcache = true;
|
||||||
|
Sh_DrawShadowMapLight(dl, colour, axis, NULL);
|
||||||
|
VectorCopy(saveorg, dl->origin);
|
||||||
|
memcpy(dl->axis, saveaxis, sizeof(saveaxis));
|
||||||
|
}
|
||||||
|
else if (dl->flags & LFLAG_CREPUSCULAR)
|
||||||
Sh_DrawCrepuscularLight(dl, colour);
|
Sh_DrawCrepuscularLight(dl, colour);
|
||||||
else if (((i >= RTL_FIRST)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
|
else if (((i >= RTL_FIRST)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1473,6 +1473,7 @@ static const char *glsl_hdrs[] =
|
||||||
"uniform float l_lightradius;"
|
"uniform float l_lightradius;"
|
||||||
"uniform vec3 l_lightcolour;"
|
"uniform vec3 l_lightcolour;"
|
||||||
"uniform vec3 l_lightposition;"
|
"uniform vec3 l_lightposition;"
|
||||||
|
"uniform vec3 l_lightdirection;"
|
||||||
"uniform vec3 l_lightcolourscale;"
|
"uniform vec3 l_lightcolourscale;"
|
||||||
"uniform mat4 l_cubematrix;"
|
"uniform mat4 l_cubematrix;"
|
||||||
"uniform vec4 l_shadowmapproj;"
|
"uniform vec4 l_shadowmapproj;"
|
||||||
|
@ -1776,7 +1777,7 @@ static const char *glsl_hdrs[] =
|
||||||
"return ((cubeproj.yxz-vec3(0.0,0.0,0.015))/cubeproj.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
|
"return ((cubeproj.yxz-vec3(0.0,0.0,0.015))/cubeproj.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
|
||||||
"#elif defined(ORTHO)\n"
|
"#elif defined(ORTHO)\n"
|
||||||
//the light's origin is in the center of the 'cube', projecting from one side to the other, so don't bias the z.
|
//the light's origin is in the center of the 'cube', projecting from one side to the other, so don't bias the z.
|
||||||
"return ((cubeproj.xyz-vec3(0.0,0.0,0.015))/cubeproj.w + vec3(1.0, 1.0, 0.0)) * vec3(0.5, 0.5, 1.0);\n"
|
"return ((cubeproj.xyz-vec3(0.0,0.0,0.015))/cubeproj.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
|
||||||
//"#elif defined(CUBESHADOW)\n"
|
//"#elif defined(CUBESHADOW)\n"
|
||||||
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
|
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
|
||||||
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
|
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
|
||||||
|
|
|
@ -1169,7 +1169,6 @@ void GLVID_SetCaption(const char *text)
|
||||||
SetWindowTextW(mainwindow, wide);
|
SetWindowTextW(mainwindow, wide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static qboolean VID_SetFullDIBMode (rendererstate_t *info)
|
static qboolean VID_SetFullDIBMode (rendererstate_t *info)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1265,6 +1264,21 @@ static qboolean VID_SetFullDIBMode (rendererstate_t *info)
|
||||||
if (!dibwindow)
|
if (!dibwindow)
|
||||||
Sys_Error ("Couldn't create DIB window");
|
Sys_Error ("Couldn't create DIB window");
|
||||||
|
|
||||||
|
{
|
||||||
|
BOOL fDisable = TRUE;
|
||||||
|
DWORD qDWMWA_TRANSITIONS_FORCEDISABLED = 3;
|
||||||
|
HRESULT (WINAPI *pDwmSetWindowAttribute)(HWND hWnd,DWORD dwAttribute,LPCVOID pvAttribute,DWORD cbAttribute);
|
||||||
|
dllfunction_t dwm[] =
|
||||||
|
{
|
||||||
|
{(void*)&pDwmSetWindowAttribute, "DwmSetWindowAttribute"},
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
if (Sys_LoadLibrary("dwmapi.dll", dwm))
|
||||||
|
{
|
||||||
|
pDwmSetWindowAttribute(dibwindow, qDWMWA_TRANSITIONS_FORCEDISABLED, &fDisable, sizeof(fDisable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SendMessage (dibwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon);
|
SendMessage (dibwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon);
|
||||||
SendMessage (dibwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);
|
SendMessage (dibwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);
|
||||||
|
|
||||||
|
@ -2874,7 +2888,7 @@ static LONG WINAPI GLMainWndProc (
|
||||||
GLAppActivate(FALSE, Minimized);//FIXME: thread
|
GLAppActivate(FALSE, Minimized);//FIXME: thread
|
||||||
ClearAllStates (); //FIXME: thread
|
ClearAllStates (); //FIXME: thread
|
||||||
#endif
|
#endif
|
||||||
if (modestate == MS_FULLDIB)
|
if (modestate != MS_WINDOWED)
|
||||||
ShowWindow(mainwindow, SW_SHOWMINNOACTIVE);
|
ShowWindow(mainwindow, SW_SHOWMINNOACTIVE);
|
||||||
break;
|
break;
|
||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
|
|
|
@ -900,6 +900,7 @@ void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int
|
||||||
|
|
||||||
//try to load dual-layer-single-image skies.
|
//try to load dual-layer-single-image skies.
|
||||||
//this is always going to be lame special case crap
|
//this is always going to be lame special case crap
|
||||||
|
if (gl_load24bit.ival)
|
||||||
{
|
{
|
||||||
size_t filesize = 0;
|
size_t filesize = 0;
|
||||||
qbyte *filedata = NULL;
|
qbyte *filedata = NULL;
|
||||||
|
|
|
@ -7179,7 +7179,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
{QR_OPENGL, 110, "defaultwarp",
|
{QR_OPENGL, 110, "defaultwarp",
|
||||||
"!!permu FOG\n"
|
"!!permu FOG\n"
|
||||||
"!!cvarf r_wateralpha\n"
|
"!!cvarf r_wateralpha\n"
|
||||||
"!!samps diffuse\n"
|
"!!samps diffuse lightmap\n"
|
||||||
|
|
||||||
"#include \"sys/defs.h\"\n"
|
"#include \"sys/defs.h\"\n"
|
||||||
|
|
||||||
|
@ -7188,6 +7188,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
|
|
||||||
"#include \"sys/fog.h\"\n"
|
"#include \"sys/fog.h\"\n"
|
||||||
"varying vec2 tc;\n"
|
"varying vec2 tc;\n"
|
||||||
|
"#ifdef LIT\n"
|
||||||
|
"varying vec2 lm0;\n"
|
||||||
|
"#endif\n"
|
||||||
"#ifdef VERTEX_SHADER\n"
|
"#ifdef VERTEX_SHADER\n"
|
||||||
"void main ()\n"
|
"void main ()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -7195,6 +7198,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"#ifdef FLOW\n"
|
"#ifdef FLOW\n"
|
||||||
"tc.s += e_time * -0.5;\n"
|
"tc.s += e_time * -0.5;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
"#ifdef LIT\n"
|
||||||
|
"lm0 = v_lmcoord;\n"
|
||||||
|
"#endif\n"
|
||||||
"gl_Position = ftetransform();\n"
|
"gl_Position = ftetransform();\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
@ -7211,6 +7217,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
|
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
|
||||||
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
|
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
|
||||||
"vec3 ts = vec3(texture2D(s_diffuse, ntc));\n"
|
"vec3 ts = vec3(texture2D(s_diffuse, ntc));\n"
|
||||||
|
|
||||||
|
"#ifdef LIT\n"
|
||||||
|
"ts *= (texture2D(s_lightmap, lm0) * e_lmscale).rgb;\n"
|
||||||
|
"#endif\n"
|
||||||
|
|
||||||
"gl_FragColor = fog4(vec4(ts, USEALPHA));\n"
|
"gl_FragColor = fog4(vec4(ts, USEALPHA));\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
@ -11356,7 +11367,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"#ifdef REFLECTCUBEMASK\n"
|
"#ifdef REFLECTCUBEMASK\n"
|
||||||
"varying mat3 invsurface;\n"
|
"varying mat3 invsurface;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
"#if defined(PCF) || defined(CUBE) || defined(SPOT)\n"
|
"#if defined(PCF) || defined(CUBE) || defined(SPOT) || defined(ORTHO)\n"
|
||||||
"varying vec4 vtexprojcoord;\n"
|
"varying vec4 vtexprojcoord;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
@ -11372,6 +11383,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"vec3 n, s, t, w;\n"
|
"vec3 n, s, t, w;\n"
|
||||||
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
|
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
|
||||||
"tcbase = v_texcoord; //pass the texture coords straight through\n"
|
"tcbase = v_texcoord; //pass the texture coords straight through\n"
|
||||||
|
"#ifdef ORTHO\n"
|
||||||
|
"vec3 lightminusvertex = -l_lightdirection;\n"
|
||||||
|
"lightvector.x = dot(lightminusvertex, s.xyz);\n"
|
||||||
|
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
|
||||||
|
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
|
||||||
|
"#else\n"
|
||||||
"vec3 lightminusvertex = l_lightposition - w.xyz;\n"
|
"vec3 lightminusvertex = l_lightposition - w.xyz;\n"
|
||||||
"#ifdef NOBUMP\n"
|
"#ifdef NOBUMP\n"
|
||||||
//the only important thing is distance
|
//the only important thing is distance
|
||||||
|
@ -11382,6 +11399,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
|
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
|
||||||
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
|
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
"#endif\n"
|
||||||
"#if defined(VERTEXCOLOURS)\n"
|
"#if defined(VERTEXCOLOURS)\n"
|
||||||
"vc = v_colour;\n"
|
"vc = v_colour;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
@ -11396,7 +11414,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"invsurface[1] = v_tvector;\n"
|
"invsurface[1] = v_tvector;\n"
|
||||||
"invsurface[2] = v_normal;\n"
|
"invsurface[2] = v_normal;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
"#if defined(PCF) || defined(SPOT) || defined(CUBE)\n"
|
"#if defined(PCF) || defined(SPOT) || defined(CUBE) || defined(ORTHO)\n"
|
||||||
//for texture projections/shadowmapping on dlights
|
//for texture projections/shadowmapping on dlights
|
||||||
"vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));\n"
|
"vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
@ -11488,7 +11506,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"vec3 t2 = w - dot(w-t_vertex[2],t_normal[2])*t_normal[2];\n"
|
"vec3 t2 = w - dot(w-t_vertex[2],t_normal[2])*t_normal[2];\n"
|
||||||
"w = w*(1.0-factor) + factor*(gl_TessCoord.x*t0+gl_TessCoord.y*t1+gl_TessCoord.z*t2);\n"
|
"w = w*(1.0-factor) + factor*(gl_TessCoord.x*t0+gl_TessCoord.y*t1+gl_TessCoord.z*t2);\n"
|
||||||
|
|
||||||
"#if defined(PCF) || defined(SPOT) || defined(CUBE)\n"
|
"#if defined(PCF) || defined(SPOT) || defined(CUBE) || defined(ORTHO)\n"
|
||||||
//for texture projections/shadowmapping on dlights
|
//for texture projections/shadowmapping on dlights
|
||||||
"vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));\n"
|
"vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
@ -11613,8 +11631,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"diff *= vc.rgb * vc.a;\n"
|
"diff *= vc.rgb * vc.a;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
|
||||||
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
|
"gl_FragColor = vec4(fog3additive(diff*colorscale*l_lightcolour), 1.0);\n"
|
||||||
|
|
||||||
"}\n"
|
"}\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
|
||||||
|
|
|
@ -455,6 +455,7 @@ typedef struct {
|
||||||
SP_LIGHTCOLOUR,
|
SP_LIGHTCOLOUR,
|
||||||
SP_LIGHTCOLOURSCALE,
|
SP_LIGHTCOLOURSCALE,
|
||||||
SP_LIGHTPOSITION,
|
SP_LIGHTPOSITION,
|
||||||
|
SP_LIGHTDIRECTION,
|
||||||
SP_LIGHTSCREEN,
|
SP_LIGHTSCREEN,
|
||||||
SP_LIGHTCUBEMATRIX,
|
SP_LIGHTCUBEMATRIX,
|
||||||
SP_LIGHTSHADOWMAPPROJ,
|
SP_LIGHTSHADOWMAPPROJ,
|
||||||
|
@ -490,10 +491,10 @@ typedef struct programshared_s
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
unsigned char *cvardata;
|
unsigned char *cvardata;
|
||||||
unsigned int cvardatasize;
|
unsigned int cvardatasize;
|
||||||
VkRetardedShaderModule vert; //for slightly faster regeneration
|
qVkShaderModule vert; //for slightly faster regeneration
|
||||||
VkRetardedShaderModule frag;
|
qVkShaderModule frag;
|
||||||
VkRetardedPipelineLayout layout; //all permutations share the same layout. I'm too lazy not to.
|
qVkPipelineLayout layout; //all permutations share the same layout. I'm too lazy not to.
|
||||||
VkRetardedDescriptorSetLayout desclayout;
|
qVkDescriptorSetLayout desclayout;
|
||||||
struct pipeline_s *pipelines;
|
struct pipeline_s *pipelines;
|
||||||
#endif
|
#endif
|
||||||
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
||||||
|
|
|
@ -9882,7 +9882,13 @@ static void QCBUILTIN PF_SendPacket(pubprogfuncs_t *prinst, struct globalvars_s
|
||||||
const char *contents = PF_VarString(prinst, 1, pr_globals);
|
const char *contents = PF_VarString(prinst, 1, pr_globals);
|
||||||
|
|
||||||
if (NET_StringToAdr(address, 0, &to))
|
if (NET_StringToAdr(address, 0, &to))
|
||||||
NET_SendPacket(NS_SERVER, strlen(contents), contents, &to);
|
{
|
||||||
|
char *send = Z_Malloc(4+strlen(contents));
|
||||||
|
send[0] = send[1] = send[2] = send[3] = 0xff;
|
||||||
|
memcpy(send+4, contents, strlen(contents));
|
||||||
|
G_FLOAT(OFS_RETURN) = NET_SendPacket(NS_SERVER, 4+strlen(contents), send, &to);
|
||||||
|
Z_Free(send);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//be careful to not touch the resource unless we're meant to, to avoid stalling
|
//be careful to not touch the resource unless we're meant to, to avoid stalling
|
||||||
|
@ -10475,7 +10481,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
|
|
||||||
{"checkpvs", PF_checkpvs, 0, 0, 0, 240, "float(vector viewpos, entity entity)"},
|
{"checkpvs", PF_checkpvs, 0, 0, 0, 240, "float(vector viewpos, entity entity)"},
|
||||||
{"matchclientname", PF_matchclient, 0, 0, 0, 241, "entity(string match, optional float matchnum)"},
|
{"matchclientname", PF_matchclient, 0, 0, 0, 241, "entity(string match, optional float matchnum)"},
|
||||||
{"sendpacket", PF_SendPacket, 0, 0, 0, 242, "void(string destaddress, string content)"},// (FTE_QC_SENDPACKET)
|
{"sendpacket", PF_SendPacket, 0, 0, 0, 242, D("void(string destaddress, string content)", "Sends a UDP packet to the specified destination. Note that the payload will be prefixed with four 255 bytes as a sort of security feature.")},// (FTE_QC_SENDPACKET)
|
||||||
|
|
||||||
// {"bulleten", PF_bulleten, 0, 0, 0, 243}, (removed builtin)
|
// {"bulleten", PF_bulleten, 0, 0, 0, 243}, (removed builtin)
|
||||||
|
|
||||||
|
@ -11976,11 +11982,13 @@ void PR_DumpPlatform_f(void)
|
||||||
{"MULTICAST_ALL", "const float", QW|NQ, D("The multicast message is unreliably sent to all players. MULTICAST_ constants are valid arguments for the multicast builtin, which ignores the specified origin when given this constant."), MULTICAST_ALL},
|
{"MULTICAST_ALL", "const float", QW|NQ, D("The multicast message is unreliably sent to all players. MULTICAST_ constants are valid arguments for the multicast builtin, which ignores the specified origin when given this constant."), MULTICAST_ALL},
|
||||||
{"MULTICAST_PHS", "const float", QW|NQ, D("The multicast message is unreliably sent to only players that can potentially hear the specified origin. Its quite loose."), MULTICAST_PHS},
|
{"MULTICAST_PHS", "const float", QW|NQ, D("The multicast message is unreliably sent to only players that can potentially hear the specified origin. Its quite loose."), MULTICAST_PHS},
|
||||||
{"MULTICAST_PVS", "const float", QW|NQ, D("The multicast message is unreliably sent to only players that can potentially see the specified origin."), MULTICAST_PVS},
|
{"MULTICAST_PVS", "const float", QW|NQ, D("The multicast message is unreliably sent to only players that can potentially see the specified origin."), MULTICAST_PVS},
|
||||||
{"MULTICAST_ONE", "const float", QW|NQ, D("The multicast message is unreliably sent to the player specified in the msg_entity global. The specified origin is ignored."), MULTICAST_ONE},
|
{"MULTICAST_ONE", "const float", QW|NQ, D("The multicast message is unreliably sent to the player (AND ALL TRACKING SPECTATORS) specified in the msg_entity global. The specified origin is ignored."), MULTICAST_ONE_SPECS},
|
||||||
|
{"MULTICAST_ONE_NOSPECS","const float", QW|NQ, D("The multicast message is unreliably sent to the player specified in the msg_entity global. The specified origin is ignored."), MULTICAST_ONE_NOSPECS},
|
||||||
{"MULTICAST_ALL_R", "const float", QW|NQ, D("The multicast message is reliably sent to all players. The specified origin is ignored."), MULTICAST_ALL_R},
|
{"MULTICAST_ALL_R", "const float", QW|NQ, D("The multicast message is reliably sent to all players. The specified origin is ignored."), MULTICAST_ALL_R},
|
||||||
{"MULTICAST_PHS_R", "const float", QW|NQ, D("The multicast message is reliably sent to only players that can potentially hear the specified origin. Players might still not receive it if they are out of range."), MULTICAST_PHS_R},
|
{"MULTICAST_PHS_R", "const float", QW|NQ, D("The multicast message is reliably sent to only players that can potentially hear the specified origin. Players might still not receive it if they are out of range."), MULTICAST_PHS_R},
|
||||||
{"MULTICAST_PVS_R", "const float", QW|NQ, D("The multicast message is reliably sent to only players that can potentially see the specified origin. Players might still not receive it if they cannot see the event."), MULTICAST_PVS_R},
|
{"MULTICAST_PVS_R", "const float", QW|NQ, D("The multicast message is reliably sent to only players that can potentially see the specified origin. Players might still not receive it if they cannot see the event."), MULTICAST_PVS_R},
|
||||||
{"MULTICAST_ONE_R", "const float", QW|NQ, D("The multicast message is reliably sent to the player specified in the msg_entity global. The specified origin is ignored"), MULTICAST_ONE_R},
|
{"MULTICAST_ONE_R", "const float", QW|NQ, D("The multicast message is reliably sent to the player (AND ALL TRACKING SPECTATORS) specified in the msg_entity global. The specified origin is ignored"), MULTICAST_ONE_R_SPECS},
|
||||||
|
{"MULTICAST_ONE_R_NOSPECS","const float", QW|NQ, D("The multicast message is reliably sent to the player specified in the msg_entity global. The specified origin is ignored"), MULTICAST_ONE_R_NOSPECS},
|
||||||
|
|
||||||
{"PRINT_LOW", "const float", QW, NULL, PRINT_LOW},
|
{"PRINT_LOW", "const float", QW, NULL, PRINT_LOW},
|
||||||
{"PRINT_MEDIUM", "const float", QW, NULL, PRINT_MEDIUM},
|
{"PRINT_MEDIUM", "const float", QW, NULL, PRINT_MEDIUM},
|
||||||
|
@ -12091,7 +12099,7 @@ void PR_DumpPlatform_f(void)
|
||||||
{"EF_FLAG1", "const float", QW , NULL, QWEF_FLAG1},
|
{"EF_FLAG1", "const float", QW , NULL, QWEF_FLAG1},
|
||||||
{"EF_FLAG2", "const float", QW , NULL, QWEF_FLAG2},
|
{"EF_FLAG2", "const float", QW , NULL, QWEF_FLAG2},
|
||||||
{"EF_NODRAW", "const float", NQ|CS, NULL, NQEF_NODRAW},
|
{"EF_NODRAW", "const float", NQ|CS, NULL, NQEF_NODRAW},
|
||||||
{"EF_ADDITIVE", "const float", NQ|CS, D("The entity will be drawn with an additive blend."), NQEF_ADDITIVE},
|
{"EF_ADDITIVE", "const float", QW|NQ|CS, D("The entity will be drawn with an additive blend. This is NOT supported on players in any quakeworld engine."), NQEF_ADDITIVE},
|
||||||
{"EF_BLUE", "const float", QW|NQ|CS, D("A blue glow"), EF_BLUE},
|
{"EF_BLUE", "const float", QW|NQ|CS, D("A blue glow"), EF_BLUE},
|
||||||
{"EF_RED", "const float", QW|NQ|CS, D("A red glow"), EF_RED},
|
{"EF_RED", "const float", QW|NQ|CS, D("A red glow"), EF_RED},
|
||||||
{"EF_GREEN", "const float", QW|NQ|CS, D("A green glow"), EF_GREEN},
|
{"EF_GREEN", "const float", QW|NQ|CS, D("A green glow"), EF_GREEN},
|
||||||
|
|
|
@ -448,7 +448,7 @@ typedef struct
|
||||||
qboolean isoffset:1;
|
qboolean isoffset:1;
|
||||||
int orientpeer;
|
int orientpeer;
|
||||||
|
|
||||||
//ode info
|
//physics engine info
|
||||||
int geomshape;
|
int geomshape;
|
||||||
float relmatrix[12];
|
float relmatrix[12];
|
||||||
float inverserelmatrix[12];
|
float inverserelmatrix[12];
|
||||||
|
@ -503,43 +503,32 @@ typedef struct rbecommandqueue_s
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// physics parameters
|
// physics parameters
|
||||||
qboolean ode_physics;
|
qboolean physics;
|
||||||
void *ode_body;
|
rbebody_t body;
|
||||||
void *ode_geom;
|
rbejoint_t joint;
|
||||||
void *ode_joint;
|
float *vertex3f;
|
||||||
float *ode_vertex3f;
|
int *element3i;
|
||||||
int *ode_element3i;
|
int numvertices;
|
||||||
int ode_numvertices;
|
int numtriangles;
|
||||||
int ode_numtriangles;
|
vec3_t mins;
|
||||||
vec3_t ode_mins;
|
vec3_t maxs;
|
||||||
vec3_t ode_maxs;
|
vec_t mass;
|
||||||
vec_t ode_mass;
|
vec3_t origin;
|
||||||
vec3_t ode_origin;
|
vec3_t velocity;
|
||||||
vec3_t ode_velocity;
|
vec3_t angles;
|
||||||
vec3_t ode_angles;
|
vec3_t avelocity;
|
||||||
vec3_t ode_avelocity;
|
qboolean gravity;
|
||||||
qboolean ode_gravity;
|
int modelindex;
|
||||||
int ode_modelindex;
|
vec_t movelimit; // smallest component of (maxs[]-mins[])
|
||||||
vec_t ode_movelimit; // smallest component of (maxs[]-mins[])
|
float offsetmatrix[16];
|
||||||
float ode_offsetmatrix[16];
|
float offsetimatrix[16];
|
||||||
float ode_offsetimatrix[16];
|
int joint_type;
|
||||||
int ode_joint_type;
|
int joint_enemy;
|
||||||
int ode_joint_enemy;
|
int joint_aiment;
|
||||||
int ode_joint_aiment;
|
vec3_t joint_origin; // joint anchor
|
||||||
vec3_t ode_joint_origin; // joint anchor
|
vec3_t joint_angles; // joint axis
|
||||||
vec3_t ode_joint_angles; // joint axis
|
vec3_t joint_velocity; // second joint axis
|
||||||
vec3_t ode_joint_velocity; // second joint axis
|
vec3_t joint_movedir; // parameters
|
||||||
vec3_t ode_joint_movedir; // parameters
|
void *massbuf;
|
||||||
void *ode_massbuf;
|
} entityrbe_t;
|
||||||
} entityode_t;
|
|
||||||
/*
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
void *ode_body;
|
|
||||||
} skelbodyode_t;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int dummy;
|
|
||||||
} skeljointode_t;
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,7 +85,7 @@ typedef struct edict_s
|
||||||
int lastruntime;
|
int lastruntime;
|
||||||
int solidsize;
|
int solidsize;
|
||||||
#ifdef USERBE
|
#ifdef USERBE
|
||||||
entityode_t ode;
|
entityrbe_t rbe;
|
||||||
#endif
|
#endif
|
||||||
/*csqc doesn't reference the rest*/
|
/*csqc doesn't reference the rest*/
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,11 @@ typedef enum multicast_e
|
||||||
MULTICAST_PHS_R,
|
MULTICAST_PHS_R,
|
||||||
MULTICAST_PVS_R,
|
MULTICAST_PVS_R,
|
||||||
|
|
||||||
MULTICAST_ONE,
|
MULTICAST_ONE_SPECS,
|
||||||
MULTICAST_ONE_R,
|
MULTICAST_ONE_R_SPECS,
|
||||||
MULTICAST_INIT
|
MULTICAST_INIT,
|
||||||
|
MULTICAST_ONE_NOSPECS,
|
||||||
|
MULTICAST_ONE_R_NOSPECS,
|
||||||
} multicast_t;
|
} multicast_t;
|
||||||
|
|
||||||
extern float pm_q2stepheight;
|
extern float pm_q2stepheight;
|
||||||
|
|
|
@ -1326,6 +1326,9 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
||||||
qbyte *oldbonedata;
|
qbyte *oldbonedata;
|
||||||
unsigned int maxbonedatasize;
|
unsigned int maxbonedatasize;
|
||||||
qboolean overflow = false;
|
qboolean overflow = false;
|
||||||
|
client_t *cl;
|
||||||
|
float age;
|
||||||
|
client_frame_t *frame;
|
||||||
|
|
||||||
if (!client->pendingdeltabits)
|
if (!client->pendingdeltabits)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1470,11 +1473,12 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
||||||
sequence = client->netchan.outgoing_unreliable;
|
sequence = client->netchan.outgoing_unreliable;
|
||||||
else
|
else
|
||||||
sequence = client->netchan.incoming_sequence;
|
sequence = client->netchan.incoming_sequence;
|
||||||
|
frame = &client->frameunion.frames[sequence & UPDATE_MASK];
|
||||||
|
|
||||||
/*cache frame info*/
|
/*cache frame info*/
|
||||||
resend = client->frameunion.frames[sequence & UPDATE_MASK].resend;
|
resend = frame->resend;
|
||||||
outno = 0;
|
outno = 0;
|
||||||
outmax = client->frameunion.frames[sequence & UPDATE_MASK].maxresend;
|
outmax = frame->maxresend;
|
||||||
|
|
||||||
/*start writing the packet*/
|
/*start writing the packet*/
|
||||||
MSG_WriteByte (msg, svcfte_updateentities);
|
MSG_WriteByte (msg, svcfte_updateentities);
|
||||||
|
@ -1557,8 +1561,32 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
||||||
else
|
else
|
||||||
client->nextdeltaindex = j; //we overflowed or something, start going round-robin
|
client->nextdeltaindex = j; //we overflowed or something, start going round-robin
|
||||||
|
|
||||||
client->frameunion.frames[sequence & UPDATE_MASK].numresend = outno;
|
frame->numresend = outno;
|
||||||
client->frameunion.frames[sequence & UPDATE_MASK].sequence = sequence;
|
frame->sequence = sequence;
|
||||||
|
|
||||||
|
for (i = 0; i < to->num_entities; i++)
|
||||||
|
{
|
||||||
|
n = &to->entities[i];
|
||||||
|
j = n->number-1;
|
||||||
|
if (j >= sv.allocated_client_slots)
|
||||||
|
break; //don't track non-player slots.
|
||||||
|
|
||||||
|
cl = &svs.clients[j];
|
||||||
|
|
||||||
|
//states of other players are actually old.
|
||||||
|
//by the time we receive the other player's move, this stuff will be outdated and we don't know when that will actually be.
|
||||||
|
//so (cheaply) guess where they're really meant to be if they're running at a lower framerate.
|
||||||
|
if (!cl->name[0] || cl->protocol == SCP_BAD) //is bot
|
||||||
|
age = 0;//= sv.time - sv.world.physicstime; //FIXME
|
||||||
|
else
|
||||||
|
age = sv.time - sv.world.physicstime;
|
||||||
|
age = bound(0, age, 0.1);
|
||||||
|
|
||||||
|
VectorMA(n->origin, (sv.time - cl->localtime)/8.0, n->u.q1.velocity, frame->playerpositions[j]);
|
||||||
|
//FIXME: add framestate_t info.
|
||||||
|
frame->playerpresent[j] = true;
|
||||||
|
}
|
||||||
|
|
||||||
return overflow;
|
return overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5127,6 +5127,9 @@ void SV_InitLocal (void)
|
||||||
|
|
||||||
Cvar_Register (&sv_resetparms, cvargroup_servercontrol);
|
Cvar_Register (&sv_resetparms, cvargroup_servercontrol);
|
||||||
|
|
||||||
|
if (isDedicated)
|
||||||
|
sv_public.string = "1";
|
||||||
|
|
||||||
Cvar_Register (&sv_guidhash, cvargroup_servercontrol);
|
Cvar_Register (&sv_guidhash, cvargroup_servercontrol);
|
||||||
Cvar_Register (&sv_serverip, cvargroup_servercontrol);
|
Cvar_Register (&sv_serverip, cvargroup_servercontrol);
|
||||||
Cvar_Register (&sv_public, cvargroup_servercontrol);
|
Cvar_Register (&sv_public, cvargroup_servercontrol);
|
||||||
|
@ -5144,11 +5147,6 @@ void SV_InitLocal (void)
|
||||||
|
|
||||||
Cvar_Register (&sv_reportheartbeats, cvargroup_servercontrol);
|
Cvar_Register (&sv_reportheartbeats, cvargroup_servercontrol);
|
||||||
|
|
||||||
#ifndef SERVERONLY
|
|
||||||
if (isDedicated)
|
|
||||||
#endif
|
|
||||||
Cvar_Set(&sv_public, "1");
|
|
||||||
|
|
||||||
Cvar_Register (&sv_showconnectionlessmessages, cvargroup_servercontrol);
|
Cvar_Register (&sv_showconnectionlessmessages, cvargroup_servercontrol);
|
||||||
Cvar_Register (&sv_banproxies, cvargroup_serverpermissions);
|
Cvar_Register (&sv_banproxies, cvargroup_serverpermissions);
|
||||||
#ifdef SV_MASTER
|
#ifdef SV_MASTER
|
||||||
|
|
|
@ -1082,6 +1082,8 @@ void Route_Calculate(void *ctx, void *data, size_t a, size_t b)
|
||||||
COM_AddWork(WG_MAIN, Route_Calculated, NULL, route, 0, 0);
|
COM_AddWork(WG_MAIN, Route_Calculated, NULL, route, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void route_linkitem(entity item, int ittype) //-1 to unlink
|
||||||
|
//void route_choosedest(entity ent, int numitemtypes, float *itemweights)
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
PF_route_calculate
|
PF_route_calculate
|
||||||
|
@ -1093,6 +1095,7 @@ the first node in the nodelist is the destination.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
vector dest;
|
vector dest;
|
||||||
int linkflags;
|
int linkflags;
|
||||||
|
//float anglehint;
|
||||||
} nodeslist_t;
|
} nodeslist_t;
|
||||||
void(entity ent, vector dest, int denylinkflags, void(entity ent, vector dest, int numnodes, nodeslist_t *nodelist) callback) route_calculate = #0;
|
void(entity ent, vector dest, int denylinkflags, void(entity ent, vector dest, int numnodes, nodeslist_t *nodelist) callback) route_calculate = #0;
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -706,6 +706,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
qboolean reliable;
|
qboolean reliable;
|
||||||
client_t *oneclient = NULL, *split;
|
client_t *oneclient = NULL, *split;
|
||||||
int seat;
|
int seat;
|
||||||
|
qboolean andspecs = false;
|
||||||
|
|
||||||
if (!sv.multicast.cursize
|
if (!sv.multicast.cursize
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
|
@ -790,9 +791,11 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
mask = CM_ClusterPVS (sv.world.worldmodel, cluster, NULL, PVM_FAST);
|
mask = CM_ClusterPVS (sv.world.worldmodel, cluster, NULL, PVM_FAST);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MULTICAST_ONE_R:
|
case MULTICAST_ONE_R_NOSPECS:
|
||||||
|
case MULTICAST_ONE_R_SPECS:
|
||||||
reliable = true;
|
reliable = true;
|
||||||
case MULTICAST_ONE:
|
case MULTICAST_ONE_NOSPECS:
|
||||||
|
case MULTICAST_ONE_SPECS:
|
||||||
if (svprogfuncs)
|
if (svprogfuncs)
|
||||||
{
|
{
|
||||||
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
|
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
|
||||||
|
@ -801,6 +804,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
else
|
else
|
||||||
oneclient = NULL; //unsupported in this game mode
|
oneclient = NULL; //unsupported in this game mode
|
||||||
mask = NULL;
|
mask = NULL;
|
||||||
|
andspecs = (to==MULTICAST_ONE_R_SPECS||to==MULTICAST_ONE_SPECS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -838,7 +842,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
{
|
{
|
||||||
if (oneclient != split)
|
if (oneclient != split)
|
||||||
{
|
{
|
||||||
if (split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track])
|
if (andspecs && split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track])
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -975,9 +979,11 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
mask = NULL;
|
mask = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MULTICAST_ONE_R:
|
case MULTICAST_ONE_R_NOSPECS:
|
||||||
|
case MULTICAST_ONE_R_SPECS:
|
||||||
reliable = true;
|
reliable = true;
|
||||||
case MULTICAST_ONE:
|
case MULTICAST_ONE_NOSPECS:
|
||||||
|
case MULTICAST_ONE_SPECS:
|
||||||
if (svprogfuncs)
|
if (svprogfuncs)
|
||||||
{
|
{
|
||||||
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
|
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
|
||||||
|
@ -986,6 +992,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
else
|
else
|
||||||
oneclient = NULL;
|
oneclient = NULL;
|
||||||
mask = NULL;
|
mask = NULL;
|
||||||
|
andspecs = (to==MULTICAST_ONE_R_SPECS||to==MULTICAST_ONE_SPECS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1150,9 +1157,15 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
msg = &demo.datagram;
|
msg = &demo.datagram;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MULTICAST_ONE_R_NOSPECS:
|
||||||
|
case MULTICAST_ONE_NOSPECS:
|
||||||
|
msg = &demo.datagram;
|
||||||
|
sv.multicast.cursize = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
//mvds are all reliables really.
|
//mvds are all reliables really.
|
||||||
case MULTICAST_ONE_R:
|
case MULTICAST_ONE_R_SPECS:
|
||||||
case MULTICAST_ONE:
|
case MULTICAST_ONE_SPECS:
|
||||||
{
|
{
|
||||||
int pnum;
|
int pnum;
|
||||||
if (svprogfuncs)
|
if (svprogfuncs)
|
||||||
|
@ -1190,6 +1203,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
int cluster;
|
int cluster;
|
||||||
int j;
|
int j;
|
||||||
client_t *oneclient = NULL, *split;
|
client_t *oneclient = NULL, *split;
|
||||||
|
qboolean andspecs = false;
|
||||||
|
|
||||||
switch (to)
|
switch (to)
|
||||||
{
|
{
|
||||||
|
@ -1224,9 +1238,12 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
mask = NULL;
|
mask = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MULTICAST_ONE_R:
|
case MULTICAST_ONE_R_NOSPECS:
|
||||||
|
case MULTICAST_ONE_R_SPECS:
|
||||||
reliable = true;
|
reliable = true;
|
||||||
case MULTICAST_ONE:
|
|
||||||
|
case MULTICAST_ONE_NOSPECS:
|
||||||
|
case MULTICAST_ONE_SPECS:
|
||||||
if (svprogfuncs)
|
if (svprogfuncs)
|
||||||
{
|
{
|
||||||
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
|
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
|
||||||
|
@ -1235,6 +1252,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
else
|
else
|
||||||
oneclient = NULL;
|
oneclient = NULL;
|
||||||
mask = NULL;
|
mask = NULL;
|
||||||
|
andspecs = (to == MULTICAST_ONE_R_SPECS || to == MULTICAST_ONE_SPECS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1262,7 +1280,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
{
|
{
|
||||||
if (oneclient != split)
|
if (oneclient != split)
|
||||||
{
|
{
|
||||||
if (split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track])
|
if (andspecs && split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track])
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -1340,9 +1358,13 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
msg = &demo.datagram;
|
msg = &demo.datagram;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MULTICAST_ONE_R_NOSPECS:
|
||||||
|
case MULTICAST_ONE_NOSPECS:
|
||||||
|
return; //demos count as spectators.
|
||||||
|
|
||||||
//mvds are all reliables really.
|
//mvds are all reliables really.
|
||||||
case MULTICAST_ONE_R:
|
case MULTICAST_ONE_R_SPECS:
|
||||||
case MULTICAST_ONE:
|
case MULTICAST_ONE_SPECS:
|
||||||
{
|
{
|
||||||
int pnum = -1;
|
int pnum = -1;
|
||||||
if (svprogfuncs)
|
if (svprogfuncs)
|
||||||
|
@ -1589,7 +1611,7 @@ void SV_StartSound (int ent, vec3_t origin, float *velocity, int seenmask, int c
|
||||||
|
|
||||||
if (chflags & CF_UNICAST)
|
if (chflags & CF_UNICAST)
|
||||||
{
|
{
|
||||||
SV_MulticastCB(origin, reliable ? MULTICAST_ONE_R : MULTICAST_ONE, seenmask, SV_SoundMulticast, &ctx);
|
SV_MulticastCB(origin, reliable ? MULTICAST_ONE_R_SPECS : MULTICAST_ONE_SPECS, seenmask, SV_SoundMulticast, &ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1880,13 +1902,10 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
|
||||||
if (client->fteprotocolextensions2 & PEXT2_PREDINFO)
|
if (client->fteprotocolextensions2 & PEXT2_PREDINFO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
#ifdef NQPROT
|
|
||||||
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
|
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
|
||||||
nqjunk = false;
|
nqjunk = false;
|
||||||
else
|
else
|
||||||
nqjunk = true;
|
nqjunk = true;
|
||||||
#endif
|
|
||||||
|
|
||||||
bits = 0;
|
bits = 0;
|
||||||
|
|
||||||
|
@ -2973,7 +2992,7 @@ static qboolean SV_SyncInfoBuf(client_t *client)
|
||||||
{ //vanilla-compatible info.
|
{ //vanilla-compatible info.
|
||||||
if (ISNQCLIENT(client))
|
if (ISNQCLIENT(client))
|
||||||
{ //except that nq never had any userinfo
|
{ //except that nq never had any userinfo
|
||||||
const char *s = va("//ui %i \"%s\" \"%s\"\n", (client_t*)info-svs.clients, enckey, encval);
|
const char *s = va("//ui %i \"%s\" \"%s\"\n", (int)((client_t*)info-svs.clients), enckey, encval);
|
||||||
ClientReliableWrite_Begin(client, svc_stufftext, strlen(s)+2);
|
ClientReliableWrite_Begin(client, svc_stufftext, strlen(s)+2);
|
||||||
ClientReliableWrite_String(client, s);
|
ClientReliableWrite_String(client, s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,8 @@ void Sys_Error (const char *error, ...)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ansiremap[8] = {0, 4, 2, 6, 1, 5, 3, 7};
|
static qboolean useansicolours;
|
||||||
|
static int ansiremap[8] = {0, 4, 2, 6, 1, 5, 3, 7};
|
||||||
void ApplyColour(unsigned int chr)
|
void ApplyColour(unsigned int chr)
|
||||||
{
|
{
|
||||||
static int oldchar = CON_WHITEMASK;
|
static int oldchar = CON_WHITEMASK;
|
||||||
|
@ -229,6 +230,8 @@ void ApplyColour(unsigned int chr)
|
||||||
if (oldchar == chr)
|
if (oldchar == chr)
|
||||||
return;
|
return;
|
||||||
oldchar = chr;
|
oldchar = chr;
|
||||||
|
if (!useansicolours) //don't spew weird chars when redirected to a file.
|
||||||
|
return;
|
||||||
|
|
||||||
printf("\e[0;"); // reset
|
printf("\e[0;"); // reset
|
||||||
|
|
||||||
|
@ -713,6 +716,9 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
|
||||||
#ifdef HAVE_GNUTLS
|
#ifdef HAVE_GNUTLS
|
||||||
qboolean SSL_InitGlobal(qboolean isserver);
|
qboolean SSL_InitGlobal(qboolean isserver);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQL
|
||||||
|
#include "sv_sql.h"
|
||||||
|
#endif
|
||||||
static int Sys_CheckChRoot(void)
|
static int Sys_CheckChRoot(void)
|
||||||
{ //also warns if run as root.
|
{ //also warns if run as root.
|
||||||
int ret = false;
|
int ret = false;
|
||||||
|
@ -720,7 +726,7 @@ static int Sys_CheckChRoot(void)
|
||||||
//three ways to use this:
|
//three ways to use this:
|
||||||
//nonroot-with-SUID-root -- chroots+drops to a fixed path when run as a regular user. the homedir mechanism can be used for writing files.
|
//nonroot-with-SUID-root -- chroots+drops to a fixed path when run as a regular user. the homedir mechanism can be used for writing files.
|
||||||
//root -chroot foo -uid bar -- requires root, changes the filesystem and then switches user rights before starting the game itself.
|
//root -chroot foo -uid bar -- requires root, changes the filesystem and then switches user rights before starting the game itself.
|
||||||
//root -chroot foo -- requires root,changes the filesystem and
|
//root -chroot foo -- requires root, changes the filesystem and leaves the process with far far too many rights
|
||||||
|
|
||||||
uid_t ruid, euid, suid;
|
uid_t ruid, euid, suid;
|
||||||
int arg = COM_CheckParm("-chroot");
|
int arg = COM_CheckParm("-chroot");
|
||||||
|
@ -735,18 +741,18 @@ static int Sys_CheckChRoot(void)
|
||||||
//this means we can't allow
|
//this means we can't allow
|
||||||
//FIXME other games. should use the list in fs.c
|
//FIXME other games. should use the list in fs.c
|
||||||
if (COM_CheckParm("-quake"))
|
if (COM_CheckParm("-quake"))
|
||||||
newroot = "/usr/share/quake";
|
newroot = "/usr/share/games/quake";
|
||||||
else if (COM_CheckParm("-quake2"))
|
else if (COM_CheckParm("-quake2"))
|
||||||
newroot = "/usr/share/quake2";
|
newroot = "/usr/share/games/quake2";
|
||||||
else if (COM_CheckParm("-quake3"))
|
else if (COM_CheckParm("-quake3"))
|
||||||
newroot = "/usr/share/quake3";
|
newroot = "/usr/share/games/quake3";
|
||||||
else if (COM_CheckParm("-hexen2") || COM_CheckParm("-portals"))
|
else if (COM_CheckParm("-hexen2") || COM_CheckParm("-portals"))
|
||||||
newroot = "/usr/share/hexen2";
|
newroot = "/usr/share/games/hexen2";
|
||||||
else
|
else
|
||||||
#ifdef GAME_SHORTNAME
|
#ifdef GAME_SHORTNAME
|
||||||
newroot = "/usr/share/" GAME_SHORTNAME;
|
newroot = "/usr/share/games/" GAME_SHORTNAME;
|
||||||
#else
|
#else
|
||||||
newroot = "/usr/share/quake";
|
newroot = "/usr/share/games/quake";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//just read the environment name
|
//just read the environment name
|
||||||
|
@ -765,11 +771,19 @@ static int Sys_CheckChRoot(void)
|
||||||
//make sure there's no suid programs in the new root dir that might get confused by /etc/ being something else.
|
//make sure there's no suid programs in the new root dir that might get confused by /etc/ being something else.
|
||||||
//this binary MUST NOT be inside the new root.
|
//this binary MUST NOT be inside the new root.
|
||||||
|
|
||||||
|
//make sure we don't crash on any con_printfs.
|
||||||
|
#ifdef MULTITHREAD
|
||||||
|
Sys_ThreadsInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
//FIXME: should we temporarily try swapping uid+euid so we don't have any more access than a non-suid binary for this initial init stuff?
|
//FIXME: should we temporarily try swapping uid+euid so we don't have any more access than a non-suid binary for this initial init stuff?
|
||||||
struct addrinfo *info;
|
struct addrinfo *info;
|
||||||
if (getaddrinfo("localhost", NULL, NULL, &info) == 0) //make sure we've loaded /etc/resolv.conf etc, otherwise any dns requests are going to fail.
|
if (getaddrinfo("master.quakeservers.net", NULL, NULL, &info) == 0) //make sure we've loaded /etc/resolv.conf etc, otherwise any dns requests are going to fail, which would mean no masters.
|
||||||
freeaddrinfo(info);
|
freeaddrinfo(info);
|
||||||
|
|
||||||
|
#ifdef SQL
|
||||||
|
SQL_Available();
|
||||||
|
#endif
|
||||||
#ifdef HAVE_GNUTLS
|
#ifdef HAVE_GNUTLS
|
||||||
SSL_InitGlobal(false); //we need to load the known CA certs while we still can, as well as any shared objects
|
SSL_InitGlobal(false); //we need to load the known CA certs while we still can, as well as any shared objects
|
||||||
//SSL_InitGlobal(true); //make sure we load our public cert from outside the sandbox. an exploit might still be able to find it in memory though. FIXME: disabled in case this reads from somewhere bad - we're still root.
|
//SSL_InitGlobal(true); //make sure we load our public cert from outside the sandbox. an exploit might still be able to find it in memory though. FIXME: disabled in case this reads from somewhere bad - we're still root.
|
||||||
|
@ -864,6 +878,12 @@ int main(int argc, char *argv[])
|
||||||
parms.manifest = CONFIG_MANIFEST_TEXT;
|
parms.manifest = CONFIG_MANIFEST_TEXT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//decide if we should be printing colours to the stdout or not.
|
||||||
|
if (!COM_CheckParm("-nocolour")||!COM_CheckParm("-nocolor"))
|
||||||
|
useansicolours = false;
|
||||||
|
else
|
||||||
|
useansicolours = (isatty(STDOUT_FILENO) || !COM_CheckParm("-colour")||!COM_CheckParm("-color"));
|
||||||
|
|
||||||
switch(Sys_CheckChRoot())
|
switch(Sys_CheckChRoot())
|
||||||
{
|
{
|
||||||
case true:
|
case true:
|
||||||
|
|
|
@ -584,6 +584,16 @@ void QDECL World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers)
|
||||||
VectorAdd (ent->v->origin, ent->v->maxs, ent->v->absmax);
|
VectorAdd (ent->v->origin, ent->v->maxs, ent->v->absmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//some fancy things can mean the ent's aabb is larger than its collision box.
|
||||||
|
#ifdef USERBE
|
||||||
|
// if (ent->rbe.body.body)
|
||||||
|
// w->rbe->ExpandBodyAABB(w->rbe, &ent->rbe.body, ent->v->absmin, env->v->absmax);
|
||||||
|
#endif
|
||||||
|
#ifdef SKELETALOBJECTS
|
||||||
|
if (ent->xv->skeletonindex)
|
||||||
|
skel_updateentbounds(ent);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ent->v->solid)
|
if (!ent->v->solid)
|
||||||
ent->solidsize = ES_SOLID_BSP;
|
ent->solidsize = ES_SOLID_BSP;
|
||||||
else// if (1)///*ent->v->modelindex || */ent->v->model)
|
else// if (1)///*ent->v->modelindex || */ent->v->model)
|
||||||
|
@ -2793,10 +2803,10 @@ static qboolean GenerateCollisionMesh_BSP(world_t *world, model_t *mod, wedict_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ed->ode.ode_element3i = ptr_elements;
|
ed->rbe.element3i = ptr_elements;
|
||||||
ed->ode.ode_vertex3f = ptr_verts;
|
ed->rbe.vertex3f = ptr_verts;
|
||||||
ed->ode.ode_numvertices = numverts;
|
ed->rbe.numvertices = numverts;
|
||||||
ed->ode.ode_numtriangles = numindexes/3;
|
ed->rbe.numtriangles = numindexes/3;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2859,10 +2869,10 @@ static qboolean GenerateCollisionMesh_Alias(world_t *world, model_t *mod, wedict
|
||||||
|
|
||||||
Alias_FlushCache(); //it got built using an entity on the stack, make sure other stuff doesn't get hurt.
|
Alias_FlushCache(); //it got built using an entity on the stack, make sure other stuff doesn't get hurt.
|
||||||
|
|
||||||
ed->ode.ode_element3i = ptr_elements;
|
ed->rbe.element3i = ptr_elements;
|
||||||
ed->ode.ode_vertex3f = ptr_verts;
|
ed->rbe.vertex3f = ptr_verts;
|
||||||
ed->ode.ode_numvertices = numverts;
|
ed->rbe.numvertices = numverts;
|
||||||
ed->ode.ode_numtriangles = numindexes/3;
|
ed->rbe.numtriangles = numindexes/3;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2872,22 +2882,22 @@ static void CollisionMesh_CleanupMesh(wedict_t *ed)
|
||||||
float *v1, *v2, *v3;
|
float *v1, *v2, *v3;
|
||||||
vec3_t d1, d2, cr;
|
vec3_t d1, d2, cr;
|
||||||
int in, out;
|
int in, out;
|
||||||
for (in = 0, out = 0; in < ed->ode.ode_numtriangles*3; in+=3)
|
for (in = 0, out = 0; in < ed->rbe.numtriangles*3; in+=3)
|
||||||
{
|
{
|
||||||
v1 = &ed->ode.ode_vertex3f[ed->ode.ode_element3i[in+0]*3];
|
v1 = &ed->rbe.vertex3f[ed->rbe.element3i[in+0]*3];
|
||||||
v2 = &ed->ode.ode_vertex3f[ed->ode.ode_element3i[in+1]*3];
|
v2 = &ed->rbe.vertex3f[ed->rbe.element3i[in+1]*3];
|
||||||
v3 = &ed->ode.ode_vertex3f[ed->ode.ode_element3i[in+2]*3];
|
v3 = &ed->rbe.vertex3f[ed->rbe.element3i[in+2]*3];
|
||||||
VectorSubtract(v3, v1, d1);
|
VectorSubtract(v3, v1, d1);
|
||||||
VectorSubtract(v2, v1, d2);
|
VectorSubtract(v2, v1, d2);
|
||||||
CrossProduct(d1, d2, cr);
|
CrossProduct(d1, d2, cr);
|
||||||
if (DotProduct(cr,cr) == 0)
|
if (DotProduct(cr,cr) == 0)
|
||||||
continue;
|
continue;
|
||||||
ed->ode.ode_element3i[out+0] = ed->ode.ode_element3i[in+0];
|
ed->rbe.element3i[out+0] = ed->rbe.element3i[in+0];
|
||||||
ed->ode.ode_element3i[out+1] = ed->ode.ode_element3i[in+1];
|
ed->rbe.element3i[out+1] = ed->rbe.element3i[in+1];
|
||||||
ed->ode.ode_element3i[out+2] = ed->ode.ode_element3i[in+2];
|
ed->rbe.element3i[out+2] = ed->rbe.element3i[in+2];
|
||||||
out+=3;
|
out+=3;
|
||||||
}
|
}
|
||||||
ed->ode.ode_numtriangles = out/3;
|
ed->rbe.numtriangles = out/3;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean QDECL World_GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter)
|
qboolean QDECL World_GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter)
|
||||||
|
@ -2912,19 +2922,19 @@ qboolean QDECL World_GenerateCollisionMesh(world_t *world, model_t *mod, wedict_
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
CollisionMesh_CleanupMesh(ed);
|
CollisionMesh_CleanupMesh(ed);
|
||||||
if (ed->ode.ode_numtriangles > 0)
|
if (ed->rbe.numtriangles > 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void QDECL World_ReleaseCollisionMesh(wedict_t *ed)
|
void QDECL World_ReleaseCollisionMesh(wedict_t *ed)
|
||||||
{
|
{
|
||||||
BZ_Free(ed->ode.ode_element3i);
|
BZ_Free(ed->rbe.element3i);
|
||||||
ed->ode.ode_element3i = NULL;
|
ed->rbe.element3i = NULL;
|
||||||
BZ_Free(ed->ode.ode_vertex3f);
|
BZ_Free(ed->rbe.vertex3f);
|
||||||
ed->ode.ode_vertex3f = NULL;
|
ed->rbe.vertex3f = NULL;
|
||||||
ed->ode.ode_numvertices = 0;
|
ed->rbe.numvertices = 0;
|
||||||
ed->ode.ode_numtriangles = 0;
|
ed->rbe.numtriangles = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
!!permu FOG
|
!!permu FOG
|
||||||
!!cvarf r_wateralpha
|
!!cvarf r_wateralpha
|
||||||
!!samps diffuse
|
!!samps diffuse lightmap
|
||||||
|
|
||||||
#include "sys/defs.h"
|
#include "sys/defs.h"
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
#include "sys/fog.h"
|
#include "sys/fog.h"
|
||||||
varying vec2 tc;
|
varying vec2 tc;
|
||||||
|
#ifdef LIT
|
||||||
|
varying vec2 lm0;
|
||||||
|
#endif
|
||||||
#ifdef VERTEX_SHADER
|
#ifdef VERTEX_SHADER
|
||||||
void main ()
|
void main ()
|
||||||
{
|
{
|
||||||
|
@ -16,6 +19,9 @@ void main ()
|
||||||
#ifdef FLOW
|
#ifdef FLOW
|
||||||
tc.s += e_time * -0.5;
|
tc.s += e_time * -0.5;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef LIT
|
||||||
|
lm0 = v_lmcoord;
|
||||||
|
#endif
|
||||||
gl_Position = ftetransform();
|
gl_Position = ftetransform();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +38,11 @@ void main ()
|
||||||
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
|
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
|
||||||
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
|
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
|
||||||
vec3 ts = vec3(texture2D(s_diffuse, ntc));
|
vec3 ts = vec3(texture2D(s_diffuse, ntc));
|
||||||
|
|
||||||
|
#ifdef LIT
|
||||||
|
ts *= (texture2D(s_lightmap, lm0) * e_lmscale).rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
gl_FragColor = fog4(vec4(ts, USEALPHA));
|
gl_FragColor = fog4(vec4(ts, USEALPHA));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
#ifdef REFLECTCUBEMASK
|
#ifdef REFLECTCUBEMASK
|
||||||
varying mat3 invsurface;
|
varying mat3 invsurface;
|
||||||
#endif
|
#endif
|
||||||
#if defined(PCF) || defined(CUBE) || defined(SPOT)
|
#if defined(PCF) || defined(CUBE) || defined(SPOT) || defined(ORTHO)
|
||||||
varying vec4 vtexprojcoord;
|
varying vec4 vtexprojcoord;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,15 +68,22 @@ void main ()
|
||||||
vec3 n, s, t, w;
|
vec3 n, s, t, w;
|
||||||
gl_Position = skeletaltransform_wnst(w,n,s,t);
|
gl_Position = skeletaltransform_wnst(w,n,s,t);
|
||||||
tcbase = v_texcoord; //pass the texture coords straight through
|
tcbase = v_texcoord; //pass the texture coords straight through
|
||||||
|
#ifdef ORTHO
|
||||||
|
vec3 lightminusvertex = -l_lightdirection;
|
||||||
|
lightvector.x = dot(lightminusvertex, s.xyz);
|
||||||
|
lightvector.y = dot(lightminusvertex, t.xyz);
|
||||||
|
lightvector.z = dot(lightminusvertex, n.xyz);
|
||||||
|
#else
|
||||||
vec3 lightminusvertex = l_lightposition - w.xyz;
|
vec3 lightminusvertex = l_lightposition - w.xyz;
|
||||||
#ifdef NOBUMP
|
#ifdef NOBUMP
|
||||||
//the only important thing is distance
|
//the only important thing is distance
|
||||||
lightvector = lightminusvertex;
|
lightvector = lightminusvertex;
|
||||||
#else
|
#else
|
||||||
//the light direction relative to the surface normal, for bumpmapping.
|
//the light direction relative to the surface normal, for bumpmapping.
|
||||||
lightvector.x = dot(lightminusvertex, s.xyz);
|
lightvector.x = dot(lightminusvertex, s.xyz);
|
||||||
lightvector.y = dot(lightminusvertex, t.xyz);
|
lightvector.y = dot(lightminusvertex, t.xyz);
|
||||||
lightvector.z = dot(lightminusvertex, n.xyz);
|
lightvector.z = dot(lightminusvertex, n.xyz);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(VERTEXCOLOURS)
|
#if defined(VERTEXCOLOURS)
|
||||||
vc = v_colour;
|
vc = v_colour;
|
||||||
|
@ -92,7 +99,7 @@ void main ()
|
||||||
invsurface[1] = v_tvector;
|
invsurface[1] = v_tvector;
|
||||||
invsurface[2] = v_normal;
|
invsurface[2] = v_normal;
|
||||||
#endif
|
#endif
|
||||||
#if defined(PCF) || defined(SPOT) || defined(CUBE)
|
#if defined(PCF) || defined(SPOT) || defined(CUBE) || defined(ORTHO)
|
||||||
//for texture projections/shadowmapping on dlights
|
//for texture projections/shadowmapping on dlights
|
||||||
vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));
|
vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));
|
||||||
#endif
|
#endif
|
||||||
|
@ -184,7 +191,7 @@ void main()
|
||||||
vec3 t2 = w - dot(w-t_vertex[2],t_normal[2])*t_normal[2];
|
vec3 t2 = w - dot(w-t_vertex[2],t_normal[2])*t_normal[2];
|
||||||
w = w*(1.0-factor) + factor*(gl_TessCoord.x*t0+gl_TessCoord.y*t1+gl_TessCoord.z*t2);
|
w = w*(1.0-factor) + factor*(gl_TessCoord.x*t0+gl_TessCoord.y*t1+gl_TessCoord.z*t2);
|
||||||
|
|
||||||
#if defined(PCF) || defined(SPOT) || defined(CUBE)
|
#if defined(PCF) || defined(SPOT) || defined(CUBE) || defined(ORTHO)
|
||||||
//for texture projections/shadowmapping on dlights
|
//for texture projections/shadowmapping on dlights
|
||||||
vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));
|
vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));
|
||||||
#endif
|
#endif
|
||||||
|
@ -309,8 +316,7 @@ void main ()
|
||||||
diff *= vc.rgb * vc.a;
|
diff *= vc.rgb * vc.a;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);
|
gl_FragColor = vec4(fog3additive(diff*colorscale*l_lightcolour), 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,7 @@ enum {
|
||||||
#define PEXT2_MAXPLAYERS 0x00000010 //Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues.
|
#define PEXT2_MAXPLAYERS 0x00000010 //Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues.
|
||||||
#define PEXT2_PREDINFO 0x00000020 //movevar stats, NQ input sequences+acks.
|
#define PEXT2_PREDINFO 0x00000020 //movevar stats, NQ input sequences+acks.
|
||||||
#define PEXT2_NEWSIZEENCODING 0x00000040 //richer size encoding.
|
#define PEXT2_NEWSIZEENCODING 0x00000040 //richer size encoding.
|
||||||
|
#define PEXT2_INFOBLOBS 0x00000080 //serverinfo+userinfo lengths can be MUCH higher (protocol is unbounded, but expect low sanity limits on userinfo), and contain nulls etc.
|
||||||
//#define PEXT2_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs)
|
//#define PEXT2_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,14 @@
|
||||||
|
|
||||||
#define HAVE_DECOUPLED_API (LIBAVCODEC_VERSION_MAJOR>57 || (LIBAVCODEC_VERSION_MAJOR==57&&LIBAVCODEC_VERSION_MINOR>=36))
|
#define HAVE_DECOUPLED_API (LIBAVCODEC_VERSION_MAJOR>57 || (LIBAVCODEC_VERSION_MAJOR==57&&LIBAVCODEC_VERSION_MINOR>=36))
|
||||||
|
|
||||||
|
//crappy compat crap
|
||||||
|
#ifndef AV_CODEC_FLAG_GLOBAL_HEADER
|
||||||
|
#define AV_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER
|
||||||
|
#endif
|
||||||
|
#ifndef AV_ERROR_MAX_STRING_SIZE
|
||||||
|
#define AV_ERROR_MAX_STRING_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Most of the logic in here came from here:
|
Most of the logic in here came from here:
|
||||||
http://svn.gnumonks.org/tags/21c3-video/upstream/ffmpeg-0.4.9-pre1/output_example.c
|
http://svn.gnumonks.org/tags/21c3-video/upstream/ffmpeg-0.4.9-pre1/output_example.c
|
||||||
|
|
|
@ -88,7 +88,7 @@ typedef struct bulletcontext_s
|
||||||
{
|
{
|
||||||
rigidbodyengine_t funcs;
|
rigidbodyengine_t funcs;
|
||||||
|
|
||||||
qboolean hasextraobjs;
|
bool hasextraobjs;
|
||||||
// void *ode_space;
|
// void *ode_space;
|
||||||
// void *ode_contactgroup;
|
// void *ode_contactgroup;
|
||||||
// number of constraint solver iterations to use (for dWorldStepFast)
|
// number of constraint solver iterations to use (for dWorldStepFast)
|
||||||
|
@ -158,10 +158,10 @@ static void QDECL World_Bullet_End(world_t *world)
|
||||||
|
|
||||||
static void QDECL World_Bullet_RemoveJointFromEntity(world_t *world, wedict_t *ed)
|
static void QDECL World_Bullet_RemoveJointFromEntity(world_t *world, wedict_t *ed)
|
||||||
{
|
{
|
||||||
ed->ode.ode_joint_type = 0;
|
ed->rbe.joint_type = 0;
|
||||||
// if(ed->ode.ode_joint)
|
// if(ed->rbe.joint)
|
||||||
// dJointDestroy((dJointID)ed->ode.ode_joint);
|
// dJointDestroy((dJointID)ed->rbe.joint);
|
||||||
ed->ode.ode_joint = NULL;
|
ed->rbe.joint.joint = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QDECL World_Bullet_RemoveFromEntity(world_t *world, wedict_t *ed)
|
static void QDECL World_Bullet_RemoveFromEntity(world_t *world, wedict_t *ed)
|
||||||
|
@ -169,27 +169,27 @@ static void QDECL World_Bullet_RemoveFromEntity(world_t *world, wedict_t *ed)
|
||||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||||
btRigidBody *body;
|
btRigidBody *body;
|
||||||
btCollisionShape *geom;
|
btCollisionShape *geom;
|
||||||
if (!ed->ode.ode_physics)
|
if (!ed->rbe.physics)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// entity is not physics controlled, free any physics data
|
// entity is not physics controlled, free any physics data
|
||||||
ed->ode.ode_physics = qfalse;
|
ed->rbe.physics = qfalse;
|
||||||
|
|
||||||
body = (btRigidBody*)ed->ode.ode_body;
|
body = (btRigidBody*)ed->rbe.body.body;
|
||||||
ed->ode.ode_body = NULL;
|
ed->rbe.body = NULL;
|
||||||
if (body)
|
if (body)
|
||||||
ctx->dworld->removeRigidBody (body);
|
ctx->dworld->removeRigidBody (body);
|
||||||
|
|
||||||
geom = (btCollisionShape*)ed->ode.ode_geom;
|
geom = (btCollisionShape*)ed->rbe.geom;
|
||||||
ed->ode.ode_geom = NULL;
|
ed->rbe.geom = NULL;
|
||||||
if (ed->ode.ode_geom)
|
if (ed->rbe.geom)
|
||||||
delete geom;
|
delete geom;
|
||||||
|
|
||||||
//FIXME: joints
|
//FIXME: joints
|
||||||
rbefuncs->ReleaseCollisionMesh(ed);
|
rbefuncs->ReleaseCollisionMesh(ed);
|
||||||
if(ed->ode.ode_massbuf)
|
if(ed->rbe.massbuf)
|
||||||
BZ_Free(ed->ode.ode_massbuf);
|
BZ_Free(ed->rbe.massbuf);
|
||||||
ed->ode.ode_massbuf = NULL;
|
ed->rbe.massbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
|
@ -202,7 +202,7 @@ static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
const float *o;
|
const float *o;
|
||||||
const float *r; // for some reason dBodyGetRotation returns a [3][4] matrix
|
const float *r; // for some reason dBodyGetRotation returns a [3][4] matrix
|
||||||
const float *vel;
|
const float *vel;
|
||||||
btRigidBody *body = (btRigidBody*)ed->ode.ode_body;
|
btRigidBody *body = (btRigidBody*)ed->rbe.body;
|
||||||
int movetype;
|
int movetype;
|
||||||
float bodymatrix[16];
|
float bodymatrix[16];
|
||||||
float entitymatrix[16];
|
float entitymatrix[16];
|
||||||
|
@ -260,7 +260,7 @@ static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
VectorCopy(avel, spinvelocity);
|
VectorCopy(avel, spinvelocity);
|
||||||
trans.getBasis().getOpenGLSubMatrix(bodymatrix);
|
trans.getBasis().getOpenGLSubMatrix(bodymatrix);
|
||||||
foo Matrix4x4_RM_FromVectors(bodymatrix, forward, left, up, origin);
|
foo Matrix4x4_RM_FromVectors(bodymatrix, forward, left, up, origin);
|
||||||
foo Matrix4_Multiply(ed->ode.ode_offsetimatrix, bodymatrix, entitymatrix);
|
foo Matrix4_Multiply(ed->rbe.offsetimatrix, bodymatrix, entitymatrix);
|
||||||
foo Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
|
foo Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
|
||||||
|
|
||||||
VectorAngles(forward, up, angles);
|
VectorAngles(forward, up, angles);
|
||||||
|
@ -290,11 +290,11 @@ static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||||
VectorCopy(avelocity, ed->v->avelocity);
|
VectorCopy(avelocity, ed->v->avelocity);
|
||||||
|
|
||||||
// values for BodyFromEntity to check if the qc modified anything later
|
// values for BodyFromEntity to check if the qc modified anything later
|
||||||
VectorCopy(origin, ed->ode.ode_origin);
|
VectorCopy(origin, ed->rbe.origin);
|
||||||
VectorCopy(velocity, ed->ode.ode_velocity);
|
VectorCopy(velocity, ed->rbe.velocity);
|
||||||
VectorCopy(angles, ed->ode.ode_angles);
|
VectorCopy(angles, ed->rbe.angles);
|
||||||
VectorCopy(avelocity, ed->ode.ode_avelocity);
|
VectorCopy(avelocity, ed->rbe.avelocity);
|
||||||
// ed->ode.ode_gravity = (qboolean)dBodyGetGravityMode(body);
|
// ed->rbe.gravity = (qboolean)dBodyGetGravityMode(body);
|
||||||
|
|
||||||
World_LinkEdict(world, ed, true);
|
World_LinkEdict(world, ed, true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -352,11 +352,11 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
jointtype = 0; // can't have both
|
jointtype = 0; // can't have both
|
||||||
|
|
||||||
e1 = (wedict_t*)PROG_TO_EDICT(world->progs, enemy);
|
e1 = (wedict_t*)PROG_TO_EDICT(world->progs, enemy);
|
||||||
b1 = (btRigidBody*)e1->ode.ode_body;
|
b1 = (btRigidBody*)e1->rbe.body;
|
||||||
if(ED_ISFREE(e1) || !b1)
|
if(ED_ISFREE(e1) || !b1)
|
||||||
enemy = 0;
|
enemy = 0;
|
||||||
e2 = (wedict_t*)PROG_TO_EDICT(world->progs, aiment);
|
e2 = (wedict_t*)PROG_TO_EDICT(world->progs, aiment);
|
||||||
b2 = (btRigidBody*)e2->ode.ode_body;
|
b2 = (btRigidBody*)e2->rbe.body;
|
||||||
if(ED_ISFREE(e2) || !b2)
|
if(ED_ISFREE(e2) || !b2)
|
||||||
aiment = 0;
|
aiment = 0;
|
||||||
// see http://www.ode.org/old_list_archives/2006-January/017614.html
|
// see http://www.ode.org/old_list_archives/2006-January/017614.html
|
||||||
|
@ -389,14 +389,14 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
// FMax = 0;
|
// FMax = 0;
|
||||||
Stop = BT_INFINITY;
|
Stop = BT_INFINITY;
|
||||||
}
|
}
|
||||||
if(jointtype == ed->ode.ode_joint_type && VectorCompare(origin, ed->ode.ode_joint_origin) && VectorCompare(velocity, ed->ode.ode_joint_velocity) && VectorCompare(ed->v->angles, ed->ode.ode_joint_angles) && enemy == ed->ode.ode_joint_enemy && aiment == ed->ode.ode_joint_aiment && VectorCompare(movedir, ed->ode.ode_joint_movedir))
|
if(jointtype == ed->rbe.joint_type && VectorCompare(origin, ed->rbe.joint_origin) && VectorCompare(velocity, ed->rbe.joint_velocity) && VectorCompare(ed->v->angles, ed->rbe.joint_angles) && enemy == ed->rbe.joint_enemy && aiment == ed->rbe.joint_aiment && VectorCompare(movedir, ed->rbe.joint_movedir))
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
|
|
||||||
if(ed->ode.ode_joint)
|
if(ed->rbe.joint)
|
||||||
{
|
{
|
||||||
j = (btTypedConstraint*)ed->ode.ode_joint;
|
j = (btTypedConstraint*)ed->rbe.joint;
|
||||||
rbe->dworld->removeConstraint(j);
|
rbe->dworld->removeConstraint(j);
|
||||||
ed->ode.ode_joint = NULL;
|
ed->rbe.joint = NULL;
|
||||||
delete j;
|
delete j;
|
||||||
}
|
}
|
||||||
if (!jointtype)
|
if (!jointtype)
|
||||||
|
@ -408,13 +408,13 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
if(aiment)
|
if(aiment)
|
||||||
b2org.setValue(e2->v->origin[0], e2->v->origin[1], e2->v->origin[2]);
|
b2org.setValue(e2->v->origin[0], e2->v->origin[1], e2->v->origin[2]);
|
||||||
|
|
||||||
ed->ode.ode_joint_type = jointtype;
|
ed->rbe.joint_type = jointtype;
|
||||||
ed->ode.ode_joint_enemy = enemy;
|
ed->rbe.joint_enemy = enemy;
|
||||||
ed->ode.ode_joint_aiment = aiment;
|
ed->rbe.joint_aiment = aiment;
|
||||||
VectorCopy(origin, ed->ode.ode_joint_origin);
|
VectorCopy(origin, ed->rbe.joint_origin);
|
||||||
VectorCopy(velocity, ed->ode.ode_joint_velocity);
|
VectorCopy(velocity, ed->rbe.joint_velocity);
|
||||||
VectorCopy(ed->v->angles, ed->ode.ode_joint_angles);
|
VectorCopy(ed->v->angles, ed->rbe.joint_angles);
|
||||||
VectorCopy(movedir, ed->ode.ode_joint_movedir);
|
VectorCopy(movedir, ed->rbe.joint_movedir);
|
||||||
|
|
||||||
rbefuncs->AngleVectors(ed->v->angles, forward, NULL, NULL);
|
rbefuncs->AngleVectors(ed->v->angles, forward, NULL, NULL);
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ed->ode.ode_joint = (void *) j;
|
ed->rbe.joint = (void *) j;
|
||||||
if (j)
|
if (j)
|
||||||
{
|
{
|
||||||
j->setUserConstraintPtr((void *) ed);
|
j->setUserConstraintPtr((void *) ed);
|
||||||
|
@ -531,76 +531,136 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static qboolean QDECL World_Bullet_RagMatrixToBody(rbebody_t *bodyptr, float *mat)
|
static void MatToTransform(const float *mat, btTransform &tr)
|
||||||
{
|
{
|
||||||
btRigidBody *body;
|
tr.setBasis(btMatrix3x3(
|
||||||
|
mat[0], mat[1], mat[2],
|
||||||
/*
|
mat[3], mat[4], mat[5],
|
||||||
dVector3 r[3];
|
mat[6], mat[7], mat[8]));
|
||||||
|
tr.setOrigin(btVector3(mat[9], mat[10], mat[11]));
|
||||||
r[0][0] = mat[0];
|
}
|
||||||
r[0][1] = mat[1];
|
static void MatFromTransform(float *mat, const btTransform &tr)
|
||||||
r[0][2] = mat[2];
|
{
|
||||||
r[1][0] = mat[4];
|
const btMatrix3x3 &m = tr.getBasis();
|
||||||
r[1][1] = mat[5];
|
const btVector3 &o = tr.getOrigin();
|
||||||
r[1][2] = mat[6];
|
const btVector3 &r0 = m.getRow(0);
|
||||||
r[2][0] = mat[8];
|
const btVector3 &r1 = m.getRow(1);
|
||||||
r[2][1] = mat[9];
|
const btVector3 &r2 = m.getRow(2);
|
||||||
r[2][2] = mat[10];
|
mat[0] = r0[0];
|
||||||
|
mat[1] = r0[1];
|
||||||
dBodySetPosition(bodyptr->ode_body, mat[3], mat[7], mat[11]);
|
mat[2] = r0[2];
|
||||||
dBodySetRotation(bodyptr->ode_body, r[0]);
|
mat[3] = r1[0];
|
||||||
dBodySetLinearVel(bodyptr->ode_body, 0, 0, 0);
|
mat[4] = r1[1];
|
||||||
dBodySetAngularVel(bodyptr->ode_body, 0, 0, 0);
|
mat[5] = r1[2];
|
||||||
*/
|
mat[6] = r2[0];
|
||||||
|
mat[7] = r2[1];
|
||||||
|
mat[8] = r2[2];
|
||||||
|
mat[9] = o[0];
|
||||||
|
mat[10] = o[1];
|
||||||
|
mat[11] = o[2];
|
||||||
|
}
|
||||||
|
static qboolean QDECL World_Bullet_RagMatrixToBody(rbebody_t *bodyptr, float *mat)
|
||||||
|
{ //mat is a 4*3 matrix
|
||||||
|
btTransform tr;
|
||||||
|
btRigidBody *body = (btRigidBody*)bodyptr->body;
|
||||||
|
MatToTransform(mat, tr);
|
||||||
|
body->setWorldTransform(tr);
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *bodyptr, rbebodyinfo_t *bodyinfo, float *mat, wedict_t *ent)
|
static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *bodyptr, rbebodyinfo_t *bodyinfo, float *mat, wedict_t *ent)
|
||||||
{
|
{
|
||||||
/*
|
btRigidBody *body = NULL;
|
||||||
dMass mass;
|
btCollisionShape *geom = NULL;
|
||||||
float radius;
|
float radius, length;
|
||||||
if (!world->ode.ode_space)
|
bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||||
return false;
|
int axisindex;
|
||||||
world->ode.hasodeents = true; //I don't like this, but we need the world etc to be solid.
|
ctx->hasextraobjs = true;
|
||||||
world->ode.hasextraobjs = true;
|
|
||||||
|
|
||||||
switch(bodyinfo->geomshape)
|
switch(bodyinfo->geomshape)
|
||||||
{
|
{
|
||||||
case GEOMTYPE_CAPSULE:
|
/*
|
||||||
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5;
|
case GEOMTYPE_TRIMESH:
|
||||||
bodyptr->ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, bodyinfo->dimensions[2]);
|
// foo Matrix4x4_Identity(ed->rbe.offsetmatrix);
|
||||||
dMassSetCapsuleTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]);
|
geom = NULL;
|
||||||
//aligned along the geom's local z axis
|
if (!model)
|
||||||
break;
|
{
|
||||||
case GEOMTYPE_SPHERE:
|
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
|
||||||
//radius
|
if (ed->rbe.physics)
|
||||||
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1] + bodyinfo->dimensions[2]) / 3;
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
bodyptr->ode_geom = dCreateSphere(world->ode.ode_space, radius);
|
return;
|
||||||
dMassSetSphereTotal(&mass, bodyinfo->mass, radius);
|
}
|
||||||
//aligned along the geom's local z axis
|
if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
|
||||||
break;
|
{
|
||||||
case GEOMTYPE_CYLINDER:
|
if (ed->rbe.physics)
|
||||||
//radius, length
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5;
|
return;
|
||||||
bodyptr->ode_geom = dCreateCylinder(world->ode.ode_space, radius, bodyinfo->dimensions[2]);
|
}
|
||||||
dMassSetCylinderTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]);
|
|
||||||
//alignment is irreleevnt, thouse I suppose it might be scaled wierdly.
|
// foo Matrix4x4_RM_CreateTranslate(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
||||||
|
|
||||||
|
{
|
||||||
|
btTriangleIndexVertexArray *tiva = new btTriangleIndexVertexArray();
|
||||||
|
btIndexedMesh mesh;
|
||||||
|
mesh.m_vertexType = PHY_FLOAT;
|
||||||
|
mesh.m_indexType = PHY_INTEGER;
|
||||||
|
mesh.m_numTriangles = ed->rbe.numtriangles;
|
||||||
|
mesh.m_numVertices = ed->rbe.numvertices;
|
||||||
|
mesh.m_triangleIndexBase = (const unsigned char*)ed->rbe.element3i;
|
||||||
|
mesh.m_triangleIndexStride = sizeof(*ed->rbe.element3i)*3;
|
||||||
|
mesh.m_vertexBase = (const unsigned char*)ed->rbe.vertex3f;
|
||||||
|
mesh.m_vertexStride = sizeof(*ed->rbe.vertex3f)*3;
|
||||||
|
tiva->addIndexedMesh(mesh);
|
||||||
|
geom = new btBvhTriangleMeshShape(tiva, true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
|
Con_DPrintf("World_Bullet_RagCreateBody: unsupported geomshape\n", bodyinfo->geomshape);
|
||||||
case GEOMTYPE_BOX:
|
case GEOMTYPE_BOX:
|
||||||
//diameter
|
geom = new btBoxShape(btVector3(bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]) * 0.5);
|
||||||
bodyptr->ode_geom = dCreateBox(world->ode.ode_space, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]);
|
break;
|
||||||
dMassSetBoxTotal(&mass, bodyinfo->mass, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]);
|
|
||||||
//monkey
|
case GEOMTYPE_SPHERE:
|
||||||
|
geom = new btSphereShape(bodyinfo->dimensions[0] * 0.5f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GEOMTYPE_CAPSULE:
|
||||||
|
// case GEOMTYPE_CAPSULE_X:
|
||||||
|
// case GEOMTYPE_CAPSULE_Y:
|
||||||
|
case GEOMTYPE_CAPSULE_Z:
|
||||||
|
radius = (bodyinfo->dimensions[0]+bodyinfo->dimensions[1]) * 0.5f;
|
||||||
|
geom = new btCapsuleShapeZ(radius, bodyinfo->dimensions[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GEOMTYPE_CYLINDER:
|
||||||
|
// case GEOMTYPE_CYLINDER_X:
|
||||||
|
// case GEOMTYPE_CYLINDER_Y:
|
||||||
|
case GEOMTYPE_CYLINDER_Z:
|
||||||
|
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5;
|
||||||
|
geom = new btCylinderShapeZ(btVector3(radius, radius, bodyinfo->dimensions[2])*0.5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bodyptr->ode_body = dBodyCreate(world->ode.ode_world);
|
bodyptr->geom = geom;
|
||||||
dBodySetMass(bodyptr->ode_body, &mass);
|
|
||||||
dGeomSetBody(bodyptr->ode_geom, bodyptr->ode_body);
|
//now create the body too
|
||||||
dGeomSetData(bodyptr->ode_geom, (void*)ent);
|
|
||||||
*/
|
btVector3 fallInertia(0, 0, 0);
|
||||||
return World_Bullet_RagMatrixToBody(bodyptr, mat);
|
((btCollisionShape*)geom)->calculateLocalInertia(bodyinfo->mass, fallInertia);
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(bodyinfo->mass, NULL, (btCollisionShape*)geom, fallInertia);
|
||||||
|
MatToTransform(mat, fallRigidBodyCI.m_startWorldTransform);
|
||||||
|
body = new btRigidBody(fallRigidBodyCI);
|
||||||
|
body->setUserPointer(ent);
|
||||||
|
bodyptr->body = (void*)body;
|
||||||
|
|
||||||
|
//motion threshhold should be speed/physicsframerate.
|
||||||
|
//FIXME: recalculate...
|
||||||
|
body->setCcdMotionThreshold((bodyinfo->dimensions[0]+bodyinfo->dimensions[1]+bodyinfo->dimensions[2])*(4/3));
|
||||||
|
//radius should be the body's radius
|
||||||
|
body->setCcdSweptSphereRadius((bodyinfo->dimensions[0]+bodyinfo->dimensions[1]+bodyinfo->dimensions[2])*(0.5/3));
|
||||||
|
|
||||||
|
ctx->dworld->addRigidBody(body, ent->xv->dimension_solid, ent->xv->dimension_hit);
|
||||||
|
|
||||||
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QDECL World_Bullet_RagMatrixFromJoint(rbejoint_t *joint, rbejointinfo_t *info, float *mat)
|
static void QDECL World_Bullet_RagMatrixFromJoint(rbejoint_t *joint, rbejointinfo_t *info, float *mat)
|
||||||
|
@ -694,24 +754,9 @@ static void QDECL World_Bullet_RagMatrixFromJoint(rbejoint_t *joint, rbejointinf
|
||||||
|
|
||||||
static void QDECL World_Bullet_RagMatrixFromBody(world_t *world, rbebody_t *bodyptr, float *mat)
|
static void QDECL World_Bullet_RagMatrixFromBody(world_t *world, rbebody_t *bodyptr, float *mat)
|
||||||
{
|
{
|
||||||
/*
|
bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||||
const dReal *o = dBodyGetPosition(bodyptr->ode_body);
|
btRigidBody *body = (btRigidBody*)bodyptr->body;
|
||||||
const dReal *r = dBodyGetRotation(bodyptr->ode_body);
|
MatFromTransform(mat, body->getCenterOfMassTransform());
|
||||||
mat[0] = r[0];
|
|
||||||
mat[1] = r[1];
|
|
||||||
mat[2] = r[2];
|
|
||||||
mat[3] = o[0];
|
|
||||||
|
|
||||||
mat[4] = r[4];
|
|
||||||
mat[5] = r[5];
|
|
||||||
mat[6] = r[6];
|
|
||||||
mat[7] = o[1];
|
|
||||||
|
|
||||||
mat[8] = r[8];
|
|
||||||
mat[9] = r[9];
|
|
||||||
mat[10] = r[10];
|
|
||||||
mat[11] = o[2];
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
static void QDECL World_Bullet_RagEnableJoint(rbejoint_t *joint, qboolean enabled)
|
static void QDECL World_Bullet_RagEnableJoint(rbejoint_t *joint, qboolean enabled)
|
||||||
{
|
{
|
||||||
|
@ -728,22 +773,22 @@ static void QDECL World_Bullet_RagCreateJoint(world_t *world, rbejoint_t *joint,
|
||||||
switch(info->type)
|
switch(info->type)
|
||||||
{
|
{
|
||||||
case JOINTTYPE_POINT:
|
case JOINTTYPE_POINT:
|
||||||
joint->ode_joint = dJointCreateBall(world->ode.ode_world, 0);
|
joint->ode_joint = dJointCreateBall(world->rbe.world, 0);
|
||||||
break;
|
break;
|
||||||
case JOINTTYPE_HINGE:
|
case JOINTTYPE_HINGE:
|
||||||
joint->ode_joint = dJointCreateHinge(world->ode.ode_world, 0);
|
joint->ode_joint = dJointCreateHinge(world->rbe.world, 0);
|
||||||
break;
|
break;
|
||||||
case JOINTTYPE_SLIDER:
|
case JOINTTYPE_SLIDER:
|
||||||
joint->ode_joint = dJointCreateSlider(world->ode.ode_world, 0);
|
joint->ode_joint = dJointCreateSlider(world->rbe.world, 0);
|
||||||
break;
|
break;
|
||||||
case JOINTTYPE_UNIVERSAL:
|
case JOINTTYPE_UNIVERSAL:
|
||||||
joint->ode_joint = dJointCreateUniversal(world->ode.ode_world, 0);
|
joint->ode_joint = dJointCreateUniversal(world->rbe.world, 0);
|
||||||
break;
|
break;
|
||||||
case JOINTTYPE_HINGE2:
|
case JOINTTYPE_HINGE2:
|
||||||
joint->ode_joint = dJointCreateHinge2(world->ode.ode_world, 0);
|
joint->ode_joint = dJointCreateHinge2(world->rbe.world, 0);
|
||||||
break;
|
break;
|
||||||
case JOINTTYPE_FIXED:
|
case JOINTTYPE_FIXED:
|
||||||
joint->ode_joint = dJointCreateFixed(world->ode.ode_world, 0);
|
joint->ode_joint = dJointCreateFixed(world->rbe.world, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
joint->ode_joint = NULL;
|
joint->ode_joint = NULL;
|
||||||
|
@ -823,14 +868,20 @@ static void QDECL World_Bullet_RagCreateJoint(world_t *world, rbejoint_t *joint,
|
||||||
|
|
||||||
static void QDECL World_Bullet_RagDestroyBody(world_t *world, rbebody_t *bodyptr)
|
static void QDECL World_Bullet_RagDestroyBody(world_t *world, rbebody_t *bodyptr)
|
||||||
{
|
{
|
||||||
/*
|
bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||||
if (bodyptr->ode_geom)
|
btRigidBody *body = (btRigidBody*)bodyptr->body;
|
||||||
dGeomDestroy(bodyptr->ode_geom);
|
btCollisionShape *geom = (btCollisionShape*)bodyptr->geom;
|
||||||
bodyptr->ode_geom = NULL;
|
|
||||||
if (bodyptr->ode_body)
|
bodyptr->body = NULL;
|
||||||
dBodyDestroy(bodyptr->ode_body);
|
bodyptr->geom = NULL;
|
||||||
bodyptr->ode_body = NULL;
|
|
||||||
*/
|
if (body)
|
||||||
|
{
|
||||||
|
ctx->dworld->removeRigidBody(body);
|
||||||
|
delete body;
|
||||||
|
}
|
||||||
|
if (geom)
|
||||||
|
delete geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QDECL World_Bullet_RagDestroyJoint(world_t *world, rbejoint_t *joint)
|
static void QDECL World_Bullet_RagDestroyJoint(world_t *world, rbejoint_t *joint)
|
||||||
|
@ -859,7 +910,7 @@ public:
|
||||||
btVector3 org;
|
btVector3 org;
|
||||||
rbefuncs->AngleVectors(edict->v->angles, axis[0], axis[1], axis[2]);
|
rbefuncs->AngleVectors(edict->v->angles, axis[0], axis[1], axis[2]);
|
||||||
VectorNegate(axis[1], axis[1]);
|
VectorNegate(axis[1], axis[1]);
|
||||||
VectorAvg(edict->ode.ode_mins, edict->ode.ode_maxs, offset);
|
VectorAvg(edict->rbe.mins, edict->rbe.maxs, offset);
|
||||||
VectorMA(edict->v->origin, offset[0]*1, axis[0], org);
|
VectorMA(edict->v->origin, offset[0]*1, axis[0], org);
|
||||||
VectorMA(org, offset[1]*1, axis[1], org);
|
VectorMA(org, offset[1]*1, axis[1], org);
|
||||||
VectorMA(org, offset[2]*1, axis[2], org);
|
VectorMA(org, offset[2]*1, axis[2], org);
|
||||||
|
@ -895,30 +946,22 @@ public:
|
||||||
VectorCopy(worldTrans.getBasis().getColumn(0), fwd);
|
VectorCopy(worldTrans.getBasis().getColumn(0), fwd);
|
||||||
VectorCopy(worldTrans.getBasis().getColumn(1), left);
|
VectorCopy(worldTrans.getBasis().getColumn(1), left);
|
||||||
VectorCopy(worldTrans.getBasis().getColumn(2), up);
|
VectorCopy(worldTrans.getBasis().getColumn(2), up);
|
||||||
VectorAvg(edict->ode.ode_mins, edict->ode.ode_maxs, offset);
|
VectorAvg(edict->rbe.mins, edict->rbe.maxs, offset);
|
||||||
VectorMA(pos, offset[0]*-1, fwd, pos);
|
VectorMA(pos, offset[0]*-1, fwd, pos);
|
||||||
VectorMA(pos, offset[1]*-1, left, pos);
|
VectorMA(pos, offset[1]*-1, left, pos);
|
||||||
VectorMA(pos, offset[2]*-1, up, edict->v->origin);
|
VectorMA(pos, offset[2]*-1, up, edict->v->origin);
|
||||||
|
|
||||||
rbefuncs->VectorAngles(fwd, up, edict->v->angles, (qboolean)NegativeMeshPitch(world, edict));
|
rbefuncs->VectorAngles(fwd, up, edict->v->angles, (qboolean)NegativeMeshPitch(world, edict));
|
||||||
|
|
||||||
const btVector3 &vel = ((btRigidBody*)edict->ode.ode_body)->getLinearVelocity();
|
const btVector3 &vel = ((btRigidBody*)edict->rbe.body)->getLinearVelocity();
|
||||||
VectorCopy(vel.m_floats, edict->v->velocity);
|
VectorCopy(vel.m_floats, edict->v->velocity);
|
||||||
|
|
||||||
//so it doesn't get rebuilt
|
//so it doesn't get rebuilt
|
||||||
VectorCopy(edict->v->origin, edict->ode.ode_origin);
|
VectorCopy(edict->v->origin, edict->rbe.origin);
|
||||||
VectorCopy(edict->v->angles, edict->ode.ode_angles);
|
VectorCopy(edict->v->angles, edict->rbe.angles);
|
||||||
VectorCopy(edict->v->velocity, edict->ode.ode_velocity);
|
VectorCopy(edict->v->velocity, edict->rbe.velocity);
|
||||||
|
|
||||||
// World_LinkEdict(world, edict, false);
|
//FIXME: relink the ent into the areagrid
|
||||||
|
|
||||||
// if(mSceneNode == nullptr)
|
|
||||||
// return; // silently return before we set a node
|
|
||||||
|
|
||||||
// btQuaternion rot = worldTrans.getRotation();
|
|
||||||
// mSceneNode ->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
|
|
||||||
// btVector3 pos = worldTrans.getOrigin();
|
|
||||||
// mSceneNode ->setPosition(pos.x(), pos.y(), pos.z());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1021,7 +1064,7 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// case GEOMTYPE_NONE:
|
// case GEOMTYPE_NONE:
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_Bullet_RemoveFromEntity(world, ed);
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1030,70 +1073,70 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
if (DotProduct(geomsize,geomsize) == 0)
|
if (DotProduct(geomsize,geomsize) == 0)
|
||||||
{
|
{
|
||||||
// we don't allow point-size physics objects...
|
// we don't allow point-size physics objects...
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_Bullet_RemoveFromEntity(world, ed);
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we need to create or replace the geom
|
// check if we need to create or replace the geom
|
||||||
if (!ed->ode.ode_physics
|
if (!ed->rbe.physics
|
||||||
|| !VectorCompare(ed->ode.ode_mins, entmins)
|
|| !VectorCompare(ed->rbe.mins, entmins)
|
||||||
|| !VectorCompare(ed->ode.ode_maxs, entmaxs)
|
|| !VectorCompare(ed->rbe.maxs, entmaxs)
|
||||||
|| ed->ode.ode_modelindex != modelindex)
|
|| ed->rbe.modelindex != modelindex)
|
||||||
{
|
{
|
||||||
btCollisionShape *geom;
|
btCollisionShape *geom;
|
||||||
|
|
||||||
modified = qtrue;
|
modified = qtrue;
|
||||||
World_Bullet_RemoveFromEntity(world, ed);
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
ed->ode.ode_physics = qtrue;
|
ed->rbe.physics = qtrue;
|
||||||
VectorCopy(entmins, ed->ode.ode_mins);
|
VectorCopy(entmins, ed->rbe.mins);
|
||||||
VectorCopy(entmaxs, ed->ode.ode_maxs);
|
VectorCopy(entmaxs, ed->rbe.maxs);
|
||||||
ed->ode.ode_modelindex = modelindex;
|
ed->rbe.modelindex = modelindex;
|
||||||
VectorAvg(entmins, entmaxs, geomcenter);
|
VectorAvg(entmins, entmaxs, geomcenter);
|
||||||
ed->ode.ode_movelimit = min(geomsize[0], min(geomsize[1], geomsize[2]));
|
ed->rbe.movelimit = min(geomsize[0], min(geomsize[1], geomsize[2]));
|
||||||
|
|
||||||
/* memset(ed->ode.ode_offsetmatrix, 0, sizeof(ed->ode.ode_offsetmatrix));
|
/* memset(ed->rbe.offsetmatrix, 0, sizeof(ed->rbe.offsetmatrix));
|
||||||
ed->ode.ode_offsetmatrix[0] = 1;
|
ed->rbe.offsetmatrix[0] = 1;
|
||||||
ed->ode.ode_offsetmatrix[5] = 1;
|
ed->rbe.offsetmatrix[5] = 1;
|
||||||
ed->ode.ode_offsetmatrix[10] = 1;
|
ed->rbe.offsetmatrix[10] = 1;
|
||||||
ed->ode.ode_offsetmatrix[3] = -geomcenter[0];
|
ed->rbe.offsetmatrix[3] = -geomcenter[0];
|
||||||
ed->ode.ode_offsetmatrix[7] = -geomcenter[1];
|
ed->rbe.offsetmatrix[7] = -geomcenter[1];
|
||||||
ed->ode.ode_offsetmatrix[11] = -geomcenter[2];
|
ed->rbe.offsetmatrix[11] = -geomcenter[2];
|
||||||
*/
|
*/
|
||||||
ed->ode.ode_mass = massval;
|
ed->rbe.mass = massval;
|
||||||
|
|
||||||
switch(geomtype)
|
switch(geomtype)
|
||||||
{
|
{
|
||||||
case GEOMTYPE_TRIMESH:
|
case GEOMTYPE_TRIMESH:
|
||||||
// foo Matrix4x4_Identity(ed->ode.ode_offsetmatrix);
|
// foo Matrix4x4_Identity(ed->rbe.offsetmatrix);
|
||||||
geom = NULL;
|
geom = NULL;
|
||||||
if (!model)
|
if (!model)
|
||||||
{
|
{
|
||||||
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
|
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_Bullet_RemoveFromEntity(world, ed);
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
|
if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter))
|
||||||
{
|
{
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_Bullet_RemoveFromEntity(world, ed);
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// foo Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
// foo Matrix4x4_RM_CreateTranslate(ed->rbe.offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
|
||||||
|
|
||||||
{
|
{
|
||||||
btTriangleIndexVertexArray *tiva = new btTriangleIndexVertexArray();
|
btTriangleIndexVertexArray *tiva = new btTriangleIndexVertexArray();
|
||||||
btIndexedMesh mesh;
|
btIndexedMesh mesh;
|
||||||
mesh.m_vertexType = PHY_FLOAT;
|
mesh.m_vertexType = PHY_FLOAT;
|
||||||
mesh.m_indexType = PHY_INTEGER;
|
mesh.m_indexType = PHY_INTEGER;
|
||||||
mesh.m_numTriangles = ed->ode.ode_numtriangles;
|
mesh.m_numTriangles = ed->rbe.numtriangles;
|
||||||
mesh.m_numVertices = ed->ode.ode_numvertices;
|
mesh.m_numVertices = ed->rbe.numvertices;
|
||||||
mesh.m_triangleIndexBase = (const unsigned char*)ed->ode.ode_element3i;
|
mesh.m_triangleIndexBase = (const unsigned char*)ed->rbe.element3i;
|
||||||
mesh.m_triangleIndexStride = sizeof(*ed->ode.ode_element3i)*3;
|
mesh.m_triangleIndexStride = sizeof(*ed->rbe.element3i)*3;
|
||||||
mesh.m_vertexBase = (const unsigned char*)ed->ode.ode_vertex3f;
|
mesh.m_vertexBase = (const unsigned char*)ed->rbe.vertex3f;
|
||||||
mesh.m_vertexStride = sizeof(*ed->ode.ode_vertex3f)*3;
|
mesh.m_vertexStride = sizeof(*ed->rbe.vertex3f)*3;
|
||||||
tiva->addIndexedMesh(mesh);
|
tiva->addIndexedMesh(mesh);
|
||||||
geom = new btBvhTriangleMeshShape(tiva, true);
|
geom = new btBvhTriangleMeshShape(tiva, true);
|
||||||
}
|
}
|
||||||
|
@ -1167,15 +1210,15 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Con_Printf("World_Bullet_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
|
// Con_Printf("World_Bullet_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
|
||||||
if (ed->ode.ode_physics)
|
if (ed->rbe.physics)
|
||||||
World_Bullet_RemoveFromEntity(world, ed);
|
World_Bullet_RemoveFromEntity(world, ed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Matrix3x4_InvertTo4x4_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix);
|
// Matrix3x4_InvertTo4x4_Simple(ed->rbe.offsetmatrix, ed->rbe.offsetimatrix);
|
||||||
// ed->ode.ode_massbuf = BZ_Malloc(sizeof(dMass));
|
// ed->rbe.massbuf = BZ_Malloc(sizeof(dMass));
|
||||||
// memcpy(ed->ode.ode_massbuf, &mass, sizeof(dMass));
|
// memcpy(ed->rbe.massbuf, &mass, sizeof(dMass));
|
||||||
|
|
||||||
ed->ode.ode_geom = (void *)geom;
|
ed->rbe.geom = (void *)geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
//non-moving objects need to be static objects (and thus need 0 mass)
|
//non-moving objects need to be static objects (and thus need 0 mass)
|
||||||
|
@ -1183,35 +1226,35 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
massval = 0;
|
massval = 0;
|
||||||
|
|
||||||
//if the mass changes, we'll need to create a new body (but not the shape, so invalidate the current one)
|
//if the mass changes, we'll need to create a new body (but not the shape, so invalidate the current one)
|
||||||
if (ed->ode.ode_mass != massval)
|
if (ed->rbe.mass != massval)
|
||||||
{
|
{
|
||||||
ed->ode.ode_mass = massval;
|
ed->rbe.mass = massval;
|
||||||
body = (btRigidBody*)ed->ode.ode_body;
|
body = (btRigidBody*)ed->rbe.body;
|
||||||
if (body)
|
if (body)
|
||||||
ctx->dworld->removeRigidBody(body);
|
ctx->dworld->removeRigidBody(body);
|
||||||
ed->ode.ode_body = NULL;
|
ed->rbe.body = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(ed->ode.ode_geom)
|
// if(ed->rbe.geom)
|
||||||
// dGeomSetData(ed->ode.ode_geom, (void*)ed);
|
// dGeomSetData(ed->rbe.geom, (void*)ed);
|
||||||
if (movetype == MOVETYPE_PHYSICS && ed->ode.ode_mass)
|
if (movetype == MOVETYPE_PHYSICS && ed->rbe.mass)
|
||||||
{
|
{
|
||||||
if (ed->ode.ode_body == NULL)
|
if (ed->rbe.body == NULL)
|
||||||
{
|
{
|
||||||
// ed->ode.ode_body = (void *)(body = dBodyCreate(world->ode.ode_world));
|
// ed->rbe.body = (void *)(body = dBodyCreate(world->rbe.world));
|
||||||
// dGeomSetBody(ed->ode.ode_geom, body);
|
// dGeomSetBody(ed->rbe.geom, body);
|
||||||
// dBodySetData(body, (void*)ed);
|
// dBodySetData(body, (void*)ed);
|
||||||
// dBodySetMass(body, (dMass *) ed->ode.ode_massbuf);
|
// dBodySetMass(body, (dMass *) ed->rbe.massbuf);
|
||||||
|
|
||||||
btVector3 fallInertia(0, 0, 0);
|
btVector3 fallInertia(0, 0, 0);
|
||||||
((btCollisionShape*)ed->ode.ode_geom)->calculateLocalInertia(ed->ode.ode_mass, fallInertia);
|
((btCollisionShape*)ed->rbe.geom)->calculateLocalInertia(ed->rbe.mass, fallInertia);
|
||||||
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(ed->ode.ode_mass, new QCMotionState(ed,world), (btCollisionShape*)ed->ode.ode_geom, fallInertia);
|
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(ed->rbe.mass, new QCMotionState(ed,world), (btCollisionShape*)ed->rbe.geom, fallInertia);
|
||||||
body = new btRigidBody(fallRigidBodyCI);
|
body = new btRigidBody(fallRigidBodyCI);
|
||||||
body->setUserPointer(ed);
|
body->setUserPointer(ed);
|
||||||
// btTransform trans;
|
// btTransform trans;
|
||||||
// trans.setFromOpenGLMatrix(ed->ode.ode_offsetmatrix);
|
// trans.setFromOpenGLMatrix(ed->rbe.offsetmatrix);
|
||||||
// body->setCenterOfMassTransform(trans);
|
// body->setCenterOfMassTransform(trans);
|
||||||
ed->ode.ode_body = (void*)body;
|
ed->rbe.body = (void*)body;
|
||||||
|
|
||||||
//motion threshhold should be speed/physicsframerate.
|
//motion threshhold should be speed/physicsframerate.
|
||||||
//FIXME: recalculate...
|
//FIXME: recalculate...
|
||||||
|
@ -1226,16 +1269,16 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ed->ode.ode_body == NULL)
|
if (ed->rbe.body == NULL)
|
||||||
{
|
{
|
||||||
btRigidBody::btRigidBodyConstructionInfo rbci(ed->ode.ode_mass, new QCMotionState(ed,world), (btCollisionShape*)ed->ode.ode_geom, btVector3(0, 0, 0));
|
btRigidBody::btRigidBodyConstructionInfo rbci(ed->rbe.mass, new QCMotionState(ed,world), (btCollisionShape*)ed->rbe.geom, btVector3(0, 0, 0));
|
||||||
body = new btRigidBody(rbci);
|
body = new btRigidBody(rbci);
|
||||||
body->setUserPointer(ed);
|
body->setUserPointer(ed);
|
||||||
// btTransform trans;
|
// btTransform trans;
|
||||||
// trans.setFromOpenGLMatrix(ed->ode.ode_offsetmatrix);
|
// trans.setFromOpenGLMatrix(ed->rbe.offsetmatrix);
|
||||||
// body->setCenterOfMassTransform(trans);
|
// body->setCenterOfMassTransform(trans);
|
||||||
ed->ode.ode_body = (void*)body;
|
ed->rbe.body = (void*)body;
|
||||||
if (ed->ode.ode_mass)
|
if (ed->rbe.mass)
|
||||||
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||||
else
|
else
|
||||||
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
|
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
|
||||||
|
@ -1245,7 +1288,7 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body = (btRigidBody*)ed->ode.ode_body;
|
body = (btRigidBody*)ed->rbe.body;
|
||||||
|
|
||||||
// get current data from entity
|
// get current data from entity
|
||||||
gravity = qtrue;
|
gravity = qtrue;
|
||||||
|
@ -1325,15 +1368,15 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
|
|
||||||
// check if the qc edited any position data
|
// check if the qc edited any position data
|
||||||
if (
|
if (
|
||||||
0//!VectorCompare(origin, ed->ode.ode_origin)
|
0//!VectorCompare(origin, ed->rbe.origin)
|
||||||
|| !VectorCompare(velocity, ed->ode.ode_velocity)
|
|| !VectorCompare(velocity, ed->rbe.velocity)
|
||||||
//|| !VectorCompare(angles, ed->ode.ode_angles)
|
//|| !VectorCompare(angles, ed->rbe.angles)
|
||||||
|| !VectorCompare(avelocity, ed->ode.ode_avelocity)
|
|| !VectorCompare(avelocity, ed->rbe.avelocity)
|
||||||
|| gravity != ed->ode.ode_gravity)
|
|| gravity != ed->rbe.gravity)
|
||||||
modified = qtrue;
|
modified = qtrue;
|
||||||
|
|
||||||
// store the qc values into the physics engine
|
// store the qc values into the physics engine
|
||||||
body = (btRigidBody*)ed->ode.ode_body;
|
body = (btRigidBody*)ed->rbe.body;
|
||||||
if (modified && body)
|
if (modified && body)
|
||||||
{
|
{
|
||||||
// dVector3 r[3];
|
// dVector3 r[3];
|
||||||
|
@ -1342,27 +1385,27 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
Con_Printf("entity %i got changed by QC\n", (int) (ed - prog->edicts));
|
Con_Printf("entity %i got changed by QC\n", (int) (ed - prog->edicts));
|
||||||
if(!VectorCompare(origin, ed->ode.ode_origin))
|
if(!VectorCompare(origin, ed->rbe.origin))
|
||||||
Con_Printf(" origin: %f %f %f -> %f %f %f\n", ed->ode.ode_origin[0], ed->ode.ode_origin[1], ed->ode.ode_origin[2], origin[0], origin[1], origin[2]);
|
Con_Printf(" origin: %f %f %f -> %f %f %f\n", ed->rbe.origin[0], ed->rbe.origin[1], ed->rbe.origin[2], origin[0], origin[1], origin[2]);
|
||||||
if(!VectorCompare(velocity, ed->ode.ode_velocity))
|
if(!VectorCompare(velocity, ed->rbe.velocity))
|
||||||
Con_Printf(" velocity: %f %f %f -> %f %f %f\n", ed->ode.ode_velocity[0], ed->ode.ode_velocity[1], ed->ode.ode_velocity[2], velocity[0], velocity[1], velocity[2]);
|
Con_Printf(" velocity: %f %f %f -> %f %f %f\n", ed->rbe.velocity[0], ed->rbe.velocity[1], ed->rbe.velocity[2], velocity[0], velocity[1], velocity[2]);
|
||||||
if(!VectorCompare(angles, ed->ode.ode_angles))
|
if(!VectorCompare(angles, ed->rbe.angles))
|
||||||
Con_Printf(" angles: %f %f %f -> %f %f %f\n", ed->ode.ode_angles[0], ed->ode.ode_angles[1], ed->ode.ode_angles[2], angles[0], angles[1], angles[2]);
|
Con_Printf(" angles: %f %f %f -> %f %f %f\n", ed->rbe.angles[0], ed->rbe.angles[1], ed->rbe.angles[2], angles[0], angles[1], angles[2]);
|
||||||
if(!VectorCompare(avelocity, ed->ode.ode_avelocity))
|
if(!VectorCompare(avelocity, ed->rbe.avelocity))
|
||||||
Con_Printf(" avelocity: %f %f %f -> %f %f %f\n", ed->ode.ode_avelocity[0], ed->ode.ode_avelocity[1], ed->ode.ode_avelocity[2], avelocity[0], avelocity[1], avelocity[2]);
|
Con_Printf(" avelocity: %f %f %f -> %f %f %f\n", ed->rbe.avelocity[0], ed->rbe.avelocity[1], ed->rbe.avelocity[2], avelocity[0], avelocity[1], avelocity[2]);
|
||||||
if(gravity != ed->ode.ode_gravity)
|
if(gravity != ed->rbe.gravity)
|
||||||
Con_Printf(" gravity: %i -> %i\n", ed->ide.ode_gravity, gravity);
|
Con_Printf(" gravity: %i -> %i\n", ed->ide.ode_gravity, gravity);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// values for BodyFromEntity to check if the qc modified anything later
|
// values for BodyFromEntity to check if the qc modified anything later
|
||||||
VectorCopy(origin, ed->ode.ode_origin);
|
VectorCopy(origin, ed->rbe.origin);
|
||||||
VectorCopy(velocity, ed->ode.ode_velocity);
|
VectorCopy(velocity, ed->rbe.velocity);
|
||||||
VectorCopy(angles, ed->ode.ode_angles);
|
VectorCopy(angles, ed->rbe.angles);
|
||||||
VectorCopy(avelocity, ed->ode.ode_avelocity);
|
VectorCopy(avelocity, ed->rbe.avelocity);
|
||||||
ed->ode.ode_gravity = gravity;
|
ed->rbe.gravity = gravity;
|
||||||
|
|
||||||
// foo Matrix4x4_RM_FromVectors(entitymatrix, forward, left, up, origin);
|
// foo Matrix4x4_RM_FromVectors(entitymatrix, forward, left, up, origin);
|
||||||
// foo Matrix4_Multiply(ed->ode.ode_offsetmatrix, entitymatrix, bodymatrix);
|
// foo Matrix4_Multiply(ed->rbe.offsetmatrix, entitymatrix, bodymatrix);
|
||||||
// foo Matrix3x4_RM_ToVectors(bodymatrix, forward, left, up, origin);
|
// foo Matrix3x4_RM_ToVectors(bodymatrix, forward, left, up, origin);
|
||||||
|
|
||||||
// r[0][0] = forward[0];
|
// r[0][0] = forward[0];
|
||||||
|
@ -1392,7 +1435,7 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||||
// limit movement speed to prevent missed collisions at high speed
|
// limit movement speed to prevent missed collisions at high speed
|
||||||
btVector3 ovelocity = body->getLinearVelocity();
|
btVector3 ovelocity = body->getLinearVelocity();
|
||||||
btVector3 ospinvelocity = body->getAngularVelocity();
|
btVector3 ospinvelocity = body->getAngularVelocity();
|
||||||
movelimit = ed->ode.ode_movelimit * world->ode.ode_movelimit;
|
movelimit = ed->rbe.movelimit * world->rbe.movelimit;
|
||||||
test = DotProduct(ovelocity,ovelocity);
|
test = DotProduct(ovelocity,ovelocity);
|
||||||
if (test > movelimit*movelimit)
|
if (test > movelimit*movelimit)
|
||||||
{
|
{
|
||||||
|
@ -1465,7 +1508,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
|
||||||
//ragdolls don't make contact with the bbox of the doll entity
|
//ragdolls don't make contact with the bbox of the doll entity
|
||||||
//the origional entity should probably not be solid anyway.
|
//the origional entity should probably not be solid anyway.
|
||||||
//these bodies should probably not collide against bboxes of other entities with ragdolls either, but meh.
|
//these bodies should probably not collide against bboxes of other entities with ragdolls either, but meh.
|
||||||
if (ed1->ode.ode_body == b1 || ed2->ode.ode_body == b2)
|
if (ed1->rbe.body == b1 || ed2->rbe.body == b2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!ed1 || ed1->isfree)
|
if(!ed1 || ed1->isfree)
|
||||||
|
@ -1529,7 +1572,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
|
||||||
bouncefactor1 = bouncefactor2;
|
bouncefactor1 = bouncefactor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dWorldGetGravity(world->ode.ode_world, grav);
|
dWorldGetGravity(world->rbe.world, grav);
|
||||||
bouncestop1 *= fabs(grav[2]);
|
bouncestop1 *= fabs(grav[2]);
|
||||||
|
|
||||||
erp = (DotProduct(ed1->v->velocity, ed1->v->velocity) > DotProduct(ed2->v->velocity, ed2->v->velocity)) ? ed1->xv->erp : ed2->xv->erp;
|
erp = (DotProduct(ed1->v->velocity, ed1->v->velocity) > DotProduct(ed2->v->velocity, ed2->v->velocity)) ? ed1->xv->erp : ed2->xv->erp;
|
||||||
|
@ -1551,7 +1594,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
|
||||||
contact[i].surface.soft_cfm = physics_bullet_contact_cfm.value;
|
contact[i].surface.soft_cfm = physics_bullet_contact_cfm.value;
|
||||||
contact[i].surface.bounce = bouncefactor1;
|
contact[i].surface.bounce = bouncefactor1;
|
||||||
contact[i].surface.bounce_vel = bouncestop1;
|
contact[i].surface.bounce_vel = bouncestop1;
|
||||||
c = dJointCreateContact(world->ode.ode_world, world->ode.ode_contactgroup, contact + i);
|
c = dJointCreateContact(world->rbe.world, world->rbe.contactgroup, contact + i);
|
||||||
dJointAttach(c, b1, b2);
|
dJointAttach(c, b1, b2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1565,9 +1608,9 @@ static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gr
|
||||||
int i;
|
int i;
|
||||||
wedict_t *ed;
|
wedict_t *ed;
|
||||||
|
|
||||||
// world->ode.ode_iterations = bound(1, physics_bullet_iterationsperframe.ival, 1000);
|
// world->rbe.iterations = bound(1, physics_bullet_iterationsperframe.ival, 1000);
|
||||||
// world->ode.ode_step = frametime / world->ode.ode_iterations;
|
// world->rbe.step = frametime / world->rbe.iterations;
|
||||||
// world->ode.ode_movelimit = physics_bullet_movelimit.value / world->ode.ode_step;
|
// world->rbe.movelimit = physics_bullet_movelimit.value / world->rbe.step;
|
||||||
|
|
||||||
|
|
||||||
// copy physics properties from entities to physics engine
|
// copy physics properties from entities to physics engine
|
||||||
|
@ -1599,22 +1642,22 @@ static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gr
|
||||||
ctx->dworld->stepSimulation(frametime, max(0, physics_bullet_maxiterationsperframe->value), 1/bound(1, physics_bullet_framerate->value, 500));
|
ctx->dworld->stepSimulation(frametime, max(0, physics_bullet_maxiterationsperframe->value), 1/bound(1, physics_bullet_framerate->value, 500));
|
||||||
|
|
||||||
// set the tolerance for closeness of objects
|
// set the tolerance for closeness of objects
|
||||||
// dWorldSetContactSurfaceLayer(world->ode.ode_world, max(0, physics_bullet_contactsurfacelayer.value));
|
// dWorldSetContactSurfaceLayer(world->rbe.world, max(0, physics_bullet_contactsurfacelayer.value));
|
||||||
|
|
||||||
// run collisions for the current world state, creating JointGroup
|
// run collisions for the current world state, creating JointGroup
|
||||||
// dSpaceCollide(world->ode.ode_space, (void *)world, nearCallback);
|
// dSpaceCollide(world->rbe.space, (void *)world, nearCallback);
|
||||||
|
|
||||||
// run physics (move objects, calculate new velocities)
|
// run physics (move objects, calculate new velocities)
|
||||||
// if (physics_bullet_worldquickstep.ival)
|
// if (physics_bullet_worldquickstep.ival)
|
||||||
// {
|
// {
|
||||||
// dWorldSetQuickStepNumIterations(world->ode.ode_world, bound(1, physics_bullet_worldquickstep_iterations.ival, 200));
|
// dWorldSetQuickStepNumIterations(world->rbe.world, bound(1, physics_bullet_worldquickstep_iterations.ival, 200));
|
||||||
// dWorldQuickStep(world->ode.ode_world, world->ode.ode_step);
|
// dWorldQuickStep(world->rbe.world, world->rbe.step);
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
// dWorldStep(world->ode.ode_world, world->ode.ode_step);
|
// dWorldStep(world->rbe.world, world->rbe.step);
|
||||||
|
|
||||||
// clear the JointGroup now that we're done with it
|
// clear the JointGroup now that we're done with it
|
||||||
// dJointGroupEmpty(world->ode.ode_contactgroup);
|
// dJointGroupEmpty(world->rbe.contactgroup);
|
||||||
|
|
||||||
if (world->rbe_hasphysicsents)
|
if (world->rbe_hasphysicsents)
|
||||||
{
|
{
|
||||||
|
@ -1631,7 +1674,7 @@ static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gr
|
||||||
|
|
||||||
static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd)
|
static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd)
|
||||||
{
|
{
|
||||||
btRigidBody *body = (btRigidBody*)(cmd->edict->ode.ode_body);
|
btRigidBody *body = (btRigidBody*)(cmd->edict->rbe.body);
|
||||||
switch(cmd->command)
|
switch(cmd->command)
|
||||||
{
|
{
|
||||||
case RBECMD_ENABLE:
|
case RBECMD_ENABLE:
|
||||||
|
@ -1650,7 +1693,7 @@ static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RBECMD_TORQUE:
|
case RBECMD_TORQUE:
|
||||||
if (cmd->edict->ode.ode_body)
|
if (cmd->edict->rbe.body)
|
||||||
{
|
{
|
||||||
body->setActivationState(1);
|
body->setActivationState(1);
|
||||||
body->applyTorque(btVector3(cmd->v1[0], cmd->v1[1], cmd->v1[2]));
|
body->applyTorque(btVector3(cmd->v1[0], cmd->v1[1], cmd->v1[2]));
|
||||||
|
@ -1679,7 +1722,7 @@ static void QDECL World_Bullet_PushCommand(world_t *world, rbecommandqueue_t *va
|
||||||
static void QDECL World_Bullet_TraceEntity(world_t *world, vec3_t start, vec3_t end, wedict_t *ed)
|
static void QDECL World_Bullet_TraceEntity(world_t *world, vec3_t start, vec3_t end, wedict_t *ed)
|
||||||
{
|
{
|
||||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||||
btCollisionShape *shape = (btCollisionShape*)ed->ode.ode_geom;
|
btCollisionShape *shape = (btCollisionShape*)ed->rbe.geom;
|
||||||
|
|
||||||
class myConvexResultCallback : public btCollisionWorld::ConvexResultCallback
|
class myConvexResultCallback : public btCollisionWorld::ConvexResultCallback
|
||||||
{
|
{
|
||||||
|
@ -1738,34 +1781,34 @@ static void QDECL World_Bullet_Start(world_t *world)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(physics_bullet_world_erp.value >= 0)
|
if(physics_bullet_world_erp.value >= 0)
|
||||||
dWorldSetERP(world->ode.ode_world, physics_bullet_world_erp.value);
|
dWorldSetERP(world->rbe.world, physics_bullet_world_erp.value);
|
||||||
if(physics_bullet_world_cfm.value >= 0)
|
if(physics_bullet_world_cfm.value >= 0)
|
||||||
dWorldSetCFM(world->ode.ode_world, physics_bullet_world_cfm.value);
|
dWorldSetCFM(world->rbe.world, physics_bullet_world_cfm.value);
|
||||||
if (physics_bullet_world_damping.ival)
|
if (physics_bullet_world_damping.ival)
|
||||||
{
|
{
|
||||||
dWorldSetLinearDamping(world->ode.ode_world, (physics_bullet_world_damping_linear.value >= 0) ? (physics_bullet_world_damping_linear.value * physics_bullet_world_damping.value) : 0);
|
dWorldSetLinearDamping(world->rbe.world, (physics_bullet_world_damping_linear.value >= 0) ? (physics_bullet_world_damping_linear.value * physics_bullet_world_damping.value) : 0);
|
||||||
dWorldSetLinearDampingThreshold(world->ode.ode_world, (physics_bullet_world_damping_linear_threshold.value >= 0) ? (physics_bullet_world_damping_linear_threshold.value * physics_bullet_world_damping.value) : 0);
|
dWorldSetLinearDampingThreshold(world->rbe.world, (physics_bullet_world_damping_linear_threshold.value >= 0) ? (physics_bullet_world_damping_linear_threshold.value * physics_bullet_world_damping.value) : 0);
|
||||||
dWorldSetAngularDamping(world->ode.ode_world, (physics_bullet_world_damping_angular.value >= 0) ? (physics_bullet_world_damping_angular.value * physics_bullet_world_damping.value) : 0);
|
dWorldSetAngularDamping(world->rbe.world, (physics_bullet_world_damping_angular.value >= 0) ? (physics_bullet_world_damping_angular.value * physics_bullet_world_damping.value) : 0);
|
||||||
dWorldSetAngularDampingThreshold(world->ode.ode_world, (physics_bullet_world_damping_angular_threshold.value >= 0) ? (physics_bullet_world_damping_angular_threshold.value * physics_bullet_world_damping.value) : 0);
|
dWorldSetAngularDampingThreshold(world->rbe.world, (physics_bullet_world_damping_angular_threshold.value >= 0) ? (physics_bullet_world_damping_angular_threshold.value * physics_bullet_world_damping.value) : 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dWorldSetLinearDamping(world->ode.ode_world, 0);
|
dWorldSetLinearDamping(world->rbe.world, 0);
|
||||||
dWorldSetLinearDampingThreshold(world->ode.ode_world, 0);
|
dWorldSetLinearDampingThreshold(world->rbe.world, 0);
|
||||||
dWorldSetAngularDamping(world->ode.ode_world, 0);
|
dWorldSetAngularDamping(world->rbe.world, 0);
|
||||||
dWorldSetAngularDampingThreshold(world->ode.ode_world, 0);
|
dWorldSetAngularDampingThreshold(world->rbe.world, 0);
|
||||||
}
|
}
|
||||||
if (physics_bullet_autodisable.ival)
|
if (physics_bullet_autodisable.ival)
|
||||||
{
|
{
|
||||||
dWorldSetAutoDisableSteps(world->ode.ode_world, bound(1, physics_bullet_autodisable_steps.ival, 100));
|
dWorldSetAutoDisableSteps(world->rbe.world, bound(1, physics_bullet_autodisable_steps.ival, 100));
|
||||||
dWorldSetAutoDisableTime(world->ode.ode_world, physics_bullet_autodisable_time.value);
|
dWorldSetAutoDisableTime(world->rbe.world, physics_bullet_autodisable_time.value);
|
||||||
dWorldSetAutoDisableAverageSamplesCount(world->ode.ode_world, bound(1, physics_bullet_autodisable_threshold_samples.ival, 100));
|
dWorldSetAutoDisableAverageSamplesCount(world->rbe.world, bound(1, physics_bullet_autodisable_threshold_samples.ival, 100));
|
||||||
dWorldSetAutoDisableLinearThreshold(world->ode.ode_world, physics_bullet_autodisable_threshold_linear.value);
|
dWorldSetAutoDisableLinearThreshold(world->rbe.world, physics_bullet_autodisable_threshold_linear.value);
|
||||||
dWorldSetAutoDisableAngularThreshold(world->ode.ode_world, physics_bullet_autodisable_threshold_angular.value);
|
dWorldSetAutoDisableAngularThreshold(world->rbe.world, physics_bullet_autodisable_threshold_angular.value);
|
||||||
dWorldSetAutoDisableFlag (world->ode.ode_world, true);
|
dWorldSetAutoDisableFlag (world->rbe.world, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dWorldSetAutoDisableFlag (world->ode.ode_world, false);
|
dWorldSetAutoDisableFlag (world->rbe.world, false);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -534,7 +534,7 @@ void Plug_InitStandardBuiltins(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef Q3_VM
|
#ifndef Q3_VM
|
||||||
void NATIVEEXPORT dllEntry(qintptr_t (QDECL *funcptr)(qintptr_t,...))
|
NATIVEEXPORT void QDECL dllEntry(qintptr_t (QDECL *funcptr)(qintptr_t,...))
|
||||||
{
|
{
|
||||||
plugin_syscall = funcptr;
|
plugin_syscall = funcptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,10 +94,14 @@ void BadBuiltin(void);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifndef NATIVEEXPORT
|
||||||
#define NATIVEEXPORT __declspec(dllexport) QDECL
|
#ifdef _WIN32
|
||||||
#else
|
#define NATIVEEXPORTPROTO __declspec(dllexport)
|
||||||
#define NATIVEEXPORT __attribute__((visibility("default")))
|
#define NATIVEEXPORT NATIVEEXPORTPROTO
|
||||||
|
#else
|
||||||
|
#define NATIVEEXPORTPROTO
|
||||||
|
#define NATIVEEXPORT __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,3 +20,13 @@ at the time of writing, r_polygonoffset_* need to be set to 0, or you'll get pur
|
||||||
|
|
||||||
Cheats: static realtime lighting _used_ to be cheat protected. Which made it useless and unusable. Darkplaces has permitted realtime lights for a while on quakeworld servers without complaint. Thus FTE no longer mandates that the server explicitly allows it.
|
Cheats: static realtime lighting _used_ to be cheat protected. Which made it useless and unusable. Darkplaces has permitted realtime lights for a while on quakeworld servers without complaint. Thus FTE no longer mandates that the server explicitly allows it.
|
||||||
Having said that, you can tell if static or dynamic lights are enabled in someone else's client via the f_version say request.
|
Having said that, you can tell if static or dynamic lights are enabled in someone else's client via the f_version say request.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
todo:
|
||||||
|
light util that omits direct lighting + engine that forces r_shadow_realtime_world_lightmaps 1
|
||||||
|
light util that emits e5bgr9 lighting + worldspawn key that forces srgb.
|
||||||
|
light util that generates complete .rtlights files, with radiuses and colours and falloffs and spotlights etc.
|
||||||
|
ggx.
|
||||||
|
screenspace refections.
|
Loading…
Reference in a new issue