From 0e82b370010bf0081a6fa153fd9004a733ab2062 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 2 Jan 2013 18:31:36 +0900 Subject: [PATCH] Parse the sun information from the worldspawn entity. --- tools/qflight/include/entities.h | 9 +++++ tools/qflight/include/light.h | 5 +++ tools/qflight/include/properties.h | 35 ++++++++++++++++ tools/qflight/source/entities.c | 29 +++++++++++-- tools/qflight/source/properties.c | 65 ++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 3 deletions(-) diff --git a/tools/qflight/include/entities.h b/tools/qflight/include/entities.h index c7a1eb1c2..82bf378cc 100644 --- a/tools/qflight/include/entities.h +++ b/tools/qflight/include/entities.h @@ -29,6 +29,8 @@ #ifndef __entities_h #define __entities_h +#include "light.h" + /** \defgroup qflight_entities Light entity data. \ingroup qflight */ @@ -55,6 +57,13 @@ typedef struct entity_s { vec3_t origin; vec_t angle; int light; + + int sun_light[2]; + vec3_t sun_color[2]; + int num_suns; + vec3_t sun_dir[NUMSUNS]; + float shadow_sense; + // LordHavoc: added falloff (smaller fractions = bigger light area), // color, and lightradius (also subbrightness to implement lightradius) vec_t falloff; diff --git a/tools/qflight/include/light.h b/tools/qflight/include/light.h index 184883746..013ee0922 100644 --- a/tools/qflight/include/light.h +++ b/tools/qflight/include/light.h @@ -44,6 +44,11 @@ #define LIGHTDISTBIAS 65536.0 #define BOGUS_RANGE 1000000000 +#define NUMHSUNS 32 +#define NUMVSUNS 4 +#define NUMSUNS (1 + NUMHSUNS * NUMVSUNS) +#define SHADOWSENSE 0.4 + #define SINGLEMAP (256*256) typedef struct { diff --git a/tools/qflight/include/properties.h b/tools/qflight/include/properties.h index 1cf6e8edf..a6b724d19 100644 --- a/tools/qflight/include/properties.h +++ b/tools/qflight/include/properties.h @@ -46,6 +46,16 @@ struct plitem_s; */ float parse_float (const char *str); +/** Parse a vector from a string. + + \param str The string holding the float. + \param vec The destination vector into which the vector values will + be written. + + \bug No error checking is performed. +*/ +void parse_vector (const char *str, vec3_t vec); + /** Parse an RGB color vector from a string. The RGB values are normalized such that the magnitude of the largest @@ -109,6 +119,31 @@ int parse_attenuation (const char *arg); */ int parse_noise (const char *arg); +/** Set the world entity's sun values based on its fields and the loaded + lighting properties database. + + The database is loaded via LoadProperties(). + + If a set of properties named "worldspawn" is in the database, the it + will be used for default values, otherwise the database will be + ignored. + + Supported properties: + \arg \c sunlight see \ref parse_light + \arg \c sunlight2 see \ref parse_light + \arg \c sunlight3 see \ref parse_light + \arg \c sunlight_color see \ref parse_color + \arg \c sunlight_color2 see \ref parse_color + \arg \c sunlight_color3 see \ref parse_color + \arg \c sun_mangle see \ref parse_vector + + \param ent The entity for which to set the lighting values. + \param dict A dictionary property list item representing the fields + of the entity. Values specified in \a dict will override + those specified in the database. +*/ +void set_sun_properties (entity_t *ent, struct plitem_s *dict); + /** Set the light entity's lighting values based on its fields and the loaded lighting properties database. diff --git a/tools/qflight/source/entities.c b/tools/qflight/source/entities.c index 990ab5cf1..01c36077c 100644 --- a/tools/qflight/source/entities.c +++ b/tools/qflight/source/entities.c @@ -174,7 +174,7 @@ LoadEntities (void) script_t *script; const char *field_name; const char *value; - int i; + int i, j; script = Script_New (); Script_Start (script, "ent data", bsp->entdata); @@ -189,12 +189,22 @@ LoadEntities (void) for (i = 0; i < num_entities; i++) { entity = &entities[i]; memset (entity, 0, sizeof (*entity)); - entity->color[0] = entity->color[1] = entity->color[2] = 1.0f; + + VectorSet (1, 1, 1, entity->color); VectorCopy (entity->color, entity->color2); entity->falloff = DEFAULTFALLOFF * DEFAULTFALLOFF; entity->lightradius = 0; entity->lightoffset = LIGHTDISTBIAS; entity->attenuation = options.attenuation; + entity->sun_light[0] = -1; + entity->sun_light[1] = -1; + VectorSet (1, 1, 1, entity->sun_color[0]); + VectorSet (1, 1, 1, entity->sun_color[1]); + entity->num_suns = 1 + NUMHSUNS * NUMVSUNS; + for (j = 0; j < entity->num_suns; j++) { + // default to straight down + VectorSet (0, 0, 1, entity->sun_dir[j]); + } entity->dict = PL_ObjectAtIndex (entity_list, i); dict = PL_NewDictionary (); @@ -235,10 +245,23 @@ LoadEntities (void) // all fields have been parsed if (entity->classname) { - if (strcmp (entity->classname, "worldspawn")) { + if (!strcmp (entity->classname, "worldspawn")) { + int hsuns = NUMHSUNS; if (world_entity) Sys_Error ("More than one worldspawn entity"); + set_sun_properties (entity, dict); + if (options.extrabit == 1) + hsuns = 6; + else if (options.extrabit == 2) + hsuns = 16; + entity->num_suns = 1 + hsuns * NUMVSUNS; + if (entity->sun_light[1] <= 0) + entity->num_suns = 1; + if (entity->sun_light[0] <= 0) + entity->num_suns = 0; world_entity = entity; + } else { + entity->num_suns = 0; } if (!strncmp (entity->classname, "light", 5)) { set_properties (entity, dict); diff --git a/tools/qflight/source/properties.c b/tools/qflight/source/properties.c index fb9f1b529..d9286e268 100644 --- a/tools/qflight/source/properties.c +++ b/tools/qflight/source/properties.c @@ -47,6 +47,7 @@ #include "compat.h" #include "entities.h" +#include "light.h" #include "options.h" #include "properties.h" @@ -60,6 +61,22 @@ parse_float (const char *str) return val; } +void +parse_vector (const char *str, vec3_t vec) +{ + double tvec[3]; + int count; + + tvec[2] = 0; // assume 2 components is yaw and pitch + count = sscanf (str, "%lf %lf %lf", &tvec[0], &tvec[1], &tvec[2]); + + if (count < 2 || count > 3) { + fprintf (stderr, "invalid vector"); + VectorZero (tvec); + } + VectorCopy (tvec, vec); +} + void parse_color (const char *str, vec3_t color) { @@ -164,6 +181,54 @@ get_item (const char *key, plitem_t *d1, plitem_t *d2) return 0; } +void +set_sun_properties (entity_t *ent, plitem_t *dict) +{ + plitem_t *prop = 0; + plitem_t *p; + const char *str; + + if (properties) { + prop = PL_ObjectForKey (properties, "worldspawn"); + } + if ((p = get_item ("sunlight", dict, prop))) { + if ((str = PL_String (p))) { + ent->sun_light[0] = parse_light (str, ent->sun_color[0]); + } + } + if ((p = get_item ("sunlight2", dict, prop))) { + if ((str = PL_String (p))) { + ent->sun_light[1] = parse_light (str, ent->sun_color[1]); + } + } + if ((p = get_item ("sunlight3", dict, prop))) { + if ((str = PL_String (p))) { + ent->sun_light[1] = parse_light (str, ent->sun_color[1]); + ent->shadow_sense = SHADOWSENSE; + } + } + if ((p = get_item ("sunlight_color", dict, prop))) { + if ((str = PL_String (p))) { + parse_color (str, ent->sun_color[0]); + } + } + if ((p = get_item ("sunlight_color2", dict, prop))) { + if ((str = PL_String (p))) { + parse_color (str, ent->sun_color[1]); + } + } + if ((p = get_item ("sunlight_color3", dict, prop))) { + if ((str = PL_String (p))) { + parse_color (str, ent->sun_color[1]); + } + } + if ((p = get_item ("sun_mangle", dict, prop))) { + if ((str = PL_String (p))) { + parse_vector (str, ent->sun_dir[0]); + } + } +} + void set_properties (entity_t *ent, plitem_t *dict) {