Parse the sun information from the worldspawn entity.

This commit is contained in:
Bill Currie 2013-01-02 18:31:36 +09:00
parent f1a18742f1
commit 0e82b37001
5 changed files with 140 additions and 3 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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.

View file

@ -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);

View file

@ -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)
{