BOOL OGF::dbg_SphereContainsVertex(Fvector& c, float R) { Fsphere S; S.set(c,R); for (u32 it=0; it<vertices.size(); it++) if (S.contains(vertices[it].P)) return TRUE; return FALSE ; }
BOOL SphereValid (FvectorVec& geom, Fsphere& test) { if (!f_valid(test.P.x) || !f_valid(test.R)) { Msg ("*** Attention ***: invalid sphere: %f,%f,%f - %f",test.P.x,test.P.y,test.P.z,test.R); } Fsphere S = test; S.R += EPS_L; for (FvectorIt I = geom.begin(); I!=geom.end(); I++) if (!S.contains(*I)) return FALSE; return TRUE; }
bool CSpaceRestrictorWrapper::inside (const Fvector &position, float radius) const { Fsphere sphere; sphere.P = position; sphere.R = radius; typedef CShapeData::ShapeVec ShapeVec; ShapeVec::const_iterator I = object().shapes.begin(); ShapeVec::const_iterator E = object().shapes.end(); for ( ; I != E; ++I) { switch ((*I).type) { case 0 : { Fsphere temp; m_xform.transform_tiny(temp.P,(*I).data.sphere.P); temp.R = (*I).data.sphere.R; if (sphere.intersect(temp)) return (true); continue; } case 1 : { Fmatrix temp; temp.mul_43 (m_xform,(*I).data.box); // Build points Fvector vertices; Fvector points[8]; Fplane plane; vertices.set(-.5f, -.5f, -.5f); temp.transform_tiny(points[0],vertices); vertices.set(-.5f, -.5f, +.5f); temp.transform_tiny(points[1],vertices); vertices.set(-.5f, +.5f, +.5f); temp.transform_tiny(points[2],vertices); vertices.set(-.5f, +.5f, -.5f); temp.transform_tiny(points[3],vertices); vertices.set(+.5f, +.5f, +.5f); temp.transform_tiny(points[4],vertices); vertices.set(+.5f, +.5f, -.5f); temp.transform_tiny(points[5],vertices); vertices.set(+.5f, -.5f, +.5f); temp.transform_tiny(points[6],vertices); vertices.set(+.5f, -.5f, -.5f); temp.transform_tiny(points[7],vertices); plane.build(points[0],points[3],points[5]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[1],points[2],points[3]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[6],points[5],points[4]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[4],points[2],points[1]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[3],points[2],points[4]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[1],points[0],points[6]); if (plane.classify(sphere.P)>sphere.R) break; return (true); } default : NODEFAULT; } } return (false); }
void base_lighting::select (xr_vector<R_Light>& dest, xr_vector<R_Light>& src, Fvector& P, float R) { Fsphere Sphere; Sphere.set (P,R); dest.clear (); R_Light* L = &*src.begin(); for (; L!=&*src.end(); L++) { if (L->type==LT_POINT) { float dist = Sphere.P.distance_to(L->position); if (dist>(Sphere.R+L->range)) continue; } dest.push_back(*L); } }
void ComputeSphere(Fsphere &B, FvectorVec& V) { if (V.size()<3) { B.P.set(0,0,0); B.R=0.f; return; } // 1: calc first variation Fsphere S1; Fsphere_compute (S1,V.begin(),V.size()); BOOL B1 = SphereValid(V,S1); // 2: calc ordinary algorithm (2nd) Fsphere S2; Fbox bbox; bbox.invalidate (); for (FvectorIt I=V.begin(); I!=V.end(); I++) bbox.modify(*I); bbox.grow (EPS_L); bbox.getsphere (S2.P,S2.R); S2.R = -1; for (I=V.begin(); I!=V.end(); I++) { float d = S2.P.distance_to_sqr(*I); if (d>S2.R) S2.R=d; } S2.R = _sqrt (_abs(S2.R)); BOOL B2 = SphereValid(V,S2); // 3: calc magic-fm Mgc::Sphere _S3 = Mgc::MinSphere(V.size(), (const Mgc::Vector3*) V.begin()); Fsphere S3; S3.P.set (_S3.Center().x,_S3.Center().y,_S3.Center().z); S3.R = _S3.Radius(); BOOL B3 = SphereValid(V,S3); // select best one if (B1 && (S1.R<S2.R)){ // miniball or FM if (B3 && (S3.R<S1.R)){ // FM wins B.set (S3); }else{ // MiniBall wins B.set (S1); } }else{ // base or FM if (B3 && (S3.R<S2.R)){ // FM wins B.set (S3); }else{ // Base wins :) R_ASSERT(B2); B.set (S2); } } }
bool CBone::Pick(float& dist, const Fvector& S, const Fvector& D, const Fmatrix& parent) { Fvector start, dir; Fmatrix M; M.mul_43(parent,_LTransform()); M.invert(); M.transform_tiny(start,S); M.transform_dir(dir,D); switch (shape.type){ case SBoneShape::stBox: return shape.box.intersect (start,dir,dist); case SBoneShape::stSphere: return shape.sphere.intersect (start,dir,dist); case SBoneShape::stCylinder:return shape.cylinder.intersect (start,dir,dist); default: Fsphere S; S.P.set(0,0,0); S.R=0.025f; return S.intersect(start,dir,dist); } }
bool __fastcall TUI_ControlShapeAdd::AfterAppendCallback(TShiftState Shift, CCustomObject* obj) { CEditShape* shape = dynamic_cast<CEditShape*>(obj); R_ASSERT(shape); TfraShape* F = (TfraShape*)parent_tool->pFrame; if (F->ebTypeSphere->Down){ Fsphere S; S.identity(); shape->add_sphere(S); if (!Shift.Contains(ssAlt)) F->ebTypeSphere->Down = false; return true; }else if (F->ebTypeBox->Down){ Fmatrix M; M.identity(); shape->add_box(M); if (!Shift.Contains(ssAlt)) F->ebTypeBox->Down = false; return true; }else{ ELog.DlgMsg(mtInformation,"Select shape type at first."); } return false; }
//---------------------------------------------------------------------- int CObjectSpace::GetNearest ( xr_vector<ISpatial*>& q_spatial, xr_vector<CObject*>& q_nearest, const Fvector &point, float range, CObject* ignore_object ) { q_spatial.clear_not_free ( ); // Query objects q_nearest.clear_not_free ( ); Fsphere Q; Q.set (point,range); Fvector B; B.set (range,range,range); g_SpatialSpace->q_box(q_spatial,0,STYPE_COLLIDEABLE,point,B); // Iterate xr_vector<ISpatial*>::iterator it = q_spatial.begin (); xr_vector<ISpatial*>::iterator end = q_spatial.end (); for (; it!=end; it++) { CObject* O = (*it)->dcast_CObject (); if (0==O) continue; if (O==ignore_object) continue; Fsphere mS = { O->spatial.sphere.P, O->spatial.sphere.R }; if (Q.intersect(mS)) q_nearest.push_back(O); } return q_nearest.size(); }