00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "cmdlib.h"
00027 #include "mathlib.h"
00028 #include "bspfile.h"
00029 #include "imagelib.h"
00030 #include "threads.h"
00031 #include "mutex.h"
00032 #include "scriplib.h"
00033
00034 #include "shaders.h"
00035 #include "mesh.h"
00036
00037 #ifdef _WIN32
00038
00039 #pragma optimize( "p", on )
00040 #endif
00041
00042 #ifdef _WIN32
00043 #include "../libs/pakstuff.h"
00044 #endif
00045
00046 #define MAX_CLUSTERS 16384
00047 #define MAX_PORTALS 32768
00048 #define MAX_FACETS 65536
00049 #define MAX_LIGHTS 16384
00050
00051 #define LIGHTMAP_SIZE 128
00052
00053 #define LIGHTMAP_PIXELSHIFT 0.5
00054
00055
00056
00057 #define PORTALFILE "PRT1"
00058
00059 #define ON_EPSILON 0.1
00060
00061 #define VectorSet(v, x, y, z) v[0] = x;v[1] = y;v[2] = z;
00062
00063 typedef struct
00064 {
00065 vec3_t normal;
00066 float dist;
00067 } plane_t;
00068
00069 #define MAX_POINTS_ON_WINDING 64
00070
00071 #define MAX_POINTS_ON_FIXED_WINDING 48
00072
00073 typedef struct
00074 {
00075 int numpoints;
00076 vec3_t points[MAX_POINTS_ON_FIXED_WINDING];
00077 } winding_t;
00078
00079 typedef struct
00080 {
00081 plane_t plane;
00082 int leaf;
00083 winding_t *winding;
00084 vec3_t origin;
00085 float radius;
00086 } lportal_t;
00087
00088 #define MAX_PORTALS_ON_LEAF 128
00089 typedef struct lleaf_s
00090 {
00091 int numportals;
00092 lportal_t *portals[MAX_PORTALS_ON_LEAF];
00093
00094 int numSurfaces;
00095 int firstSurface;
00096 } lleaf_t;
00097
00098 typedef struct lFacet_s
00099 {
00100 int num;
00101 plane_t plane;
00102 vec3_t points[4];
00103 int numpoints;
00104 float lightmapCoords[4][2];
00105 plane_t boundaries[4];
00106 float textureMatrix[2][4];
00107 float lightmapMatrix[2][4];
00108 vec3_t mins;
00109 int x, y, width, height;
00110 } lFacet_t;
00111
00112 typedef struct lsurfaceTest_s
00113 {
00114 vec3_t mins, maxs;
00115 vec3_t origin;
00116 float radius;
00117 qboolean patch;
00118 qboolean trisoup;
00119 int numFacets;
00120 lFacet_t *facets;
00121 mesh_t *detailMesh;
00122 shaderInfo_t *shader;
00123 mutex_t *mutex;
00124 int numvolumes;
00125
00126 int always_tracelight;
00127 int always_vsound;
00128 } lsurfaceTest_t;
00129
00130
00131 #define VOLUME_NORMAL 0
00132 #define VOLUME_DIRECTED 1
00133
00134 #define MAX_TRANSLUCENTFACETS 32
00135
00136 typedef struct lightvolume_s
00137 {
00138 int num;
00139 int cluster;
00140 plane_t endplane;
00141 plane_t farplane;
00142 vec3_t points[MAX_POINTS_ON_WINDING];
00143 plane_t planes[MAX_POINTS_ON_WINDING];
00144 int numplanes;
00145 int type;
00146
00147 int transFacets[MAX_TRANSLUCENTFACETS];
00148 int transSurfaces[MAX_TRANSLUCENTFACETS];
00149 int numtransFacets;
00150
00151 byte clusterTested[MAX_CLUSTERS/8];
00152
00153 byte facetTested[MAX_FACETS/8];
00154 int facetNum;
00155 int surfaceNum;
00156 } lightvolume_t;
00157
00158
00159 #define LIGHT_POINTRADIAL 1
00160 #define LIGHT_POINTSPOT 2
00161 #define LIGHT_POINTFAKESURFACE 3
00162 #define LIGHT_SURFACEDIRECTED 4
00163 #define LIGHT_SURFACERADIAL 5
00164 #define LIGHT_SURFACESPOT 6
00165
00166
00167 #define LDAT_QUADRATIC 0
00168 #define LDAT_LINEAR 1
00169 #define LDAT_NOSCALE 2
00170
00171
00172 #define LAAT_NORMAL 0
00173 #define LAAT_QUADRATIC 1
00174 #define LAAT_DOUBLEQUADRATIC 2
00175
00176 typedef struct vsound_s
00177 {
00178 vec3_t origin;
00179 winding_t w;
00180 vec4_t plane;
00181 vec3_t normal;
00182 int type;
00183 vec3_t color;
00184 qboolean twosided;
00185 int style;
00186 int atten_disttype;
00187 int atten_angletype;
00188 float atten_distscale;
00189 float atten_anglescale;
00190 float radiusByDist;
00191 float photons;
00192 float intensity;
00193 vec3_t emitColor;
00194 struct shaderInfo_s *si;
00195 int insolid;
00196 } vsound_t;
00197
00198 static float lightLinearScale = 1.0 / 8000;
00199 static float lightPointScale = 7500;
00200 static float lightAreaScale = 0.25;
00201 static float lightFormFactorValueScale = 3;
00202 static int lightDefaultSubdivide = 999;
00203 static vec3_t lightAmbientColor;
00204
00205 static int portalclusters, numportals, numfaces;
00206 static lleaf_t *leafs;
00207 static lportal_t *portals;
00208 static int numvsounds = 0;
00209 static vsound_t *vsounds[MAX_LIGHTS];
00210 static int nostitching = 0;
00211 static int noalphashading = 0;
00212 static int nocolorshading = 0;
00213 static int nobackfaceculling = 0;
00214 static int defaulttracelight = 0;
00215 static int radiosity = 0;
00216 static int radiosity_scale;
00217
00218 static int clustersurfaces[MAX_MAP_LEAFFACES];
00219 static int numclustersurfaces = 0;
00220 static lsurfaceTest_t *lsurfaceTest[MAX_MAP_DRAW_SURFS];
00221 static int numfacets;
00222 static float lightmappixelarea[MAX_MAP_LIGHTING/3];
00223 static float *lightFloats;
00224
00225
00226 winding_t *AllocWinding (int points);
00227 void FreeWinding (winding_t *w);
00228 void WindingCenter (winding_t *w, vec3_t center);
00229 void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs);
00230 vec_t WindingArea (winding_t *w);
00231 winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist);
00232 void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
00233 vec_t epsilon, winding_t **front, winding_t **back);
00234 winding_t *ReverseWinding (winding_t *w);
00235
00236
00237 extern char source[1024];
00238 extern vec3_t surfaceOrigin[ MAX_MAP_DRAW_SURFS ];
00239 extern int entitySurface[ MAX_MAP_DRAW_SURFS ];
00240 extern int samplesize;
00241 extern qboolean patchshadows;
00242 extern vec3_t gridSize;
00243
00244 float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w );
00245 void ColorToBytes( const float *color, byte *colorBytes );
00246 void CountLightmaps( void );
00247 void GridAndVertexLighting( void );
00248 void SetEntityOrigins( void );
00249
00250
00251
00252
00253 #ifdef DEBUGNET
00254
00255 #include "l_net.h"
00256
00257 socket_t *debug_socket;
00258
00259
00260
00261
00262
00263
00264 void DebugNet_Setup(void)
00265 {
00266 address_t address;
00267 int i;
00268
00269 Net_Setup();
00270 Net_StringToAddress("127.0.0.1:28000", &address);
00271 for (i = 0; i < 10; i++)
00272 {
00273 debug_socket = Net_Connect(&address, 28005 + i);
00274 if (debug_socket)
00275 break;
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284 void DebugNet_Shutdown(void)
00285 {
00286 netmessage_t msg;
00287
00288 if (debug_socket)
00289 {
00290 NMSG_Clear(&msg);
00291 NMSG_WriteByte(&msg, 1);
00292 Net_Send(debug_socket, &msg);
00293 Net_Disconnect(debug_socket);
00294 }
00295 debug_socket = NULL;
00296 Net_Shutdown();
00297 }
00298
00299
00300
00301
00302
00303
00304 void DebugNet_RemoveAllPolys(void)
00305 {
00306 netmessage_t msg;
00307
00308 if (!debug_socket)
00309 return;
00310 NMSG_Clear(&msg);
00311 NMSG_WriteByte(&msg, 2);
00312 Net_Send(debug_socket, &msg);
00313 }
00314
00315
00316
00317
00318
00319
00320 void DebugNet_DrawWinding(winding_t *w, int color)
00321 {
00322 netmessage_t msg;
00323 int i;
00324
00325 if (!debug_socket)
00326 return;
00327 NMSG_Clear(&msg);
00328 NMSG_WriteByte(&msg, 0);
00329 NMSG_WriteByte(&msg, w->numpoints);
00330 NMSG_WriteLong(&msg, color);
00331 for (i = 0; i < w->numpoints; i++)
00332 {
00333 NMSG_WriteFloat(&msg, w->points[i][0]);
00334 NMSG_WriteFloat(&msg, w->points[i][1]);
00335 NMSG_WriteFloat(&msg, w->points[i][2]);
00336 }
00337 Net_Send(debug_socket, &msg);
00338 }
00339
00340
00341
00342
00343
00344
00345 void DebugNet_DrawLine(vec3_t p1, vec3_t p2, int color)
00346 {
00347 netmessage_t msg;
00348
00349 if (!debug_socket)
00350 return;
00351 NMSG_Clear(&msg);
00352 NMSG_WriteByte(&msg, 1);
00353 NMSG_WriteLong(&msg, color);
00354 NMSG_WriteFloat(&msg, p1[0]);
00355 NMSG_WriteFloat(&msg, p1[1]);
00356 NMSG_WriteFloat(&msg, p1[2]);
00357 NMSG_WriteFloat(&msg, p2[0]);
00358 NMSG_WriteFloat(&msg, p2[1]);
00359 NMSG_WriteFloat(&msg, p2[2]);
00360 Net_Send(debug_socket, &msg);
00361 }
00362
00363
00364
00365
00366
00367
00368 void DebugNet_DrawMesh(mesh_t *mesh)
00369 {
00370 int i, j;
00371 float dot;
00372 drawVert_t *v1, *v2, *v3, *v4;
00373 winding_t winding;
00374 plane_t plane;
00375 vec3_t d1, d2;
00376
00377 for ( i = 0 ; i < mesh->width - 1 ; i++ ) {
00378 for ( j = 0 ; j < mesh->height - 1 ; j++ ) {
00379
00380 v1 = mesh->verts + j * mesh->width + i;
00381 v2 = v1 + 1;
00382 v3 = v1 + mesh->width + 1;
00383 v4 = v1 + mesh->width;
00384
00385 VectorSubtract( v4->xyz, v1->xyz, d1 );
00386 VectorSubtract( v3->xyz, v1->xyz, d2 );
00387 CrossProduct( d2, d1, plane.normal );
00388 if ( VectorNormalize( plane.normal, plane.normal ) != 0 )
00389 {
00390 plane.dist = DotProduct( v1->xyz, plane.normal );
00391 dot = DotProduct(plane.normal, v2->xyz) - plane.dist;
00392 if (fabs(dot) < 0.1)
00393 {
00394 VectorCopy(v1->xyz, winding.points[0]);
00395 VectorCopy(v4->xyz, winding.points[1]);
00396 VectorCopy(v3->xyz, winding.points[2]);
00397 VectorCopy(v2->xyz, winding.points[3]);
00398 winding.numpoints = 4;
00399 DebugNet_DrawWinding(&winding, 2);
00400 continue;
00401 }
00402 }
00403
00404 winding.numpoints = 3;
00405 VectorCopy(v1->xyz, winding.points[0]);
00406 VectorCopy(v4->xyz, winding.points[1]);
00407 VectorCopy(v3->xyz, winding.points[2]);
00408 DebugNet_DrawWinding(&winding, 2);
00409
00410 VectorCopy(v1->xyz, winding.points[0]);
00411 VectorCopy(v3->xyz, winding.points[1]);
00412 VectorCopy(v2->xyz, winding.points[2]);
00413 DebugNet_DrawWinding(&winding, 2);
00414 }
00415 }
00416 }
00417
00418
00419
00420
00421
00422
00423 int VS_ChopWinding (winding_t *in, plane_t *split, float epsilon);
00424
00425 void VS_DrawLightVolume(vsound_t *light, lightvolume_t *volume)
00426 {
00427 winding_t w;
00428 int i;
00429 vec3_t p2, invsound;
00430
00431 memcpy(w.points, volume->points, volume->numplanes * sizeof(vec3_t));
00432 w.numpoints = volume->numplanes;
00433 DebugNet_DrawWinding(&w, 2);
00434
00435 if (volume->type == VOLUME_DIRECTED)
00436 {
00437 VectorCopy(light->normal, invsound);
00438 VectorInverse(invsound);
00439 for (i = 0; i < volume->numplanes; i++)
00440 {
00441 VectorCopy(volume->points[i], w.points[0]);
00442 VectorCopy(volume->points[(i+1) % volume->numplanes], w.points[1]);
00443 VectorMA(w.points[1], MAX_WORLD_COORD, invsound, w.points[2]);
00444 VectorMA(w.points[0], MAX_WORLD_COORD, invsound, w.points[3]);
00445 w.numpoints = 4;
00446 DebugNet_DrawWinding(&w, 2);
00447 VectorMA(volume->points[i], 8, volume->planes[i].normal, p2);
00448 DebugNet_DrawLine(volume->points[i], p2, 3);
00449 }
00450 }
00451 else
00452 {
00453
00454 VectorCopy(light->origin, w.points[0]);
00455 w.numpoints = 3;
00456 for (i = 0; i < volume->numplanes; i++)
00457 {
00458 VectorCopy(volume->points[i], w.points[1]);
00459 VectorCopy(volume->points[(i+1) % volume->numplanes], w.points[2]);
00460 VS_ChopWinding(&w, &volume->endplane, 0);
00461 DebugNet_DrawWinding(&w, 2);
00462 VectorMA(volume->points[i], 8, volume->planes[i].normal, p2);
00463 DebugNet_DrawLine(volume->points[i], p2, 3);
00464 }
00465 }
00466 }
00467
00468
00469
00470
00471
00472
00473 void VS_DrawLightmapPixel(int surfaceNum, int x, int y, int color)
00474 {
00475 winding_t w;
00476 dsurface_t *ds;
00477 mesh_t *mesh;
00478
00479 ds = &drawSurfaces[surfaceNum];
00480
00481 if (ds->surfaceType == MST_PATCH)
00482 {
00483 mesh = lsurfaceTest[surfaceNum]->detailMesh;
00484 VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[0]);
00485 VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[1]);
00486 VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[2]);
00487 VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[3]);
00488 w.numpoints = 4;
00489 }
00490 else
00491 {
00492 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[0]);
00493 VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[0]);
00494 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[1]);
00495 VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[1]);
00496 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[2]);
00497 VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[2]);
00498 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[3]);
00499 VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[3]);
00500 w.numpoints = 4;
00501 }
00502 DebugNet_DrawWinding(&w, color);
00503 }
00504
00505
00506
00507
00508
00509
00510 void VS_DrawPortals(void)
00511 {
00512 int j;
00513 lportal_t *p;
00514
00515 for (j = 0; j < numportals * 2; j++)
00516 {
00517 p = portals + j;
00518 DebugNet_DrawWinding(p->winding, 1);
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527 void VS_DrawLeaf(int cluster)
00528 {
00529 int i;
00530 lleaf_t *leaf;
00531 lportal_t *p;
00532
00533 leaf = &leafs[cluster];
00534 for (i = 0; i < leaf->numportals; i++)
00535 {
00536 p = leaf->portals[i];
00537 DebugNet_DrawWinding(p->winding, 1);
00538 }
00539 }
00540
00541 #endif //DEBUGNET
00542
00543
00544
00545
00546
00547
00548 int VS_SplitWinding (winding_t *in, winding_t *back, plane_t *split, float epsilon)
00549 {
00550 vec_t dists[128];
00551 int sides[128];
00552 int counts[3];
00553 vec_t dot;
00554 int i, j;
00555 vec_t *p1, *p2;
00556 vec3_t mid;
00557 winding_t out;
00558 winding_t *neww;
00559
00560 counts[0] = counts[1] = counts[2] = 0;
00561
00562
00563 for (i=0 ; i<in->numpoints ; i++)
00564 {
00565 dot = DotProduct (in->points[i], split->normal);
00566 dot -= split->dist;
00567 dists[i] = dot;
00568 if (dot > epsilon)
00569 sides[i] = SIDE_FRONT;
00570 else if (dot < -epsilon)
00571 sides[i] = SIDE_BACK;
00572 else
00573 {
00574 sides[i] = SIDE_ON;
00575 }
00576 counts[sides[i]]++;
00577 }
00578
00579 if (!counts[SIDE_BACK])
00580 {
00581 if (!counts[SIDE_FRONT])
00582 return SIDE_ON;
00583 else
00584 return SIDE_FRONT;
00585 }
00586
00587 if (!counts[SIDE_FRONT])
00588 {
00589 return SIDE_BACK;
00590 }
00591
00592 sides[i] = sides[0];
00593 dists[i] = dists[0];
00594
00595 neww = &out;
00596
00597 neww->numpoints = 0;
00598 back->numpoints = 0;
00599
00600 for (i=0 ; i<in->numpoints ; i++)
00601 {
00602 p1 = in->points[i];
00603
00604 if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00605 {
00606 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00607 return SIDE_FRONT;
00608 }
00609 if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00610 {
00611 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00612 return SIDE_FRONT;
00613 }
00614
00615 if (sides[i] == SIDE_ON)
00616 {
00617 VectorCopy (p1, neww->points[neww->numpoints]);
00618 neww->numpoints++;
00619 VectorCopy (p1, back->points[back->numpoints]);
00620 back->numpoints++;
00621 continue;
00622 }
00623
00624 if (sides[i] == SIDE_FRONT)
00625 {
00626 VectorCopy (p1, neww->points[neww->numpoints]);
00627 neww->numpoints++;
00628 }
00629 if (sides[i] == SIDE_BACK)
00630 {
00631 VectorCopy (p1, back->points[back->numpoints]);
00632 back->numpoints++;
00633 }
00634
00635 if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
00636 continue;
00637
00638 if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00639 {
00640 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00641 return SIDE_FRONT;
00642 }
00643
00644 if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00645 {
00646 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00647 return SIDE_FRONT;
00648 }
00649
00650
00651 p2 = in->points[(i+1)%in->numpoints];
00652
00653 dot = dists[i] / (dists[i]-dists[i+1]);
00654 for (j=0 ; j<3 ; j++)
00655 {
00656 if (split->normal[j] == 1)
00657 mid[j] = split->dist;
00658 else if (split->normal[j] == -1)
00659 mid[j] = -split->dist;
00660 else
00661 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
00662 }
00663
00664 VectorCopy (mid, neww->points[neww->numpoints]);
00665 neww->numpoints++;
00666 VectorCopy (mid, back->points[back->numpoints]);
00667 back->numpoints++;
00668 }
00669 memcpy(in, &out, sizeof(winding_t));
00670
00671 return SIDE_CROSS;
00672 }
00673
00674
00675
00676
00677
00678
00679 void VS_LinkSurfaceIntoCluster(int cluster, int surfaceNum)
00680 {
00681 lleaf_t *leaf;
00682 int i;
00683
00684 leaf = &leafs[cluster];
00685
00686 for (i = 0; i < leaf->numSurfaces; i++)
00687 {
00688 if (clustersurfaces[leaf->firstSurface + i] == surfaceNum)
00689 return;
00690 }
00691 for (i = numclustersurfaces; i > leaf->firstSurface + leaf->numSurfaces; i--)
00692 clustersurfaces[i] = clustersurfaces[i-1];
00693 for (i = 0; i < portalclusters; i++)
00694 {
00695 if (i == cluster)
00696 continue;
00697 if (leafs[i].firstSurface >= leaf->firstSurface + leaf->numSurfaces)
00698 leafs[i].firstSurface++;
00699 }
00700 clustersurfaces[leaf->firstSurface + leaf->numSurfaces] = surfaceNum;
00701 leaf->numSurfaces++;
00702 numclustersurfaces++;
00703 if (numclustersurfaces >= MAX_MAP_LEAFFACES)
00704 Error("MAX_MAP_LEAFFACES");
00705 }
00706
00707
00708
00709
00710
00711
00712 void VS_R_LinkSurface(int nodenum, int surfaceNum, winding_t *w)
00713 {
00714 int leafnum, cluster, res;
00715 dnode_t *node;
00716 dplane_t *plane;
00717 winding_t back;
00718 plane_t split;
00719
00720 while(nodenum >= 0)
00721 {
00722 node = &dnodes[nodenum];
00723 plane = &dplanes[node->planeNum];
00724
00725 VectorCopy(plane->normal, split.normal);
00726 split.dist = plane->dist;
00727 res = VS_SplitWinding (w, &back, &split, 0.1);
00728
00729 if (res == SIDE_FRONT)
00730 {
00731 nodenum = node->children[0];
00732 }
00733 else if (res == SIDE_BACK)
00734 {
00735 nodenum = node->children[1];
00736 }
00737 else if (res == SIDE_ON)
00738 {
00739 memcpy(&back, w, sizeof(winding_t));
00740 VS_R_LinkSurface(node->children[1], surfaceNum, &back);
00741 nodenum = node->children[0];
00742 }
00743 else
00744 {
00745 VS_R_LinkSurface(node->children[1], surfaceNum, &back);
00746 nodenum = node->children[0];
00747 }
00748 }
00749 leafnum = -nodenum - 1;
00750 cluster = dleafs[leafnum].cluster;
00751 if (cluster != -1)
00752 {
00753 VS_LinkSurfaceIntoCluster(cluster, surfaceNum);
00754 }
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764 void VS_LinkSurfaces(void)
00765 {
00766 int i, j;
00767 lsurfaceTest_t *test;
00768 lFacet_t *facet;
00769 winding_t winding;
00770
00771 for ( i = 0 ; i < numDrawSurfaces ; i++ )
00772 {
00773 test = lsurfaceTest[ i ];
00774 if (!test)
00775 continue;
00776 for (j = 0; j < test->numFacets; j++)
00777 {
00778 facet = &test->facets[j];
00779 memcpy(winding.points, facet->points, facet->numpoints * sizeof(vec3_t));
00780 winding.numpoints = facet->numpoints;
00781 VS_R_LinkSurface(0, i, &winding);
00782 }
00783 }
00784 }
00785
00786
00787
00788
00789
00790
00791 void VS_TextureMatrixFromPoints( lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
00792 int i, j;
00793 float t;
00794 float m[3][4];
00795 float s;
00796
00797
00798 for ( i = 0 ; i < 2 ; i++ ) {
00799
00800 m[0][0] = a->xyz[0];
00801 m[0][1] = a->xyz[1];
00802 m[0][2] = a->xyz[2];
00803 m[0][3] = a->st[i];
00804
00805 m[1][0] = b->xyz[0];
00806 m[1][1] = b->xyz[1];
00807 m[1][2] = b->xyz[2];
00808 m[1][3] = b->st[i];
00809
00810 m[2][0] = c->xyz[0];
00811 m[2][1] = c->xyz[1];
00812 m[2][2] = c->xyz[2];
00813 m[2][3] = c->st[i];
00814
00815 if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) > fabs(m[2][0]) ) {
00816 for ( j = 0 ; j < 4 ; j ++ ) {
00817 t = m[0][j];
00818 m[0][j] = m[1][j];
00819 m[1][j] = t;
00820 }
00821 } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) > fabs(m[1][0]) ) {
00822 for ( j = 0 ; j < 4 ; j ++ ) {
00823 t = m[0][j];
00824 m[0][j] = m[2][j];
00825 m[2][j] = t;
00826 }
00827 }
00828
00829 s = 1.0 / m[0][0];
00830 m[0][0] *= s;
00831 m[0][1] *= s;
00832 m[0][2] *= s;
00833 m[0][3] *= s;
00834
00835 s = m[1][0];
00836 m[1][0] -= m[0][0] * s;
00837 m[1][1] -= m[0][1] * s;
00838 m[1][2] -= m[0][2] * s;
00839 m[1][3] -= m[0][3] * s;
00840
00841 s = m[2][0];
00842 m[2][0] -= m[0][0] * s;
00843 m[2][1] -= m[0][1] * s;
00844 m[2][2] -= m[0][2] * s;
00845 m[2][3] -= m[0][3] * s;
00846
00847 if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
00848 for ( j = 0 ; j < 4 ; j ++ ) {
00849 t = m[1][j];
00850 m[1][j] = m[2][j];
00851 m[2][j] = t;
00852 }
00853 }
00854
00855 s = 1.0 / m[1][1];
00856 m[1][0] *= s;
00857 m[1][1] *= s;
00858 m[1][2] *= s;
00859 m[1][3] *= s;
00860
00861 s = m[2][1];
00862 m[2][0] -= m[1][0] * s;
00863 m[2][1] -= m[1][1] * s;
00864 m[2][2] -= m[1][2] * s;
00865 m[2][3] -= m[1][3] * s;
00866
00867 s = 1.0 / m[2][2];
00868 m[2][0] *= s;
00869 m[2][1] *= s;
00870 m[2][2] *= s;
00871 m[2][3] *= s;
00872
00873 f->textureMatrix[i][2] = m[2][3];
00874 f->textureMatrix[i][1] = m[1][3] - f->textureMatrix[i][2] * m[1][2];
00875 f->textureMatrix[i][0] = m[0][3] - f->textureMatrix[i][2] * m[0][2] - f->textureMatrix[i][1] * m[0][1];
00876
00877 f->textureMatrix[i][3] = 0;
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892 }
00893 }
00894
00895
00896
00897
00898
00899
00900 void VS_LightmapMatrixFromPoints( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
00901 int i, j;
00902 float t;
00903 float m[3][4], al, bl, cl;
00904 float s;
00905 int h, w, ssize;
00906 vec3_t mins, maxs, delta, size, planeNormal;
00907 drawVert_t *verts;
00908 static int message;
00909
00910
00911 if ( dsurf->surfaceType == MST_TRIANGLE_SOUP ) {
00912 return;
00913 }
00914
00915 if ( dsurf->lightmapNum < 0 ) {
00916 return;
00917 }
00918
00919 VectorClear(f->mins);
00920 if (dsurf->surfaceType != MST_PATCH)
00921 {
00922 ssize = samplesize;
00923 if (si->lightmapSampleSize)
00924 ssize = si->lightmapSampleSize;
00925 ClearBounds( mins, maxs );
00926 verts = &drawVerts[dsurf->firstVert];
00927 for ( i = 0 ; i < dsurf->numVerts ; i++ ) {
00928 AddPointToBounds( verts[i].xyz, mins, maxs );
00929 }
00930
00931 for ( i = 0 ; i < 3 ; i++ ) {
00932 mins[i] = ssize * floor( mins[i] / ssize );
00933 maxs[i] = ssize * ceil( maxs[i] / ssize );
00934 f->mins[i] = mins[i];
00935 size[i] = (maxs[i] - mins[i]) / ssize + 1;
00936 }
00937
00938 VectorClear(f->lightmapMatrix[0]);
00939 f->lightmapMatrix[0][3] = 0;
00940 VectorClear(f->lightmapMatrix[1]);
00941 f->lightmapMatrix[1][3] = 0;
00942
00943 planeNormal[0] = fabs( dsurf->lightmapVecs[2][0] );
00944 planeNormal[1] = fabs( dsurf->lightmapVecs[2][1] );
00945 planeNormal[2] = fabs( dsurf->lightmapVecs[2][2] );
00946
00947 if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
00948 w = size[1];
00949 h = size[2];
00950 f->lightmapMatrix[0][1] = 1.0 / ssize;
00951 f->lightmapMatrix[1][2] = 1.0 / ssize;
00952 } else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
00953 w = size[0];
00954 h = size[2];
00955 f->lightmapMatrix[0][0] = 1.0 / ssize;
00956 f->lightmapMatrix[1][2] = 1.0 / ssize;
00957 } else {
00958 w = size[0];
00959 h = size[1];
00960 f->lightmapMatrix[0][0] = 1.0 / ssize;
00961 f->lightmapMatrix[1][1] = 1.0 / ssize;
00962 }
00963 if ( w > LIGHTMAP_WIDTH ) {
00964 VectorScale ( f->lightmapMatrix[0], (float)LIGHTMAP_SIZE/w, f->lightmapMatrix[0] );
00965 }
00966
00967 if ( h > LIGHTMAP_HEIGHT ) {
00968 VectorScale ( f->lightmapMatrix[1], (float)LIGHTMAP_SIZE/h, f->lightmapMatrix[1] );
00969 }
00970 VectorSubtract(a->xyz, f->mins, delta);
00971 s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
00972 if ( fabs(s - a->lightmap[0]) > 0.01 ) {
00973 _printf( "Bad lightmapMatrix" );
00974 }
00975 t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
00976 if ( fabs(t - a->lightmap[1]) > 0.01 ) {
00977 _printf( "Bad lightmapMatrix" );
00978 }
00979 VectorSubtract(b->xyz, f->mins, delta);
00980 s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
00981 if ( fabs(s - b->lightmap[0]) > 0.01 ) {
00982 _printf( "Bad lightmapMatrix" );
00983 }
00984 t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
00985 if ( fabs(t - b->lightmap[1]) > 0.01 ) {
00986 _printf( "Bad lightmapMatrix" );
00987 }
00988 VectorSubtract(c->xyz, f->mins, delta);
00989 s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
00990 if ( fabs(s - c->lightmap[0]) > 0.01 ) {
00991 _printf( "Bad lightmapMatrix" );
00992 }
00993 t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
00994 if ( fabs(t - c->lightmap[1]) > 0.01 ) {
00995 _printf( "Bad lightmapMatrix" );
00996 }
00997 VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
00998 return;
00999 }
01000
01001 for ( i = 0 ; i < 2 ; i++ ) {
01002
01003 if (i)
01004 al = a->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
01005 else
01006 al = a->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
01007
01008 m[0][0] = a->xyz[0] - f->mins[0];
01009 m[0][1] = a->xyz[1] - f->mins[1];
01010 m[0][2] = a->xyz[2] - f->mins[2];
01011 m[0][3] = al;
01012
01013 if (i)
01014 bl = b->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
01015 else
01016 bl = b->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
01017
01018 m[1][0] = b->xyz[0] - f->mins[0];
01019 m[1][1] = b->xyz[1] - f->mins[1];
01020 m[1][2] = b->xyz[2] - f->mins[2];
01021 m[1][3] = bl;
01022
01023 if (i)
01024 cl = c->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
01025 else
01026 cl = c->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
01027
01028 m[2][0] = c->xyz[0] - f->mins[0];
01029 m[2][1] = c->xyz[1] - f->mins[1];
01030 m[2][2] = c->xyz[2] - f->mins[2];
01031 m[2][3] = cl;
01032
01033 if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) >= fabs(m[2][0]) ) {
01034 for ( j = 0 ; j < 4 ; j ++ ) {
01035 t = m[0][j];
01036 m[0][j] = m[1][j];
01037 m[1][j] = t;
01038 }
01039 } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) >= fabs(m[1][0]) ) {
01040 for ( j = 0 ; j < 4 ; j ++ ) {
01041 t = m[0][j];
01042 m[0][j] = m[2][j];
01043 m[2][j] = t;
01044 }
01045 }
01046
01047 if (m[0][0])
01048 {
01049 s = 1.0 / m[0][0];
01050 m[0][0] *= s;
01051 m[0][1] *= s;
01052 m[0][2] *= s;
01053 m[0][3] *= s;
01054
01055 s = m[1][0];
01056 m[1][0] -= m[0][0] * s;
01057 m[1][1] -= m[0][1] * s;
01058 m[1][2] -= m[0][2] * s;
01059 m[1][3] -= m[0][3] * s;
01060
01061 s = m[2][0];
01062 m[2][0] -= m[0][0] * s;
01063 m[2][1] -= m[0][1] * s;
01064 m[2][2] -= m[0][2] * s;
01065 m[2][3] -= m[0][3] * s;
01066 }
01067
01068 if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
01069 for ( j = 0 ; j < 4 ; j ++ ) {
01070 t = m[1][j];
01071 m[1][j] = m[2][j];
01072 m[2][j] = t;
01073 }
01074 }
01075
01076 if (m[1][1])
01077 {
01078 s = 1.0 / m[1][1];
01079 m[1][0] *= s;
01080 m[1][1] *= s;
01081 m[1][2] *= s;
01082 m[1][3] *= s;
01083
01084 s = m[2][1];
01085 m[2][0] -= m[1][0] * s;
01086 m[2][1] -= m[1][1] * s;
01087 m[2][2] -= m[1][2] * s;
01088 m[2][3] -= m[1][3] * s;
01089 }
01090
01091 if (m[2][2])
01092 {
01093 s = 1.0 / m[2][2];
01094 m[2][0] *= s;
01095 m[2][1] *= s;
01096 m[2][2] *= s;
01097 m[2][3] *= s;
01098 }
01099
01100 f->lightmapMatrix[i][2] = m[2][3];
01101 f->lightmapMatrix[i][1] = m[1][3] - f->lightmapMatrix[i][2] * m[1][2];
01102 f->lightmapMatrix[i][0] = m[0][3] - f->lightmapMatrix[i][2] * m[0][2] - f->lightmapMatrix[i][1] * m[0][1];
01103
01104 f->lightmapMatrix[i][3] = 0;
01105
01106 VectorSubtract(a->xyz, f->mins, delta);
01107 s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - al );
01108 if ( s > 0.01 ) {
01109 if (!message)
01110 _printf( "Bad lightmapMatrix\n" );
01111 message = qtrue;
01112 }
01113 VectorSubtract(b->xyz, f->mins, delta);
01114 s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - bl );
01115 if ( s > 0.01 ) {
01116 if (!message)
01117 _printf( "Bad lightmapMatrix\n" );
01118 message = qtrue;
01119 }
01120 VectorSubtract(c->xyz, f->mins, delta);
01121 s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - cl );
01122 if ( s > 0.01 ) {
01123 if (!message)
01124 _printf( "Bad lightmapMatrix\n" );
01125 message = qtrue;
01126 }
01127 VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
01128 }
01129 }
01130
01131
01132
01133
01134
01135
01136 #define NORMAL_EPSILON 0.0001
01137 #define DIST_EPSILON 0.02
01138
01139 static int Plane_Equal(plane_t *a, plane_t *b, int flip)
01140 {
01141 vec3_t normal;
01142 float dist;
01143
01144 if (flip) {
01145 normal[0] = -