| 296 | |
| 297 | isx.type = rpINTERSECTSPHERE; |
| 298 | *(xSphere*)&isx.t.sphere = *b; |
| 299 | |
| 300 | xMat4x3* mat = (xMat4x3*)m->Mat; |
| 301 | RwFrame* frame = RpAtomicGetFrame(m->Data); |
| 302 | RwFrameTransform(frame, (RwMatrix*)mat, rwCOMBINEREPLACE); |
| 303 | |
| 304 | F32 mscale = xVec3Length(&mat->right); |
| 305 | xMat4x3Tolocal((xVec3*)&context.localx.t.sphere.center, mat, &b->center); |
| 306 | context.localx.t.sphere.radius = b->r / mscale; |
| 307 | |
| 308 | coll->flags &= ~k_HIT_IT; |
| 309 | coll->dist = HUGE; |
| 310 | |
| 311 | if (coll->flags & k_HIT_CALC_TRI) |
| 312 | { |
| 313 | coll->flags |= k_HIT_0x400; |
| 314 | } |
| 315 | |
| 316 | RpAtomicForAllIntersections(m->Data, &isx, sphereHitsModelCB, &context); |
| 317 | |
| 318 | if ((coll->flags & k_HIT_CALC_TRI) && (coll->flags & k_HIT_IT)) |
| 319 | { |
| 320 | xCollideCalcTri(coll->tri, *m, *(xVec3*)&context.localx.t.sphere.center, coll->tohit); |
| 321 | } |
| 322 | |
| 323 | if (coll->flags & k_HIT_0x400) |
| 324 | { |
| 325 | xMat3x3RMulVec(&coll->tohit, mat, &coll->tohit); |
| 326 | } |
| 327 | |
| 328 | if (coll->flags & k_HIT_0x800) |
| 329 | { |
| 330 | xMat3x3RMulVec(&coll->depen, mat, &coll->depen); |
| 331 | } |
| 332 | |
| 333 | if (coll->flags & k_HIT_CALC_HDNG) |
| 334 | { |
| 335 | xMat3x3RMulVec(&coll->hdng, mat, &coll->hdng); |
| 336 | } |
| 337 | |
| 338 | if (coll->flags & k_HIT_0x200) |
| 339 | { |
| 340 | xMat3x3RMulVec(&coll->norm, mat, &coll->norm); |
| 341 | F32 mag2 = coll->norm.length2(); |
| 342 | if (!xeq(mag2, 1.0f, 1e-5f)) |
| 343 | { |
| 344 | coll->norm *= 1.0f / xsqrt(mag2); |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | coll->dist *= mscale; |
| 349 | |
| 350 | if (m->Flags & 0x800) |
| 351 | { |
| 352 | xModelAnimCollRestore(*m); |
| 353 | } |
| 354 | |
| 355 | return coll->flags & k_HIT_IT; |
no test coverage detected