예제 #1
0
파일: compress.cpp 프로젝트: mittorn/XashXT
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);
}
예제 #2
0
void            MakeScales(const int threadnum)
{
    int             i;
    unsigned        j;
    vec3_t          delta;
    vec_t           dist;
    int             count;
    float           trans;
    patch_t*        patch;
    patch_t*        patch2;
    vec3_t          origin;
    vec_t           area;
    const vec_t*    normal1;
    const vec_t*    normal2;

#ifdef HLRAD_HULLU
#ifdef HLRAD_TRANSPARENCY_CPP
    unsigned int    fastfind_index = 0;
#endif
#endif

    vec_t           total;

#ifdef HLRAD_TRANSFERDATA_COMPRESS
    transfer_raw_index_t* tIndex;
    float* tData;

    transfer_raw_index_t* tIndex_All = (transfer_raw_index_t*)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
    float* tData_All = (float*)AllocBlock(sizeof(float) * MAX_PATCHES);
#else
    transfer_raw_index_t* tIndex;
    transfer_data_t* tData;

    transfer_raw_index_t* tIndex_All = (transfer_raw_index_t*)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
    transfer_data_t* tData_All = (transfer_data_t*)AllocBlock(sizeof(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;
        tData = tData_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;

#ifdef HLRAD_HULLU
            vec3_t          transparency = {1.0,1.0,1.0};
#endif
#ifdef HLRAD_TRANSLUCENT
			bool useback;
			useback = false;
#endif

            if (!g_CheckVisBit(i, j
#ifdef HLRAD_HULLU
				, transparency
#ifdef HLRAD_TRANSPARENCY_CPP
				, fastfind_index
#endif
#endif
				) || (i == j))
            {
#ifdef HLRAD_TRANSLUCENT
				if (patch->translucent_b)
				{
					if ((i == j) ||
						!CheckVisBitBackwards(i, j, backorigin, backnormal
	#ifdef HLRAD_HULLU
						, transparency
	#endif
						))
					{
						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 = (dot1 * dot2) / (dist * dist);         // Inverse square falloff factoring angle between patch normals
#ifdef HLRAD_TRANSWEIRDFIX
#ifdef HLRAD_NOSWAP
            if (trans * patch2->area > 0.8f)
				trans = 0.8f / patch2->area;
#else
			// HLRAD_TRANSWEIRDFIX:
			// we should limit "trans(patch2receive) * patch1area" 
			// instead of "trans(patch2receive) * patch2area".
			// also raise "0.4f" to "0.8f" ( 0.8/Q_PI = 1/4).
            if (trans * area > 0.8f)
                trans = 0.8f / area;
#endif
#endif
#ifdef HLRAD_ACCURATEBOUNCE
			if (dist < patch2->emitter_range - ON_EPSILON)
			{
	#ifdef HLRAD_ACCURATEBOUNCE_ALTERNATEORIGIN
				if (light_behind_surface)
				{
					trans = 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 = frac * trans + (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 *= patch2->exposure;
#endif
#ifdef HLRAD_HULLU
            trans = trans * VectorAvg(transparency); //hullu: add transparency effect
#endif
#ifdef HLRAD_TRANSLUCENT
			if (patch->translucent_b)
			{
				if (useback)
				{
					trans *= VectorAvg (patch->translucent_v);
				}
				else
				{
					trans *= 1 - VectorAvg (patch->translucent_v);
				}
			}
#endif

#ifndef HLRAD_ACCURATEBOUNCE
            if (trans >= 0)
#endif
            {
#ifndef HLRAD_TRANSWEIRDFIX
#ifdef HLRAD_NOSWAP
				send = trans * area;
#else
                send = trans * patch2->area;
#endif

                // Caps light from getting weird
                if (send > 0.4f)
                {
#ifdef HLRAD_NOSWAP
					trans = 0.4f / area;
#else
                    trans = 0.4f / patch2->area;
#endif
                    send = 0.4f;
                }
#endif /*HLRAD_TRANSWEIRDFIX*/

#ifndef HLRAD_TRANSNONORMALIZE
                total += send;
#endif

#ifdef HLRAD_TRANSFERDATA_COMPRESS
				trans = trans * patch2->area;
#else
                // scale to 16 bit (black magic)
				// BUG: (in MakeRGBScales) convert to integer will lose data. --vluzacn
#ifdef HLRAD_NOSWAP
                trans = trans * patch2->area * INVERSE_TRANSFER_SCALE;
#else
                trans = trans * area * INVERSE_TRANSFER_SCALE;
#endif /*HLRAD_NOSWAP*/
                if (trans >= TRANSFER_SCALE_MAX)
                {
                    trans = TRANSFER_SCALE_MAX;
                }
#endif
            }
#ifndef HLRAD_ACCURATEBOUNCE
            else
            {
#if 0
                Warning("transfer < 0 (%f): 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, 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
                trans = 0.0;
            }
#endif
#ifdef HLRAD_ACCURATEBOUNCE
			if (trans <= 0.0)
			{
				continue;
			}
#endif

            *tData = trans;
            *tIndex = j;
            tData++;
            tIndex++;
            patch->iData++;
            count++;
        }

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

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

            hlassume(patch->tData != 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 // BAD assumption when there is SKY.
            //
            // 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;
                transfer_data_t* t1 = patch->tData;
                float* t2 = tData_All;

				float	f;
				for (x = 0; x < patch->iData; x++, t1+=float_size[g_transfer_compress_type], t2++)
				{
					f = (*t2) * total;
					float_compress (g_transfer_compress_type, t1, &f);
				}
#else
                unsigned        x;
                transfer_data_t* t1 = patch->tData;
                transfer_data_t* t2 = tData_All;

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

    FreeBlock(tIndex_All);
    FreeBlock(tData_All);

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