From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Tue, 26 Jan 2010 01:07:13 +0000 (+0000)
Subject: some bugfixes to mod_generatelightmaps that make it run on q1bsp
X-Git-Tag: xonotic-v0.1.0preview~230^2~610
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=67a973fc0fbf946d2cd4e4735be901897880a365;p=xonotic%2Fdarkplaces.git

some bugfixes to mod_generatelightmaps that make it run on q1bsp
(doesn't look right though)


git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9859 d7cf8633-e32d-0410-b094-e92efae38249
---

diff --git a/model_brush.c b/model_brush.c
index 052d3650..7b965f45 100644
--- a/model_brush.c
+++ b/model_brush.c
@@ -1209,7 +1209,7 @@ loc0:
 			surface = model->data_surfaces + node->firstsurface;
 			for (i = 0;i < node->numsurfaces;i++, surface++)
 			{
-				if (!(surface->texture->basematerialflags & MATERIALFLAG_WALL) || !surface->lightmapinfo->samples)
+				if (!(surface->texture->basematerialflags & MATERIALFLAG_WALL) || !surface->lightmapinfo || !surface->lightmapinfo->samples)
 					continue;	// no lightmaps
 
 				// location we want to sample in the lightmap
diff --git a/model_shared.c b/model_shared.c
index c5437504..11291646 100644
--- a/model_shared.c
+++ b/model_shared.c
@@ -3052,6 +3052,79 @@ static float mod_generatelightmaps_offsets[3][MAX_LIGHTMAPSAMPLES][3];
 static int mod_generatelightmaps_numlights;
 static lightmaplight_t *mod_generatelightmaps_lightinfo;
 
+extern int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
+extern cvar_t r_shadow_lightattenuationdividebias;
+extern cvar_t r_shadow_lightattenuationlinearscale;
+
+static void Mod_GenerateLightmaps_LightPoint(dp_model_t *model, const vec3_t pos, vec3_t ambient, vec3_t diffuse, vec3_t lightdir)
+{
+	int i;
+	int index;
+	int result;
+	float relativepoint[3];
+	float color[3];
+	float dir[3];
+	float dist;
+	float dist2;
+	float intensity;
+	float sample[5*3];
+	float lightorigin[3];
+	float lightradius;
+	float lightradius2;
+	float lightiradius;
+	float lightcolor[3];
+	trace_t trace;
+	for (i = 0;i < 5*3;i++)
+		sample[i] = 0.0f;
+	for (index = 0;;index++)
+	{
+		result = R_Shadow_GetRTLightInfo(index, lightorigin, &lightradius, lightcolor);
+		if (result < 0)
+			break;
+		if (result == 0)
+			continue;
+		lightradius2 = lightradius * lightradius;
+		VectorSubtract(lightorigin, pos, relativepoint);
+		dist2 = VectorLength2(relativepoint);
+		if (dist2 >= lightradius2)
+			continue;
+		lightiradius = 1.0f / lightradius;
+		dist = sqrt(dist2) * lightiradius;
+		intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
+		if (intensity <= 0)
+			continue;
+		if (model && model->TraceLine)
+		{
+			model->TraceLine(model, NULL, NULL, &trace, pos, lightorigin, SUPERCONTENTS_VISBLOCKERMASK);
+			if (trace.fraction < 1)
+				continue;
+		}
+		// scale down intensity to add to both ambient and diffuse
+		//intensity *= 0.5f;
+		VectorNormalize(relativepoint);
+		VectorScale(lightcolor, intensity, color);
+		VectorMA(sample    , 0.5f            , color, sample    );
+		VectorMA(sample + 3, relativepoint[0], color, sample + 3);
+		VectorMA(sample + 6, relativepoint[1], color, sample + 6);
+		VectorMA(sample + 9, relativepoint[2], color, sample + 9);
+		// calculate a weighted average light direction as well
+		intensity *= VectorLength(color);
+		VectorMA(sample + 12, intensity, relativepoint, sample + 12);
+	}
+	// calculate the direction we'll use to reduce the sample to a directional light source
+	VectorCopy(sample + 12, dir);
+	//VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]);
+	VectorNormalize(dir);
+	// extract the diffuse color along the chosen direction and scale it
+	diffuse[0] = (dir[0]*sample[3] + dir[1]*sample[6] + dir[2]*sample[ 9] + sample[ 0]);
+	diffuse[1] = (dir[0]*sample[4] + dir[1]*sample[7] + dir[2]*sample[10] + sample[ 1]);
+	diffuse[2] = (dir[0]*sample[5] + dir[1]*sample[8] + dir[2]*sample[11] + sample[ 2]);
+	// subtract some of diffuse from ambient
+	VectorMA(sample, -0.333f, diffuse, ambient);
+	// store the normalized lightdir
+	VectorCopy(dir, lightdir);
+}
+
 static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const dp_model_t *model, svbsp_t *svbsp, const float *mins, const float *maxs)
 {
 	int surfaceindex;
@@ -3065,7 +3138,7 @@ static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP_InsertSurfaces(const
 	{
 		if (!BoxesOverlap(surface->mins, surface->maxs, mins, maxs))
 			continue;
-		if (R_GetCurrentTexture(surface->texture)->currentmaterialflags & MATERIALFLAG_NOSHADOW)
+		if (surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW)
 			continue;
 		for (triangleindex = 0, e = element3i + 3*surface->num_firsttriangle;triangleindex < surface->num_triangles;triangleindex++, e += 3)
 		{
@@ -3116,7 +3189,6 @@ static void Mod_GenerateLightmaps_CreateLights_ComputeSVBSP(dp_model_t *model, l
 	Mem_Free(nodes);
 }
 
-extern int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
 static void Mod_GenerateLightmaps_CreateLights(dp_model_t *model)
 {
 	int index;
@@ -3183,8 +3255,6 @@ static qboolean Mod_GenerateLightmaps_SamplePoint_SVBSP(const svbsp_t *svbsp, co
 	return num == -1; // true if empty, false if solid (shadowed)
 }
 
-extern cvar_t r_shadow_lightattenuationdividebias;
-extern cvar_t r_shadow_lightattenuationlinearscale;
 static void Mod_GenerateLightmaps_SamplePoint(const float *pos, const float *normal, float *sample, int numoffsets, const float *offsets)
 {
 	int i;
@@ -3357,14 +3427,16 @@ static void Mod_GenerateLightmaps_DestroyLightmaps(dp_model_t *model)
 	if (model->brushq3.data_lightmaps)
 	{
 		for (i = 0;i < model->brushq3.num_mergedlightmaps;i++)
-			R_FreeTexture(model->brushq3.data_lightmaps[i]);
+			if (model->brushq3.data_lightmaps[i])
+				R_FreeTexture(model->brushq3.data_lightmaps[i]);
 		Mem_Free(model->brushq3.data_lightmaps);
 		model->brushq3.data_lightmaps = NULL;
 	}
 	if (model->brushq3.data_deluxemaps)
 	{
 		for (i = 0;i < model->brushq3.num_mergedlightmaps;i++)
-			R_FreeTexture(model->brushq3.data_deluxemaps[i]);
+			if (model->brushq3.data_deluxemaps[i])
+				R_FreeTexture(model->brushq3.data_deluxemaps[i]);
 		Mem_Free(model->brushq3.data_deluxemaps);
 		model->brushq3.data_deluxemaps = NULL;
 	}
@@ -3438,12 +3510,20 @@ static void Mod_GenerateLightmaps_UnweldTriangles(dp_model_t *model)
 			model->surfmesh.data_tvector3f[outvertexindex*3+2] = oldsurfmesh.data_tvector3f[vertexindex*3+2];
 			model->surfmesh.data_texcoordtexture2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordtexture2f[vertexindex*2+0];
 			model->surfmesh.data_texcoordtexture2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordtexture2f[vertexindex*2+1];
-			model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+0];
-			model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+1];
-			model->surfmesh.data_lightmapcolor4f[outvertexindex*4+0] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+0];
-			model->surfmesh.data_lightmapcolor4f[outvertexindex*4+1] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+1];
-			model->surfmesh.data_lightmapcolor4f[outvertexindex*4+2] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+2];
-			model->surfmesh.data_lightmapcolor4f[outvertexindex*4+3] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+3];
+			if (oldsurfmesh.data_texcoordlightmap2f)
+			{
+				model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+0] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+0];
+				model->surfmesh.data_texcoordlightmap2f[outvertexindex*2+1] = oldsurfmesh.data_texcoordlightmap2f[vertexindex*2+1];
+			}
+			if (oldsurfmesh.data_lightmapcolor4f)
+			{
+				model->surfmesh.data_lightmapcolor4f[outvertexindex*4+0] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+0];
+				model->surfmesh.data_lightmapcolor4f[outvertexindex*4+1] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+1];
+				model->surfmesh.data_lightmapcolor4f[outvertexindex*4+2] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+2];
+				model->surfmesh.data_lightmapcolor4f[outvertexindex*4+3] = oldsurfmesh.data_lightmapcolor4f[vertexindex*4+3];
+			}
+			else
+				Vector4Set(model->surfmesh.data_lightmapcolor4f + 4*outvertexindex, 1, 1, 1, 1);
 			model->surfmesh.data_element3i[surface->num_firsttriangle*3+i] = outvertexindex;
 			outvertexindex++;
 		}
