/* ============== TestPatchToFace Sets vis bits for all patches in the face ============== */ void TestPatchToFace (unsigned patchnum, int facenum, int head, unsigned bitpos) { patch_t *patch = &patches[patchnum]; patch_t *patch2 = face_patches[facenum]; // if emitter is behind that face plane, skip all patches if ( patch2 && DotProduct(patch->origin, patch2->normal) > PatchPlaneDist(patch2)+1.01 ) { // we need to do a real test for ( ; patch2 ; patch2 = patch2->next) { unsigned m = patch2 - patches; // check vis between patch and patch2 // if bit has not already been set // && v2 is not behind light plane // && v2 is visible from v1 if ( m > patchnum && DotProduct (patch2->origin, patch->normal) > PatchPlaneDist(patch)+1.01 && TestLine_r (head, patch->origin, patch2->origin) == CONTENTS_EMPTY ) { // patchnum can see patch m int bitset = bitpos+m; vismatrix[ bitset>>3 ] |= 1 << (bitset&7); } } }
void MakeScales (int threadnum) { int i; unsigned j; vec3_t delta; vec_t dist, scale; int count; float trans; patch_t *patch, *patch2; float total, send; dplane_t plane; vec3_t origin; vec_t area; transfer_t transfers[MAX_PATCHES], *all_transfers; count = 0; while (1) { i = GetThreadWork (); if (i == -1) break; patch = patches + i; total = 0; patch->numtransfers = 0; VectorCopy (patch->origin, origin); plane = *patch->plane; plane.dist = PatchPlaneDist( patch ); area = patch->area; // find out which patch2's will collect light // from patch all_transfers = transfers; for (j=0, patch2 = patches ; j<num_patches ; j++, patch2++) { if (!CheckVisBit (i, j)) continue; // calculate transferemnce VectorSubtract (patch2->origin, origin, delta); dist = VectorNormalize (delta); // skys don't care about the interface angle, but everything // else does if (!patch->sky) scale = DotProduct (delta, patch->normal); else scale = 1; scale *= -DotProduct (delta, patch2->normal); trans = scale / (dist*dist); if (trans < -ON_EPSILON) Error ("transfer < 0"); send = trans*patch2->area; if (send > 0.4f) { trans = 0.4f / patch2->area; send = 0.4f; } total += send; // scale to 16 bit trans = trans * area * INVERSE_TRANSFER_SCALE; if (trans >= 0x10000) trans = 0xffff; if (!trans) continue; all_transfers->transfer = (unsigned short)trans; all_transfers->patch = j; all_transfers++; patch->numtransfers++; count++; } // copy the transfers out if (patch->numtransfers) { transfer_t *t, *t2; patch->transfers = calloc (patch->numtransfers, sizeof(transfer_t)); if (!patch->transfers) Error ("Memory allocation failure"); // // normalize all transfers so exactly 50% of the light // is transfered to the surroundings // total = 0.5f/total; t = patch->transfers; t2 = transfers; for (j=0 ; j<(unsigned)patch->numtransfers ; j++, t++, t2++) { t->transfer = (unsigned short)(t2->transfer*total); t->patch = t2->patch; } } } ThreadLock (); total_transfer += count; ThreadUnlock (); }