Retrive dynamic lights placed in WED

Posted By: BoH_Havoc

Retrive dynamic lights placed in WED - 12/24/09 02:18

Is there any way to retrive ALL dynamic lights which were placed in WED? I can't find anything in the manual about this.
I need to create an array of all dynamic lights in the level for my deferred shader. Retriving lights which were created by script is no problem, but the WED ones are giving me headaches.


Any ideas? laugh

Posted By: rojart

Re: Retrive dynamic lights placed in WED - 12/24/09 15:55

Hi, the new feature ent_nextlight should to work, but have not tested yet.

Note:
"The ent_nextlight function now stores light info in the hit struct, and can also detect WED-placed lights."

"Returns
ENTITY* - Pointer to the light emitting entity, or A7.82 level_ent for a level-placed dynamic light or the sun, or NULL when no more light was in range."
Posted By: BoH_Havoc

Re: Retrive dynamic lights placed in WED - 12/24/09 20:05

Yes i also thought about using ent_nextlight, but

Quote:
num - Number of the light (1..7), with 1 the closest and 7 the furthest light in range.


the function only returns the 7 nearest lights. If this wouldn't be fixed to 1->7 but 1->unlimited then this would be great fantastic and EXACTLY what i need.

Posted By: Enduriel

Re: Retrive dynamic lights placed in WED - 12/24/09 21:56

hmm, I think I got a solution. Not sure yet.

What if you used ent_next and kept looping through every single entity in the level, and then calling that ent_nextlight with the entity retrieved from the previous funciton. You could also then maybe somehow do a check if the retrieved light is already on the list, if yes; skip it, else, add it.

Not sure though, just something that came to my mind.
Posted By: BoH_Havoc

Re: Retrive dynamic lights placed in WED - 12/25/09 00:04

Nice idea laugh

But if there is only one model in the level and more than 7 lights, this won't work, as you can only get the 7 nearest lights of a model. So if there are 26 lights, i would only get 7 out of these 26 frown
Posted By: Enduriel

Re: Retrive dynamic lights placed in WED - 12/25/09 00:05

ow yeah right =/ damn, I guess JCL needs to add a function to retrieve all the lights then to support deferred rendering tongue

EDIT: but hmm, I wonder if ent_next returns lights placed by WED. Cause afaik only ENTITY* can cast lights through the LIGHT flag if it's set, and I guess that the lights that are placed by WED are entities created by the engine when it's initialized. So maybe you should try ent_next and see if it returns an ENTITY* on an empty level with only WED placed lights, if it does, I bet it has the LIGHT flag set which let's you know it's a light
Posted By: BoH_Havoc

Re: Retrive dynamic lights placed in WED - 12/25/09 00:43

Just tried it.

ent_next seems to only return entities/models. Level Geometry (i.e. level_ent) and WED lights are not returned. >.<

oh well, guess that would have been to easy wink
Posted By: Enduriel

Re: Retrive dynamic lights placed in WED - 12/25/09 01:02

Haha, well up to JCL from now on =}
Posted By: DJBMASTER

Re: Retrive dynamic lights placed in WED - 12/25/09 01:39

hmm well I might be off here but I know a mechanism to read the .wmb file, and search through the data lists, and extract info about dynamic lights like position, colour, range.

Posted By: DJBMASTER

Re: Retrive dynamic lights placed in WED - 12/25/09 08:50

Ok, here's a way to get all the dynamic lights in a level. It might be a little messy, as this is my first time using dynamic memory allocation functions (I'm a C# guy), haha...
Code:
/////////////////////////
// Includes /////////////
/////////////////////////

#include <acknex.h>
#include <default.c>
#include <stdio.h>

/////////////////////////
// Variables ////////////
/////////////////////////

DynamicLight* lights; // Array of dynamic lights.
int dynamic_light_counter = 0; // Amount of dynamic lights in our array.

/////////////////////////
// Structs //////////////
/////////////////////////