@@ -3616,7 +3696,9 @@ static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model)
 	lightmapnumber++;
 	Mod_AllocLightmap_Free(&lmstate);
 
-	// now together lightmap textures
+	// now put triangles together into lightmap textures, and do not allow
+	// triangles of a surface to go into different textures (as that would
+	// require rewriting the surface list)
 	model->brushq3.deluxemapping_modelspace = true;
 	model->brushq3.deluxemapping = true;
 	model->brushq3.num_mergedlightmaps = lightmapnumber;
@@ -3742,6 +3824,21 @@ static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model)
 		lightmapindex = mod_generatelightmaps_lightmaptriangles[surface->num_firsttriangle].lightmapindex;
 		surface->lightmaptexture = model->brushq3.data_lightmaps[lightmapindex];
 		surface->deluxemaptexture = model->brushq3.data_deluxemaps[lightmapindex];
+		surface->lightmapinfo = NULL;
+	}
+
+	model->brush.LightPoint = Mod_GenerateLightmaps_LightPoint;
+	model->brushq1.lightdata = NULL;
+	model->brushq1.lightmapupdateflags = NULL;
+	model->brushq1.firstrender = false;
+	model->brushq1.num_lightstyles = 0;
+	model->brushq1.data_lightstyleinfo = NULL;
+	for (i = 0;i < model->brush.numsubmodels;i++)
+	{
+		model->brush.submodels[i]->brushq1.lightmapupdateflags = NULL;
+		model->brush.submodels[i]->brushq1.firstrender = false;
+		model->brush.submodels[i]->brushq1.num_lightstyles = 0;
+		model->brush.submodels[i]->brushq1.data_lightstyleinfo = NULL;
 	}
 }