Ejemplo n.º 1
0
static void     DumpHullWindings(const brushhull_t* const hull)
{
    int             x = 0;
    bface_t*        face;

    for (face = hull->faces; face; face = face->next)
    {
        Developer(DEVELOPER_LEVEL_MEGASPAM, "Winding %d\n", x++);
        face->w->Print();
        Developer(DEVELOPER_LEVEL_MEGASPAM, "\n");
    }
}
Ejemplo n.º 2
0
static Winding* NewWindingFromPlane(const brushhull_t* const hull, const int planenum)
{
    Winding*        winding;
    Winding*        front;
    Winding*        back;
    bface_t*        face;
    plane_t*        plane;

    plane = &g_mapplanes[planenum];
    winding = new Winding(plane->normal, plane->dist);

    for (face = hull->faces; face; face = face->next)
    {
        plane = &g_mapplanes[face->planenum];
        winding->Clip(plane->normal, plane->dist, &front, &back);
        delete winding;

        if (front)
        {
            delete front;
        }
        if (back)
        {
            winding = back;
        }
        else
        {
            Developer(DEVELOPER_LEVEL_ERROR, "NewFaceFromPlane returning NULL");
            return NULL;
        }
    }

    return winding;
}
Ejemplo n.º 3
0
static vec_t    CalculateSolidVolume(const brushhull_t* const hull)
{
    // calculate polyhedron origin
    // subdivide face winding into triangles

    // for each face
    // calculate volume of triangle of face to origin
    // add subidivided volume chunk to total

    int             x = 0;
    vec_t           volume = 0.0;
    vec_t           inverse;
    vec3_t          midpoint = { 0.0, 0.0, 0.0 };

    bface_t*        face;

    for (face = hull->faces; face; face = face->next, x++)
    {
        vec3_t          facemid;

        face->w->getCenter(facemid);
        VectorAdd(midpoint, facemid, midpoint);
        Developer(DEVELOPER_LEVEL_MESSAGE, "Midpoint for face %d is %f %f %f\n", x, facemid[0], facemid[1], facemid[2]);
    }

    inverse = 1.0 / x;

    VectorScale(midpoint, inverse, midpoint);

    Developer(DEVELOPER_LEVEL_MESSAGE, "Midpoint for hull is %f %f %f\n", midpoint[0], midpoint[1], midpoint[2]);

    for (face = hull->faces; face; face = face->next, x++)
    {
        plane_t*        plane = &g_mapplanes[face->planenum];
        vec_t           area = face->w->getArea();
        vec_t           dist = DotProduct(plane->normal, midpoint);

        dist -= plane->dist;
        dist = fabs(dist);

        volume += area * dist / 3.0;
    }

    Developer(DEVELOPER_LEVEL_MESSAGE, "Volume for brush is %f\n", volume);

    return volume;
}
Ejemplo n.º 4
0
/*
 * ================
 * exists
 * ================
 */