typedef struct
{
float x,y,z; 	
float red,green,blue;	
float range;	
} 
DynamicLight; // A simple struct to hold the properties of a dynamic light.

/////////////////////////
// Functions ////////////
/////////////////////////

// This function reads the internal structure of a .WMB file, and searches only for dynamic lights. It then creates a new DynamicLight struct
// with the light's properties and adds it to the global array (lights).

void GetDynamicLights(char* filename)
{
  FILE* file = fopen(level,"rb");
  fseek(file,124,SEEK_SET);

  var i = 0; int offset = 0, length = 0, num_of_objects = 0, object_type = 0;

  fread(&offset, sizeof(int), 1, file);
  fread(&length, sizeof(int), 1, file);
  fseek(file,offset,SEEK_SET);

  fread(&num_of_objects, sizeof(int), 1, file);
  
  int* offset_list = (int*)malloc (num_of_objects*sizeof(int));
  for(i = 0; i < num_of_objects; i++)
  {
		fread(&(offset_list[i]), sizeof(int), 1, file);
  }

  for(i=0; i < num_of_objects; i++)
  {
	  fseek(file,offset+offset_list[i],SEEK_SET);
	  fread(&object_type, sizeof(int), 1, file);

	  if(object_type == 2) // light
	  {
      fseek(file,offset+offset_list[i]+32,SEEK_SET);
		int flags = 0;
	
		fread(&flags, sizeof(long), 1, file);

		if(flags == 2)
		{
		fseek(file,offset+offset_list[i]+4,SEEK_SET);

		float x = 0.0, y = 0.0, z = 0.0;
		float red =0.0, blue =0.0, green = 0.0;
		float range = 0.0;
		
		fread(&x, sizeof(float), 1, file);
		fread(&y, sizeof(float), 1, file);
		fread(&z, sizeof(float), 1, file);
		fread(&red, sizeof(float), 1, file);
		fread(&green, sizeof(float), 1, file);
		fread(&blue, sizeof(float), 1, file);
		fread(&range, sizeof(float), 1, file);
		
		DynamicLight* new_light = (DynamicLight*)malloc(sizeof(DynamicLight));
		memset(new_light,0,sizeof(DynamicLight));
		new_light->x = x;
		new_light->y = y;
		new_light->z = z;
		new_light->red = (red*255)/100;
		new_light->green = (green*255)/100;
		new_light->blue = (blue*255)/100;
		new_light->range = range;
		
		lights = (DynamicLight*) realloc (lights, (dynamic_light_counter+1) * sizeof(DynamicLight));
		memcpy(&lights[dynamic_light_counter],new_light,sizeof(DynamicLight));
		dynamic_light_counter++;
		}
	  }
  }

  free (offset_list);
  fclose(file);
     
}

void main()
{
	GetDynamicLights("mylevel.wmb"); // Populate array of dynamic lights.
}



I've tested it and it works pretty well. Hope it helps.

DJB.
Posted By: BoH_Havoc

Re: Retrive dynamic lights placed in WED - 12/26/09 02:58

Awesome! That's exactly what i needed laugh

THANKS! laugh

[edit] one little thing: what do i have to change so it retrives all lights that have the dynamic flag set? if i set [dynamic] together with [highres] and/or [static] in WED, they aren't retrived anymore. Not that much of a big deal, but it would be nice to have that feature laugh
Posted By: DJBMASTER

Re: Retrive dynamic lights placed in WED - 12/26/09 09:12

ermm, you can just add some more clauses identical to the 'if(flags == 2)' bit, using the following values...

flags = 0 >>> (static light)
flags = 1 >>> (hi-res static light)
flags = 2 >>> (dynamic light)
flags = 3 >>> (hi-res dynamic light)

So all dynamic lights (hi-res or not), just change the if statement to 'if(flags == 2 || flags == 3)'.

Any more problems, don't hesitate to ask.

DJB.
© 2024 lite-C Forums