Break the specified (glass) face into shards Parameters: rp, facenum - the face to break. The face must be a portal face. hitpnt - the point on the face where the face shatters. If NULL, uses center point of face hitvec - the direction in which the thing that's breaking the glass is moving. If NULL, uses the negative of the surface normal
| 1478 | // face hitvec - the direction in which the thing that's breaking the glass is |
| 1479 | // moving. If NULL, uses the negative of the surface normal |
| 1480 | void BreakGlassFace(room *rp, int facenum, vector *hitpnt, vector *hitvec) { |
| 1481 | int roomnum; |
| 1482 | vector t_hitpnt, t_hitvec; |
| 1483 | face *fp = &rp->faces[facenum]; |
| 1484 | |
| 1485 | ASSERT(fp->portal_num != -1); |
| 1486 | portal *pp0 = &rp->portals[fp->portal_num]; |
| 1487 | portal *pp1 = &Rooms[pp0->croom].portals[pp0->cportal]; |
| 1488 | |
| 1489 | // If face already broken, bail |
| 1490 | if (!(pp0->flags & PF_RENDER_FACES)) |
| 1491 | return; |
| 1492 | |
| 1493 | // Set hitpnt if not specified |
| 1494 | if (hitpnt == NULL) { |
| 1495 | ComputeCenterPointOnFace(&t_hitpnt, rp, facenum); |
| 1496 | hitpnt = &t_hitpnt; |
| 1497 | } |
| 1498 | |
| 1499 | // Set hitvec if not specified |
| 1500 | if (hitvec == NULL) { |
| 1501 | t_hitvec = -fp->normal; |
| 1502 | hitvec = &t_hitvec; |
| 1503 | } |
| 1504 | |
| 1505 | // Get roomnum |
| 1506 | if (rp->flags & RF_EXTERNAL) |
| 1507 | roomnum = MAKE_ROOMNUM(GetTerrainCellFromPos(hitpnt)); |
| 1508 | else |
| 1509 | roomnum = ROOMNUM(rp); |
| 1510 | |
| 1511 | // Play sound |
| 1512 | pos_state pos; |
| 1513 | pos.position = hitpnt; |
| 1514 | pos.orient = (matrix *)&Identity_matrix; |
| 1515 | pos.roomnum = roomnum; |
| 1516 | |
| 1517 | if (sound_override_glass_breaking == -1) |
| 1518 | Sound_system.Play3dSound(SOUND_BREAKING_GLASS, SND_PRIORITY_HIGH, &pos); |
| 1519 | else |
| 1520 | Sound_system.Play3dSound(sound_override_glass_breaking, SND_PRIORITY_HIGH, &pos); |
| 1521 | |
| 1522 | // Clear render flags |
| 1523 | pp0->flags &= ~PF_RENDER_FACES; |
| 1524 | pp1->flags &= ~PF_RENDER_FACES; |
| 1525 | |
| 1526 | // Get the UV for the hit point |
| 1527 | float hitpnt_u, hitpnt_v; |
| 1528 | FindHitpointUV(&hitpnt_u, &hitpnt_v, hitpnt, rp, facenum); |
| 1529 | |
| 1530 | // Calculate shard movement vector |
| 1531 | vector shardvec = *hitvec; |
| 1532 | vm_NormalizeVectorFast(&shardvec); |
| 1533 | |
| 1534 | // Create shards |
| 1535 | vector prevpoint = rp->verts[fp->face_verts[fp->num_verts - 1]]; |
| 1536 | float prev_u = fp->face_uvls[fp->num_verts - 1].u, prev_v = fp->face_uvls[fp->num_verts - 1].v; |
| 1537 | for (int vertnum = 0; vertnum < fp->num_verts;) { |
no test coverage detected