bool            q_exists(const char* const filename)
{
    FILE*           f;

    f = fopen(filename, "rb");

    if (!f)
    {
        IfDebug(Developer(DEVELOPER_LEVEL_SPAM, "Checking for existance of file %s (failed)\n", filename));
        return false;
    }
    else
    {
        fclose(f);
        IfDebug(Developer(DEVELOPER_LEVEL_SPAM, "Checking for existance of file %s (success)\n", filename));
        return true;
    }
}
Ejemplo n.º 5
0
void LoadWadcfgfile (const char *filename)
{
	int count = 0;
	int size;
	char *buffer;
	size = LoadFile (filename, &buffer);
	ParseFromMemory (buffer, size);
	while (GetToken (true))
	{
		bool include = false;
		wadpath_t *current;
		if (!stricmp (g_token, "include"))
		{
			include = true;
			if (!GetToken (true))
			{
				Error ("parsing '%s': unexpected end of file.", filename);
			}
		}
		Developer (DEVELOPER_LEVEL_MESSAGE, "LoadWadcfgfile: adding wad file '%s'.\n", g_token);
		if (g_iNumWadPaths >= MAX_WADPATHS)
		{
			Error ("parsing '%s': too many wad files.", filename);
		}
		count++;
		current = (wadpath_t *)malloc (sizeof (wadpath_t));
		hlassume (current != NULL, assume_NoMemory);
		g_pWadPaths[g_iNumWadPaths] = current;
		g_iNumWadPaths++;
		safe_strncpy (current->path, g_token, _MAX_PATH);
		current->usedbymap = true; // what's this?
		current->usedtextures = 0;
		if (include)
		{
			Developer (DEVELOPER_LEVEL_MESSAGE, "LoadWadcfgfile: including '%s'.\n", current->path);
			g_WadInclude.push_back(current->path);
		}
	}
	free (buffer); // should not be freed because it is still being used as script buffer
	Log ("Using custom wadfile configuration: '%s' (with %i wad%s)\n", filename, count, count > 1 ? "s" : "");
}
Ejemplo n.º 6
0
// =====================================================================================
//  LoadLump
// =====================================================================================
int             LoadLump(const lumpinfo_t* const source, byte* dest, int* texsize)
{
    //Log("** PnFNFUNC: LoadLump\n");

    *texsize = 0;
    if (source->filepos)
    {
        if (fseek(texfiles[source->iTexFile], source->filepos, SEEK_SET))
        {
            Warning("fseek to %d failed\n", source->filepos);
        }
        *texsize = source->disksize;

        bool wadinclude = false;
        std::map< int, bool >::iterator it;
        it = s_WadIncludeMap.find(source->iTexFile);
        if (it != s_WadIncludeMap.end())
        {
            wadinclude = it->second;
        }

        // Should we just load the texture header w/o the palette & bitmap?
        if ((g_wadtextures && !wadinclude) || !TestIncludeTextureNamed(source->name))
        {
            // Just read the miptex header and zero out the data offsets.
            // We will load the entire texture from the WAD at engine runtime
            int             i;
            miptex_t*       miptex = (miptex_t*)dest;
            SafeRead(texfiles[source->iTexFile], dest, sizeof(miptex_t));

            for (i = 0; i < MIPLEVELS; i++)
                miptex->offsets[i] = 0;
            return sizeof(miptex_t);
        }
        else
        {
			Developer(DEVELOPER_LEVEL_MESSAGE,"Including texture %s\n",source->name);
            // Load the entire texture here so the BSP contains the texture
            SafeRead(texfiles[source->iTexFile], dest, source->disksize);
            return source->disksize;
        }
    }

    Warning("::LoadLump() texture %s not found!", source->name);
    return 0;
}
Ejemplo n.º 7
0
void            CalculateBrushUnions(const int brushnum)
{
    int             bn, hull;
    brush_t*        b1;
    brush_t*        b2;
    brushhull_t*    bh1;
    brushhull_t*    bh2;
    entity_t*       e;

    b1 = &g_mapbrushes[brushnum];
    e = &g_entities[b1->entitynum];

    for (hull = 0; hull < 1 /* NUM_HULLS */ ; hull++)
    {
        bh1 = &b1->hulls[hull];
        if (!bh1->faces)                                   // Skip it if it is not in this hull
        {
            continue;
        }

        for (bn = brushnum + 1; bn < e->numbrushes; bn++)
        {                                                  // Only compare if b2 > b1, tests are communitive
            b2 = &g_mapbrushes[e->firstbrush + bn];
            bh2 = &b2->hulls[hull];

            if (!bh2->faces)                               // Skip it if it is not in this hull
            {
                continue;
            }
            if (b1->contents != b2->contents)
            {
                continue;                                  // different contents, ignore
            }

            Developer(DEVELOPER_LEVEL_SPAM, "Processing hull %d brush %d and brush %d\n", hull, brushnum, bn);

            {
                brushhull_t     union_hull;
                bface_t*        face;

                union_hull.bounds = bh1->bounds;

                union_hull.faces = CopyFaceList(bh1->faces);

                for (face = bh2->faces; face; face = face->next)
                {
                    AddPlaneToUnion(&union_hull, face->planenum);
                }

                // union was clipped away (no intersection)
                if (!union_hull.faces)
                {
                    continue;
                }

                if (g_developer >= DEVELOPER_LEVEL_MESSAGE)
                {
                    Log("\nUnion windings\n");
                    DumpHullWindings(&union_hull);

                    Log("\nBrush %d windings\n", brushnum);
                    DumpHullWindings(bh1);

                    Log("\nBrush %d windings\n", bn);
                    DumpHullWindings(bh2);
                }


                {
                    vec_t           volume_brush_1;
                    vec_t           volume_brush_2;
                    vec_t           volume_brush_union;
                    vec_t           volume_ratio_1;
                    vec_t           volume_ratio_2;

                    if (isInvalidHull(&union_hull))
                    {
                        FreeFaceList(union_hull.faces);
                        continue;
                    }

                    volume_brush_union = CalculateSolidVolume(&union_hull);
                    volume_brush_1 = CalculateSolidVolume(bh1);
                    volume_brush_2 = CalculateSolidVolume(bh2);

                    volume_ratio_1 = volume_brush_union / volume_brush_1;
                    volume_ratio_2 = volume_brush_union / volume_brush_2;

                    if ((volume_ratio_1 > g_BrushUnionThreshold) || (g_developer >= DEVELOPER_LEVEL_MESSAGE))
                    {
                        volume_ratio_1 *= 100.0;
                        Warning("Entity %d : Brush %d intersects with brush %d by %2.3f percent", 
#ifdef HLCSG_COUNT_NEW
							b1->originalentitynum, b1->originalbrushnum, b2->originalbrushnum, 
#else
							b1->entitynum, brushnum, bn, 
#endif
							volume_ratio_1);
                    }
                    if ((volume_ratio_2 > g_BrushUnionThreshold) || (g_developer >= DEVELOPER_LEVEL_MESSAGE))
                    {
                        volume_ratio_2 *= 100.0;
                        Warning("Entity %d : Brush %d intersects with brush %d by %2.3f percent", 
#ifdef HLCSG_COUNT_NEW
							b1->originalentitynum, b2->originalbrushnum, b1->originalbrushnum, 
#else
							b1->entitynum, bn, brushnum, 
#endif
							volume_ratio_2);
                    }
                }

                FreeFaceList(union_hull.faces);
            }
        }
    }
}
Ejemplo n.º 8
0
int             GetThreadWork()
{
    int             r, f, i;
    double          ct, finish, finish2, finish3;

    ThreadLock();

    if (dispatch == 0)
    {
        oldf = 0;
    }

    if (dispatch > workcount)
    {
        Developer(DEVELOPER_LEVEL_ERROR, "dispatch > workcount!!!\n");
        ThreadUnlock();
        return -1;
    }
    if (dispatch == workcount)
    {
        Developer(DEVELOPER_LEVEL_MESSAGE, "dispatch == workcount, work is complete\n");
        ThreadUnlock();
        return -1;
    }
    if (dispatch < 0)
    {
        Developer(DEVELOPER_LEVEL_ERROR, "negative dispatch!!!\n");
        ThreadUnlock();
        return -1;
    }

    f = THREADTIMES_SIZE * dispatch / workcount;
    if (pacifier)
    {
        printf("\r%6d /%6d", dispatch, workcount);
#ifdef ZHLT_PROGRESSFILE // AJM
        if (g_progressfile)
        {
            

        }
#endif

        if (f != oldf)
        {
            ct = I_FloatTime();
            /* Fill in current time for threadtimes record */
            for (i = oldf; i <= f; i++)
            {
                if (threadtimes[i] < 1)
                {
                    threadtimes[i] = ct;
                }
            }
            oldf = f;

            if (f > 10)
            {
                finish = (ct - threadtimes[0]) * (THREADTIMES_SIZEf - f) / f;
                finish2 = 10.0 * (ct - threadtimes[f - 10]) * (THREADTIMES_SIZEf - f) / THREADTIMES_SIZEf;
                finish3 = THREADTIMES_SIZEf * (ct - threadtimes[f - 1]) * (THREADTIMES_SIZEf - f) / THREADTIMES_SIZEf;

                if (finish > 1.0)
                {
                    printf("  (%d%%: est. time to completion %ld/%ld/%ld secs)   ", f, (long)(finish), (long)(finish2),
                           (long)(finish3));
#ifdef ZHLT_PROGRESSFILE // AJM
                    if (g_progressfile)
                    {


                    }
#endif
                }
                else
                {
                    printf("  (%d%%: est. time to completion <1 sec)   ", f);

#ifdef ZHLT_PROGRESSFILE // AJM
                    if (g_progressfile)
                    {


                    }
#endif
                }
            }
        }
    }
    else
    {
        if (f != oldf)
        {
            oldf = f;
            switch (f)
            {
            case 10:
            case 20:
            case 30:
            case 40:
            case 50:
            case 60:
            case 70:
            case 80:
            case 90:
            case 100:
/*
            case 5:
            case 15:
            case 25:
            case 35:
            case 45:
            case 55:
            case 65:
            case 75:
            case 85:
            case 95:
*/
                printf("%d%%...", f);
            default:
                break;
            }
        }
    }

    r = dispatch;
    dispatch++;

    ThreadUnlock();
    return r;
}
Ejemplo n.º 9
0
void            RunThreadsOn(int workcnt, bool showpacifier, q_threadfunction func)
{
    DWORD           threadid[MAX_THREADS];
    HANDLE          threadhandle[MAX_THREADS];
    int             i;
    double          start, end;

    threadstart = I_FloatTime();
    start = threadstart;
    for (i = 0; i < THREADTIMES_SIZE; i++)
    {
        threadtimes[i] = 0;
    }
    dispatch = 0;
    workcount = workcnt;
    oldf = -1;
    pacifier = showpacifier;
    threaded = true;
    q_entry = func;

    if (workcount < dispatch)
    {
        Developer(DEVELOPER_LEVEL_ERROR, "RunThreadsOn: Workcount(%i) < dispatch(%i)\n", workcount, dispatch);
    }
    hlassume(workcount >= dispatch, assume_BadWorkcount);

    //
    // Create all the threads (suspended)
    //
    threads_InitCrit();
    for (i = 0; i < g_numthreads; i++)
    {
        HANDLE          hThread = CreateThread(NULL,
                                               0,
                                               (LPTHREAD_START_ROUTINE) ThreadEntryStub,
                                               (LPVOID) i,
                                               CREATE_SUSPENDED,
                                               &threadid[i]);

        if (hThread != NULL)
        {
            threadhandle[i] = hThread;
        }
        else
        {
            LPVOID          lpMsgBuf;

            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),       // Default language
                          (LPTSTR) & lpMsgBuf, 0, NULL);
            // Process any inserts in lpMsgBuf.
            // ...
            // Display the string.
            Developer(DEVELOPER_LEVEL_ERROR, "CreateThread #%d [%08X] failed : %s\n", i, threadhandle[i], lpMsgBuf);
            Fatal(assume_THREAD_ERROR, "Unable to create thread #%d", i);
            // Free the buffer.
            LocalFree(lpMsgBuf);
        }
    }
    CheckFatal();

    // Start all the threads
    for (i = 0; i < g_numthreads; i++)
    {
        if (ResumeThread(threadhandle[i]) == 0xFFFFFFFF)
        {
            LPVOID          lpMsgBuf;

            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),       // Default language
                          (LPTSTR) & lpMsgBuf, 0, NULL);
            // Process any inserts in lpMsgBuf.
            // ...
            // Display the string.
            Developer(DEVELOPER_LEVEL_ERROR, "ResumeThread #%d [%08X] failed : %s\n", i, threadhandle[i], lpMsgBuf);
            Fatal(assume_THREAD_ERROR, "Unable to start thread #%d", i);
            // Free the buffer.
            LocalFree(lpMsgBuf);
        }
    }
    CheckFatal();

    // Wait for threads to complete
    for (i = 0; i < g_numthreads; i++)
    {
        Developer(DEVELOPER_LEVEL_MESSAGE, "WaitForSingleObject on thread #%d [%08X]\n", i, threadhandle[i]);
        WaitForSingleObject(threadhandle[i], INFINITE);
    }
    threads_UninitCrit();

    q_entry = NULL;
    threaded = false;
    end = I_FloatTime();
    if (pacifier)
    {
        printf("\r%60s\r", "");
    }
    Log(" (%.2f seconds)\n", end - start);
}
Ejemplo n.º 10
0
// =====================================================================================
//  SubdivideFace
//      If the face is >256 in either texture direction, carve a valid sized
//      piece off and insert the remainder in the next link
// =====================================================================================
void            SubdivideFace(face_t* f, face_t** prevptr)
{
    vec_t           mins, maxs;
    vec_t           v;
    int             axis;
    int             i;
    dplane_t        plane;
    face_t*         front;
    face_t*         back;
    face_t*         next;
    texinfo_t*      tex;
    vec3_t          temp;

    // special (non-surface cached) faces don't need subdivision

#ifdef HLCSG_HLBSP_VOIDTEXINFO
	if (f->texturenum == -1)
	{
		return;
	}
#endif
    tex = &g_texinfo[f->texturenum];

    if (tex->flags & TEX_SPECIAL) 
    {
        return;
    }

    if (f->facestyle == face_hint)
    {
        return;
    }
    if (f->facestyle == face_skip)
    {
        return;
    }

#ifdef ZHLT_NULLTEX    // AJM
    if (f->facestyle == face_null)
        return; // ideally these should have their tex_special flag set, so its here jic
#endif
#ifdef HLCSG_HLBSP_SOLIDHINT
	if (f->facestyle == face_discardable)
		return;
#endif
	
    for (axis = 0; axis < 2; axis++)
    {
        while (1)
        {
#ifdef HLBSP_SUBDIVIDE_INMID
			const int maxlightmapsize = g_subdivide_size / TEXTURE_STEP + 1;
			int lightmapmins, lightmapmaxs;
			if (f->numpoints == 0)
			{
				break;
			}
			for (i = 0; i < f->numpoints; i++)
			{
				v = DotProduct (f->pts[i], tex->vecs[axis]) + tex->vecs[axis][3];
				if (i == 0 || v < mins)
				{
					mins = v;
				}
				if (i == 0 || v > maxs)
				{
					maxs = v;
				}
			}
			lightmapmins = (int)floor (mins / TEXTURE_STEP - 0.05); // the worst case
			lightmapmaxs = (int)ceil (maxs / TEXTURE_STEP + 0.05); // the worst case
			if (lightmapmaxs - lightmapmins <= maxlightmapsize)
			{
				break;
			}
#else
            mins = 999999;
            maxs = -999999;

            for (i = 0; i < f->numpoints; i++)
            {
                v = DotProduct(f->pts[i], tex->vecs[axis]);
                if (v < mins)
                {
                    mins = v;
                }
                if (v > maxs)
                {
                    maxs = v;
                }
            }

            if ((maxs - mins) <= g_subdivide_size)
            {
                break;
            }
#endif
                
            // split it
            subdivides++;

            VectorCopy(tex->vecs[axis], temp);
            v = VectorNormalize(temp);

            VectorCopy(temp, plane.normal);
#ifdef HLBSP_SUBDIVIDE_INMID
			int splitpos;
			if ((lightmapmaxs - lightmapmins - 1) - (maxlightmapsize - 1) < (maxlightmapsize - 1) / 4) // don't create very thin face
			{
				splitpos = lightmapmins + (maxlightmapsize - 1) - (maxlightmapsize - 1) / 4;
			}
			else
			{
				splitpos = lightmapmins + (maxlightmapsize - 1);
			}
			plane.dist = ((splitpos + 0.5) * TEXTURE_STEP - tex->vecs[axis][3]) / v;
#else
            plane.dist = (mins + g_subdivide_size - TEXTURE_STEP) / v; //plane.dist = (mins + g_subdivide_size - 16) / v; //--vluzacn
#endif
            next = f->next;
            SplitFace(f, &plane, &front, &back);
            if (!front || !back)
            {
                Developer(DEVELOPER_LEVEL_SPAM, "SubdivideFace: didn't split the %d-sided polygon @(%.0f,%.0f,%.0f)",
                        f->numpoints, f->pts[0][0], f->pts[0][1], f->pts[0][2]);
#ifndef HLBSP_SubdivideFace_FIX
                break;
#endif
            }
#ifdef HLBSP_SubdivideFace_FIX
			f = next;
			if (front)
			{
				front->next = f;
				f = front;
			}
			if (back)
			{
				back->next = f;
				f = back;
			}
			*prevptr = f;
#else
            *prevptr = back;
            back->next = front;
            front->next = next;
            f = back;
#endif
        }
    }
}