static void ConvertBrush(FILE * f, int num, bspBrush_t * brush, vec3_t origin) { int i, j; bspBrushSide_t *side; side_t *buildSide; bspShader_t *shader; char *texture; bspPlane_t *plane; plane_t *buildPlane; vec3_t pts[3]; bspDrawVert_t *vert[3]; int valid; /* start brush */ fprintf(f, "\t// brush %d\n", num); fprintf(f, "\t{\n"); fprintf(f, "\tbrushDef\n"); fprintf(f, "\t{\n"); /* clear out build brush */ for(i = 0; i < buildBrush->numsides; i++) { buildSide = &buildBrush->sides[i]; if(buildSide->winding != NULL) { FreeWinding(buildSide->winding); buildSide->winding = NULL; } } buildBrush->numsides = 0; /* iterate through bsp brush sides */ for(i = 0; i < brush->numSides; i++) { /* get side */ side = &bspBrushSides[brush->firstSide + i]; /* get shader */ if(side->shaderNum < 0 || side->shaderNum >= numBSPShaders) continue; shader = &bspShaders[side->shaderNum]; if(!Q_stricmp(shader->shader, "default") || !Q_stricmp(shader->shader, "noshader")) continue; /* get plane */ plane = &bspPlanes[side->planeNum]; /* add build side */ buildSide = &buildBrush->sides[buildBrush->numsides]; buildBrush->numsides++; /* tag it */ buildSide->shaderInfo = ShaderInfoForShader(shader->shader); buildSide->planenum = side->planeNum; buildSide->winding = NULL; } /* make brush windings */ if(!CreateBrushWindings(buildBrush)) return; /* iterate through build brush sides */ for(i = 0; i < buildBrush->numsides; i++) { /* get build side */ buildSide = &buildBrush->sides[i]; /* get plane */ buildPlane = &mapplanes[buildSide->planenum]; /* dummy check */ if(buildSide->shaderInfo == NULL || buildSide->winding == NULL) continue; // st-texcoords -> texMat block // start out with dummy VectorSet(buildSide->texMat[0], 1 / 32.0, 0, 0); VectorSet(buildSide->texMat[1], 0, 1 / 32.0, 0); // find surface for this side (by brute force) // surface format: // - meshverts point in pairs of three into verts // - (triangles) // - find the triangle that has most in common with our side GetBestSurfaceTriangleMatchForBrushside(buildSide, vert); valid = 0; if(vert[0] && vert[1] && vert[2]) { int i; vec3_t texX, texY; vec3_t xy1I, xy1J, xy1K; vec2_t stI, stJ, stK; vec_t D, D0, D1, D2; ComputeAxisBase(buildPlane->normal, texX, texY); VectorSet(xy1I, DotProduct(vert[0]->xyz, texX), DotProduct(vert[0]->xyz, texY), 1); VectorSet(xy1J, DotProduct(vert[1]->xyz, texX), DotProduct(vert[1]->xyz, texY), 1); VectorSet(xy1K, DotProduct(vert[2]->xyz, texX), DotProduct(vert[2]->xyz, texY), 1); stI[0] = vert[0]->st[0]; stI[1] = vert[0]->st[1]; stJ[0] = vert[1]->st[0]; stJ[1] = vert[1]->st[1]; stK[0] = vert[2]->st[0]; stK[1] = vert[2]->st[1]; // - solve linear equations: // - (x, y) := xyz . (texX, texY) // - st[i] = texMat[i][0]*x + texMat[i][1]*y + texMat[i][2] // (for three vertices) D = Det3x3(xy1I[0], xy1I[1], 1, xy1J[0], xy1J[1], 1, xy1K[0], xy1K[1], 1); if(D != 0) { for(i = 0; i < 2; ++i) { D0 = Det3x3(stI[i], xy1I[1], 1, stJ[i], xy1J[1], 1, stK[i], xy1K[1], 1); D1 = Det3x3(xy1I[0], stI[i], 1, xy1J[0], stJ[i], 1, xy1K[0], stK[i], 1); D2 = Det3x3(xy1I[0], xy1I[1], stI[i], xy1J[0], xy1J[1], stJ[i], xy1K[0], xy1K[1], stK[i]); VectorSet(buildSide->texMat[i], D0 / D, D1 / D, D2 / D); valid = 1; } } else fprintf(stderr, "degenerate triangle found when solving texMat equations for\n(%f %f %f) (%f %f %f) (%f %f %f)\n( %f %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n", buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], vert[0]->normal[0], vert[0]->normal[1], vert[0]->normal[2], texX[0], texX[1], texX[2], texY[0], texY[1], texY[2], vert[0]->xyz[0], vert[0]->xyz[1], vert[0]->xyz[2], xy1I[0], xy1I[1], vert[1]->xyz[0], vert[1]->xyz[1], vert[1]->xyz[2], xy1J[0], xy1J[1], vert[2]->xyz[0], vert[2]->xyz[1], vert[2]->xyz[2], xy1K[0], xy1K[1]); } else if(strncmp(buildSide->shaderInfo->shader, "textures/common/", 16)) fprintf(stderr, "no matching triangle for brushside using %s (hopefully nobody can see this side anyway)\n", buildSide->shaderInfo->shader); /* get texture name */ if(!Q_strncasecmp(buildSide->shaderInfo->shader, "textures/", 9)) texture = buildSide->shaderInfo->shader + 9; else texture = buildSide->shaderInfo->shader; /* get plane points and offset by origin */ for(j = 0; j < 3; j++) { VectorAdd(buildSide->winding->p[j], origin, pts[j]); //% pts[ j ][ 0 ] = SNAP_INT_TO_FLOAT * floor( pts[ j ][ 0 ] * SNAP_FLOAT_TO_INT + 0.5f ); //% pts[ j ][ 1 ] = SNAP_INT_TO_FLOAT * floor( pts[ j ][ 1 ] * SNAP_FLOAT_TO_INT + 0.5f ); //% pts[ j ][ 2 ] = SNAP_INT_TO_FLOAT * floor( pts[ j ][ 2 ] * SNAP_FLOAT_TO_INT + 0.5f ); } /* print brush side */ /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */ fprintf(f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", pts[0][0], pts[0][1], pts[0][2], pts[1][0], pts[1][1], pts[1][2], pts[2][0], pts[2][1], pts[2][2], buildSide->texMat[0][0], buildSide->texMat[0][1], buildSide->texMat[0][2], buildSide->texMat[1][0], buildSide->texMat[1][1], buildSide->texMat[1][2], texture, // DEBUG: valid ? 0 : C_DETAIL 0); // TODO write brush primitives format here } /* end brush */ fprintf(f, "\t}\n"); fprintf(f, "\t}\n\n"); }
float mvtkMatrix4x4::Inverse() { float a1, a2, a3, a4, b1, b2, b3, b4; float c1, c2, c3, c4, d1, d2, d3, d4; a1 = ele[0]; b1 = ele[1]; c1 = ele[2]; d1 = ele[3]; a2 = ele[4]; b2 = ele[5]; c2 = ele[6]; d2 = ele[7]; a3 = ele[8]; b3 = ele[9]; c3 = ele[10]; d3 = ele[11]; a4 = ele[12]; b4 = ele[13]; c4 = ele[14]; d4 = ele[15]; float det1 = Det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4); float det2 = Det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4); float det3 = Det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4); float det4 = Det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4); float det = a1*det1 - b1*det2 + c1*det3 - d1*det4; if(det == 0.0f) return 0.0f; float invdet = 1.0f / det; ele[0] = det1*invdet; ele[4] = -det2*invdet; ele[8] = det3*invdet; ele[12] = -det4*invdet; ele[1] = -Det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4)*invdet; ele[5] = Det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4)*invdet; ele[9] = -Det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4)*invdet; ele[13] = Det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4)*invdet; ele[2] = Det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4)*invdet; ele[6] = -Det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4)*invdet; ele[10]= Det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4)*invdet; ele[14]= -Det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4)*invdet; ele[3]= -Det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3)*invdet; ele[7]= Det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3)*invdet; ele[11]= -Det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3)*invdet; ele[15]= Det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3)*invdet; return det; }