static void ParseBrush(void) { vec3_t planepts[3]; vec3_t t1, t2, t3; int i, j; texinfo_t tx; vec_t d; int shift[2], rotate; vec_t scale[2]; int iFace; int tx_type; map.rgBrushes[map.iBrushes].iFaceEnd = map.iFaces + 1; while (ParseToken(PARSE_NORMAL)) { if (!strcmp(token, "}")) break; // read the three point plane definition for (i = 0; i < 3; i++) { if (i != 0) ParseToken(PARSE_NORMAL); if (strcmp(token, "(")) Message(msgError, errInvalidMapPlane, linenum); for (j = 0; j < 3; j++) { ParseToken(PARSE_SAMELINE); planepts[i][j] = atof(token); } ParseToken(PARSE_SAMELINE); if (strcmp(token, ")")) Message(msgError, errInvalidMapPlane, linenum); } // read the texturedef memset(&tx, 0, sizeof(tx)); ParseToken(PARSE_SAMELINE); tx.miptex = FindMiptex(token); ParseToken(PARSE_SAMELINE); shift[0] = atoi(token); ParseToken(PARSE_SAMELINE); shift[1] = atoi(token); ParseToken(PARSE_SAMELINE); rotate = atoi(token); ParseToken(PARSE_SAMELINE); scale[0] = atof(token); ParseToken(PARSE_SAMELINE); scale[1] = atof(token); // if the three points are all on a previous plane, it is a // duplicate plane for (iFace = map.rgBrushes[map.iBrushes].iFaceEnd - 1; iFace > map.iFaces; iFace--) { for (i = 0; i < 3; i++) { d = DotProduct(planepts[i], map.rgFaces[iFace].plane.normal) - map.rgFaces[iFace].plane.dist; if (d < -ON_EPSILON || d > ON_EPSILON) break; } if (i == 3) break; } if (iFace > map.iFaces) { Message(msgWarning, warnBrushDuplicatePlane, linenum); continue; } if (map.iFaces < 0) Message(msgError, errLowFaceCount); // convert to a vector / dist plane for (j = 0; j < 3; j++) { t1[j] = planepts[0][j] - planepts[1][j]; t2[j] = planepts[2][j] - planepts[1][j]; t3[j] = planepts[1][j]; } CrossProduct(t1, t2, map.rgFaces[map.iFaces].plane.normal); if (VectorCompare(map.rgFaces[map.iFaces].plane.normal, vec3_origin)) { Message(msgWarning, warnNoPlaneNormal, linenum); break; } VectorNormalize(map.rgFaces[map.iFaces].plane.normal); map.rgFaces[map.iFaces].plane.dist = DotProduct(t3, map.rgFaces[map.iFaces].plane.normal); tx_type = ParseExtendedTX(); switch (tx_type) { case TX_QUARK_TYPE1: case TX_QUARK_TYPE2: SetTexinfo_QuArK(planepts, tx_type, &tx); break; default: SetTexinfo_QuakeEd(shift, rotate, scale, &tx); break; } // unique the texinfo map.rgFaces[map.iFaces].texinfo = FindTexinfo(&tx); map.iFaces--; Message(msgPercent, map.cFaces - map.iFaces - 1, map.cFaces); } map.rgBrushes[map.iBrushes].iFaceStart = map.iFaces + 1; map.iBrushes--; }
static void ParseBrush(parser_t *parser, mapbrush_t *brush) { vec3_t planepts[3]; vec3_t t1, t2, t3; int i, j; texinfo_t tx; vec_t d; int shift[2], rotate; vec_t scale[2]; int tx_type; plane_t *plane; mapface_t *face, *checkface; brush->faces = face = map.faces + map.numfaces; while (ParseToken(parser, PARSE_NORMAL)) { if (!strcmp(parser->token, "}")) break; // read the three point plane definition for (i = 0; i < 3; i++) { if (i != 0) ParseToken(parser, PARSE_NORMAL); if (strcmp(parser->token, "(")) Error(errInvalidMapPlane, parser->linenum); for (j = 0; j < 3; j++) { ParseToken(parser, PARSE_SAMELINE); planepts[i][j] = atof(parser->token); } ParseToken(parser, PARSE_SAMELINE); if (strcmp(parser->token, ")")) Error(errInvalidMapPlane, parser->linenum); } // read the texturedef memset(&tx, 0, sizeof(tx)); ParseToken(parser, PARSE_SAMELINE); tx.miptex = FindMiptex(parser->token); ParseToken(parser, PARSE_SAMELINE); shift[0] = atoi(parser->token); ParseToken(parser, PARSE_SAMELINE); shift[1] = atoi(parser->token); ParseToken(parser, PARSE_SAMELINE); rotate = atoi(parser->token); ParseToken(parser, PARSE_SAMELINE); scale[0] = atof(parser->token); ParseToken(parser, PARSE_SAMELINE); scale[1] = atof(parser->token); // if the three points are all on a previous plane, it is a // duplicate plane for (checkface = brush->faces; checkface < face; checkface++) { plane = &checkface->plane; for (i = 0; i < 3; i++) { d = DotProduct(planepts[i], plane->normal) - plane->dist; if (d < -ON_EPSILON || d > ON_EPSILON) break; } if (i == 3) break; } if (checkface < face) { Message(msgWarning, warnBrushDuplicatePlane, parser->linenum); continue; } if (map.numfaces == map.maxfaces) Error(errLowFaceCount); // convert to a vector / dist plane for (j = 0; j < 3; j++) { t1[j] = planepts[0][j] - planepts[1][j]; t2[j] = planepts[2][j] - planepts[1][j]; t3[j] = planepts[1][j]; } plane = &face->plane; CrossProduct(t1, t2, plane->normal); if (VectorCompare(plane->normal, vec3_origin)) { Message(msgWarning, warnNoPlaneNormal, parser->linenum); continue; } VectorNormalize(plane->normal); plane->dist = DotProduct(t3, plane->normal); tx_type = ParseExtendedTX(parser); switch (tx_type) { case TX_QUARK_TYPE1: case TX_QUARK_TYPE2: SetTexinfo_QuArK(parser, &planepts[0], tx_type, &tx); break; default: SetTexinfo_QuakeEd(plane, shift, rotate, scale, &tx); break; } face->texinfo = FindTexinfo(&tx); face++; map.numfaces++; Message(msgPercent, map.numfaces, map.maxfaces); } brush->numfaces = face - brush->faces; if (!brush->numfaces) brush->faces = NULL; }