Esempio n. 1
0
void compress_compatability_test ()
{
	unsigned char *v = (unsigned char *)malloc (16u);
	memset (v, 0, 16u);
	if (sizeof(char) !=1 || sizeof(unsigned int) != 4 || sizeof(float) != 4)
		fail ();
	*(float *)(v+1) = 0.123f;
	if (*(unsigned int *)v != 4226247936u || *(unsigned int *)(v+1) != 1039918957u)
		fail ();
	*(float *)(v+1) = -58;
	if (*(unsigned int *)v != 1744830464u || *(unsigned int *)(v+1) != 3261595648u)
		fail ();
	float f[5] = {0.123f, 1.f, 0.f, 0.123f, 0.f};
	memset (v, ~0, 16u);
	vector_compress (VECTOR24, v, &f[0], &f[1], &f[2]);
	float_compress (FLOAT16, v+6, &f[3]);
	float_compress (FLOAT16, v+4, &f[4]);
	if (((unsigned int *)v)[0] != 4286318595u || ((unsigned int *)v)[1] != 3753771008u)
		fail ();
	float_decompress (FLOAT16, v+6, &f[3]);
	float_decompress (FLOAT16, v+4, &f[4]);
	vector_decompress (VECTOR24, v, &f[0], &f[1], &f[2]);
	float ans[5] = {0.109375f,1.015625f,0.015625f,0.123001f,0.000000f};
	int i;
	for (i=0; i<5; ++i)
		if (f[i]-ans[i] > 0.00001f || f[i]-ans[i] < -0.00001f)
			fail ();
	free (v);
}
Esempio n. 2
0
void            MakeRGBScales(const int threadnum)
{
    int             i;
    unsigned        j;
    vec3_t          delta;
    vec_t           dist;
    int             count;
    float           trans[3];
    float           trans_one;
    patch_t*        patch;
    patch_t*        patch2;
    vec3_t          origin;
    vec_t           area;
    const vec_t*    normal1;
    const vec_t*    normal2;

#ifdef HLRAD_TRANSPARENCY_CPP
    unsigned int    fastfind_index = 0;
#endif
    vec_t           total;

#ifdef HLRAD_TRANSFERDATA_COMPRESS
    transfer_raw_index_t* tIndex;
    float* tRGBData;

    transfer_raw_index_t* tIndex_All = (transfer_raw_index_t*)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
    float* tRGBData_All = (float*)AllocBlock(sizeof(float[3]) * MAX_PATCHES);
#else
    transfer_raw_index_t* tIndex;
    rgb_transfer_data_t* tRGBData;

    transfer_raw_index_t* tIndex_All = (transfer_raw_index_t*)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
    rgb_transfer_data_t* tRGBData_All = (rgb_transfer_data_t*)AllocBlock(sizeof(rgb_transfer_data_t) * MAX_PATCHES);
#endif

    count = 0;

    while (1)
    {
        i = GetThreadWork();
        if (i == -1)
            break;

        patch = g_patches + i;
        patch->iIndex = 0;
        patch->iData = 0;

#ifndef HLRAD_TRANSNONORMALIZE
        total = 0.0;
#endif

        tIndex = tIndex_All;
        tRGBData = tRGBData_All;

        VectorCopy(patch->origin, origin);
        normal1 = getPlaneFromFaceNumber(patch->faceNumber)->normal;

        area = patch->area;
#ifdef HLRAD_TRANSLUCENT
		vec3_t backorigin;
		vec3_t backnormal;
		if (patch->translucent_b)
		{
			VectorMA (patch->origin, -(g_translucentdepth + 2*PATCH_HUNT_OFFSET), normal1, backorigin);
			VectorSubtract (vec3_origin, normal1, backnormal);
		}
#endif
#ifdef HLRAD_DIVERSE_LIGHTING
		bool lighting_diversify;
		vec_t lighting_power;
		vec_t lighting_scale;
		int miptex = g_texinfo[g_dfaces[patch->faceNumber].texinfo].miptex;
		lighting_power = g_lightingconeinfo[miptex][0];
		lighting_scale = g_lightingconeinfo[miptex][1];
		lighting_diversify = (lighting_power != 1.0 || lighting_scale != 1.0);
#endif

        // find out which patch2's will collect light
        // from patch
		// HLRAD_NOSWAP: patch collect light from patch2

        for (j = 0, patch2 = g_patches; j < g_num_patches; j++, patch2++)
        {
            vec_t           dot1;
            vec_t           dot2;
            vec3_t          transparency = {1.0,1.0,1.0};
#ifdef HLRAD_TRANSLUCENT
			bool useback;
			useback = false;
#endif

            if (!g_CheckVisBit(i, j
				, transparency
#ifdef HLRAD_TRANSPARENCY_CPP
				, fastfind_index
#endif
				) || (i == j))
            {
#ifdef HLRAD_TRANSLUCENT
				if (patch->translucent_b)
				{
					if (!CheckVisBitBackwards(i, j, backorigin, backnormal
	#ifdef HLRAD_HULLU
						, transparency
	#endif
						) || (i==j))
					{
						continue;
					}
					useback = true;
				}
				else
				{
					continue;
				}
#else
                continue;
#endif
            }

            normal2 = getPlaneFromFaceNumber(patch2->faceNumber)->normal;

            // calculate transferemnce
            VectorSubtract(patch2->origin, origin, delta);
#ifdef HLRAD_TRANSLUCENT
			if (useback)
			{
				VectorSubtract (patch2->origin, backorigin, delta);
			}
#endif
#ifdef HLRAD_ACCURATEBOUNCE
			// move emitter back to its plane
			VectorMA (delta, -PATCH_HUNT_OFFSET, normal2, delta);
#endif

            dist = VectorNormalize(delta);
            dot1 = DotProduct(delta, normal1);
#ifdef HLRAD_TRANSLUCENT
			if (useback)
			{
				dot1 = DotProduct (delta, backnormal);
			}
#endif
            dot2 = -DotProduct(delta, normal2);
#ifdef HLRAD_ACCURATEBOUNCE
#ifdef HLRAD_ACCURATEBOUNCE_ALTERNATEORIGIN
			bool light_behind_surface = false;
			if (dot1 <= NORMAL_EPSILON)
			{
				light_behind_surface = true;
			}
#else
			if (dot1 <= NORMAL_EPSILON)
			{
				continue;
			}
#endif
			if (dot2 * dist <= MINIMUM_PATCH_DISTANCE)
			{
				continue;
			}
#endif
			
#ifdef HLRAD_DIVERSE_LIGHTING
			if (lighting_diversify
	#ifdef HLRAD_ACCURATEBOUNCE_ALTERNATEORIGIN
				&& !light_behind_surface
	#endif
				)
			{
				dot1 = lighting_scale * pow (dot1, lighting_power);
			}
#endif
            trans_one = (dot1 * dot2) / (dist * dist);         // Inverse square falloff factoring angle between patch normals
            
#ifdef HLRAD_TRANSWEIRDFIX
#ifdef HLRAD_NOSWAP
			if (trans_one * patch2->area > 0.8f)
			{
				trans_one = 0.8f / patch2->area;
			}
#else
			if (trans_one * area > 0.8f)
			{
				trans_one = 0.8f / area;
			}
#endif
#endif
#ifdef HLRAD_ACCURATEBOUNCE
			if (dist < patch2->emitter_range - ON_EPSILON)
			{
	#ifdef HLRAD_ACCURATEBOUNCE_ALTERNATEORIGIN
				if (light_behind_surface)
				{
					trans_one = 0.0;
				}
	#endif
				vec_t sightarea;
				const vec_t *receiver_origin;
				const vec_t *receiver_normal;
				const Winding *emitter_winding;
				receiver_origin = origin;
				receiver_normal = normal1;
	#ifdef HLRAD_TRANSLUCENT
				if (useback)
				{
					receiver_origin = backorigin;
					receiver_normal = backnormal;
				}
	#endif
				emitter_winding = patch2->winding;
				sightarea = CalcSightArea (receiver_origin, receiver_normal, emitter_winding, patch2->emitter_skylevel
	#ifdef HLRAD_DIVERSE_LIGHTING
					, lighting_power, lighting_scale
	#endif
					);
				
				vec_t frac;
				frac = dist / patch2->emitter_range;
				frac = (frac - 0.5f) * 2.0f; // make a smooth transition between the two methods
				frac = max (0, min (frac, 1));
				trans_one = frac * trans_one + (1 - frac) * (sightarea / patch2->area); // because later we will multiply this back
			}
	#ifdef HLRAD_ACCURATEBOUNCE_ALTERNATEORIGIN
			else
			{
				if (light_behind_surface)
				{
					continue;
				}
			}
	#endif
#endif
#ifdef HLRAD_ACCURATEBOUNCE_REDUCEAREA
			trans_one *= patch2->exposure;
#endif
            VectorFill(trans, trans_one);
            VectorMultiply(trans, transparency, trans); //hullu: add transparency effect
#ifdef HLRAD_TRANSLUCENT
			if (patch->translucent_b)
			{
				if (useback)
				{
					for (int x = 0; x < 3; x++)
					{
						trans[x] = patch->translucent_v[x] * trans[x];
					}
				}
				else
				{
					for (int x = 0; x < 3; x++)
					{
						trans[x] = (1 - patch->translucent_v[x]) * trans[x];
					}
				}
			}
#endif

#ifdef HLRAD_RGBTRANSFIX
#ifdef HLRAD_ACCURATEBOUNCE
			if (trans_one <= 0.0)
			{
				continue;
			}
#else
			if (trans_one >= 0)
#endif
			{
#ifndef HLRAD_TRANSWEIRDFIX
	#ifdef HLRAD_NOSWAP
				send = trans_one * area;
	#else
				send = trans_one * patch2->area;
	#endif
				if (send > 0.4f)
				{
	#ifdef HLRAD_NOSWAP
					trans_one = 0.4f / area;
	#else
                    trans_one = 0.4f / patch2->area;
	#endif
					send = 0.4f;
					VectorFill(trans, trans_one);
					VectorMultiply(trans, transparency, trans);
				}
#endif /*HLRAD_TRANSWEIRDFIX*/
	#ifndef HLRAD_TRANSNONORMALIZE
				total += send;
	#endif
#else /*HLRAD_RGBTRANSFIX*/
#ifdef HLRAD_ACCURATEBOUNCE
            if (VectorAvg(trans) <= 0.0)
			{
				continue;
			}
#else
            if (VectorAvg(trans) >= 0)
#endif
            {
            	/////////////////////////////////////////RED
                send = trans[0] * patch2->area;
                // Caps light from getting weird
                if (send > 0.4f) 
                {
                    trans[0] = 0.4f / patch2->area;
                    send = 0.4f;
                }
	#ifndef HLRAD_TRANSNONORMALIZE
                total += send / 3.0f;
	#endif
                
            	/////////////////////////////////////////GREEN
                send = trans[1] * patch2->area;
                // Caps light from getting weird
                if (send > 0.4f) 
                {
                    trans[1] = 0.4f / patch2->area;
                    send = 0.4f;
                }
	#ifndef HLRAD_TRANSNONORMALIZE
                total += send / 3.0f;
	#endif

            	/////////////////////////////////////////BLUE
                send = trans[2] * patch2->area;
                // Caps light from getting weird
                if (send > 0.4f) 
                {
                    trans[2] = 0.4f / patch2->area;
                    send = 0.4f;
                }
	#ifndef HLRAD_TRANSNONORMALIZE
                total += send / 3.0f;
	#endif
#endif /*HLRAD_RGBTRANSFIX*/

#ifdef HLRAD_TRANSFERDATA_COMPRESS
                VectorScale(trans, patch2 -> area, trans);
#else
                // scale to 16 bit (black magic)
#ifdef HLRAD_NOSWAP
                VectorScale(trans, patch2 -> area * INVERSE_TRANSFER_SCALE, trans);
#else
                VectorScale(trans, area * INVERSE_TRANSFER_SCALE, trans);
#endif /*HLRAD_NOSWAP*/

                if (trans[0] >= TRANSFER_SCALE_MAX)
                {
                    trans[0] = TRANSFER_SCALE_MAX;
                }
                if (trans[1] >= TRANSFER_SCALE_MAX)
                {
                    trans[1] = TRANSFER_SCALE_MAX;
                }
                if (trans[2] >= TRANSFER_SCALE_MAX)
                {
                    trans[2] = TRANSFER_SCALE_MAX;
                }
#endif
            }
#ifndef HLRAD_ACCURATEBOUNCE
            else
            {
#if 0
                Warning("transfer < 0 (%4.3f %4.3f %4.3f): dist=(%f)\n"
                        "   dot1=(%f) patch@(%4.3f %4.3f %4.3f) normal(%4.3f %4.3f %4.3f)\n"
                        "   dot2=(%f) patch@(%4.3f %4.3f %4.3f) normal(%4.3f %4.3f %4.3f)\n",
                        trans[0], trans[1], trans[2], dist,
                        dot1, patch->origin[0], patch->origin[1], patch->origin[2], patch->normal[0], patch->normal[1],
                        patch->normal[2], dot2, patch2->origin[0], patch2->origin[1], patch2->origin[2],
                        patch2->normal[0], patch2->normal[1], patch2->normal[2]);
#endif
                VectorFill(trans,0.0);
            }
#endif

#ifdef HLRAD_TRANSFERDATA_COMPRESS
			VectorCopy(trans, tRGBData);
            *tIndex = j;
            tRGBData+=3;
            tIndex++;
            patch->iData++;
#else
            VectorCopy(trans, *tRGBData);
            *tIndex = j;
            tRGBData++;
            tIndex++;
            patch->iData++;
#endif
            count++;
        }

        // copy the transfers out
        if (patch->iData)
        {
#ifdef HLRAD_TRANSFERDATA_COMPRESS
			unsigned	data_size = patch->iData * vector_size[g_rgbtransfer_compress_type] + unused_size;
#else
            unsigned data_size = patch->iData * sizeof(rgb_transfer_data_t);
#endif

            patch->tRGBData = (rgb_transfer_data_t*)AllocBlock(data_size);
            patch->tIndex = CompressTransferIndicies(tIndex_All, patch->iData, &patch->iIndex);

            hlassume(patch->tRGBData != NULL, assume_NoMemory);
            hlassume(patch->tIndex != NULL, assume_NoMemory);

            ThreadLock();
            g_transfer_data_bytes += data_size;
            ThreadUnlock();

#ifdef HLRAD_REFLECTIVITY
			total = 1 / Q_PI;
#else
#ifdef HLRAD_TRANSNONORMALIZE
	#ifdef HLRAD_TRANSTOTAL_HACK
			total = g_transtotal_hack / Q_PI;
	#else
			total = 0.5 / Q_PI;
	#endif
#else
            //
            // normalize all transfers so exactly 50% of the light
            // is transfered to the surroundings
            //
            total = 0.5 / total;
#endif
#endif
            {
#ifdef HLRAD_TRANSFERDATA_COMPRESS
                unsigned        x;
                rgb_transfer_data_t* t1 = patch->tRGBData;
				float* t2 = tRGBData_All;

				float f[3];
                for (x = 0; x < patch->iData; x++, t1+=vector_size[g_rgbtransfer_compress_type], t2+=3)
                {
                     VectorScale( t2, total, f );
					 vector_compress (g_rgbtransfer_compress_type, t1, &f[0], &f[1], &f[2]);
                }
#else
                unsigned        x;
                rgb_transfer_data_t* t1 = patch->tRGBData;
                rgb_transfer_data_t* t2 = tRGBData_All;

                for (x = 0; x < patch->iData; x++, t1++, t2++)
                {
                     VectorScale( *t2, total, *t1 );
                }
#endif
            }
        }
    }

    FreeBlock(tIndex_All);
    FreeBlock(tRGBData_All);

    ThreadLock();
    g_total_transfer += count;
    ThreadUnlock();
}

#ifdef SYSTEM_WIN32
#pragma warning(pop)
#endif

/*
 * =============
 * SwapTransfersTask
 * 
 * Change transfers from light sent out to light collected in.
 * In an ideal world, they would be exactly symetrical, but
 * because the form factors are only aproximated, then normalized,
 * they will actually be rather different.
 * =============
 */
#ifndef HLRAD_NOSWAP
void            SwapRGBTransfers(const int patchnum)
{
    patch_t*        		patch	= &g_patches[patchnum];
    transfer_index_t*		tIndex	= patch->tIndex;
    rgb_transfer_data_t* 	tRGBData= patch->tRGBData;
    unsigned        x;

    for (x = 0; x < patch->iIndex; x++, tIndex++)
    {
        unsigned        size = (tIndex->size + 1);
        unsigned        patchnum2 = tIndex->index;
        unsigned        y;

        for (y = 0; y < size; y++, tRGBData++, patchnum2++)
        {
            patch_t*        patch2 = &g_patches[patchnum2];

            if (patchnum2 > patchnum)
            {                                              // done with this list
                return;
            }
            else if (!patch2->iData)
            {                                              // Set to zero in this impossible case
                Log("patch2 has no iData\n");
                VectorFill(*tRGBData, 0);
                continue;
            }
            else
            {
                transfer_index_t* tIndex2 = patch2->tIndex;
                rgb_transfer_data_t* tRGBData2 = patch2->tRGBData;
                int             offset = FindTransferOffsetPatchnum(tIndex2, patch2, patchnum);

                if (offset >= 0)
                {
                    rgb_transfer_data_t tmp;
                    VectorCopy(*tRGBData, tmp)

                    VectorCopy(tRGBData2[offset], *tRGBData);
                    VectorCopy(tmp, tRGBData2[offset]);
                }
                else
                {                                          // Set to zero in this impossible case
                    Log("FindTransferOffsetPatchnum returned -1 looking for patch %d in patch %d's transfer lists\n",
                        patchnum, patchnum2);
                    VectorFill(*tRGBData, 0);
                    return;
                }
            }
        }
    }
}