static int OOF_ReadIntList (CFile& cf, CArray<int>& list) { uint i; char szId [20] = ""; list.Destroy (); if (!(i = OOF_ReadInt (cf, "nList"))) return 0; if (!list.Create (i)) return -1; for (i = 0; i < list.Length (); i++) { if (bLogOOF) sprintf (szId, "list [%d]", i); list [i] = OOF_ReadInt (cf, szId); } return list.Length (); }
fix CModel::Radius (CObject *objP) { CSubModel* psm; CFace* pmf; CVertex* pmv; CArray<CFloatVector3> vertices; CFloatVector3 vCenter, vOffset, v, vMin, vMax; float fRad = 0, r; short h, i, j, k; tModelSphere *sP = gameData.models.spheres + m_nModel; if (m_nType >= 0) { if ((m_nSubModels == sP->nSubModels) && (m_nFaces == sP->nFaces) && (m_nFaceVerts == sP->nFaceVerts)) { gameData.models.offsets [m_nModel] = sP->vOffsets [m_nType]; return sP->xRads [m_nType]; } } //first get the biggest distance between any two model vertices if (vertices.Create (m_nFaceVerts)) { CFloatVector3 *pv, *pvi, *pvj; for (i = 0, h = m_nSubModels, psm = m_subModels.Buffer (), pv = vertices.Buffer (); i < h; i++, psm++) { if (psm->m_nHitbox > 0) { vOffset.Assign (gameData.models.hitboxes [m_nModel].hitboxes [psm->m_nHitbox].vOffset); for (j = psm->m_nFaces, pmf = psm->m_faces; j; j--, pmf++) { for (k = pmf->m_nVerts, pmv = m_faceVerts + pmf->m_nIndex; k; k--, pmv++, pv++) *pv = pmv->m_vertex + vOffset; } } } h = (short) (pv - vertices.Buffer ()) - 1; CQuickSort<CFloatVector3> qs; qs.SortAscending (vertices.Buffer (), 0, h, &RenderModel::CModel::CmpVerts); //G3SortModelVerts (vertices, 0, h); h = FilterVertices (vertices, h); for (i = 0, pvi = vertices.Buffer (); i < h - 1; i++, pvi++) for (j = i + 1, pvj = vertices + j; j < h; j++, pvj++) if (fRad < (r = CFloatVector3::Dist (*pvi, *pvj))) { fRad = r; vMin = *pvi; vMax = *pvj; } fRad /= 2; // then move the tentatively computed model center around so that all vertices are enclosed in the sphere // around the center with the radius computed above vCenter.Assign (gameData.models.offsets [m_nModel]); for (i = h, pv = vertices.Buffer (); i; i--, pv++) { v = *pv - vCenter; r = v.Mag(); if (fRad < r) vCenter += v * ((r - fRad) / r); } for (i = h, pv = vertices.Buffer (); i; i--, pv++) if (fRad < (r = CFloatVector3::Dist (*pv, vCenter))) fRad = r; vertices.Destroy (); gameData.models.offsets [m_nModel].Assign (vCenter); if (m_nType >= 0) { sP->nSubModels = m_nSubModels; sP->nFaces = m_nFaces; sP->nFaceVerts = m_nFaceVerts; sP->vOffsets [m_nType] = gameData.models.offsets [m_nModel]; sP->xRads [m_nType] = F2X (fRad); } } else { // then move the tentatively computed model center around so that all vertices are enclosed in the sphere // around the center with the radius computed above vCenter.Assign (gameData.models.offsets [m_nModel]); for (i = 0, h = m_nSubModels, psm = m_subModels.Buffer (); i < h; i++, psm++) { if (psm->m_nHitbox > 0) { vOffset.Assign (gameData.models.hitboxes [m_nModel].hitboxes [psm->m_nHitbox].vOffset); for (j = psm->m_nFaces, pmf = psm->m_faces; j; j--, pmf++) { for (k = pmf->m_nVerts, pmv = m_faceVerts + pmf->m_nIndex; k; k--, pmv++) { v = pmv->m_vertex + vOffset; if (fRad < (r = CFloatVector3::Dist (v, vCenter))) fRad = r; } } } } gameData.models.offsets [m_nModel].Assign (vCenter); } return F2X (fRad); }