void csPortalContainer::Prepare () { if (prepared) return; prepared = true; movable_nr = -1; // Make sure move stuff gets updated. movable_identity = false; data_nr++; csCompressVertex* vt = csVector3Array::CompressVertices (vertices); size_t i; for (i = 0 ; i < portals.GetSize () ; i++) { csPortal* prt = portals[i]; size_t j; csArray<int>& vidx = prt->GetVertexIndices (); csPoly3D poly; csBox3 box; box.StartBoundingBox (); for (j = 0 ; j < vidx.GetSize () ; j++) { if (vt) vidx[j] = (int)vt[vidx[j]].new_idx; poly.AddVertex (vertices[vidx[j]]); box.AddBoundingVertex (vertices[vidx[j]]); } float max_sqradius = 0; csVector3 center = box.GetCenter (); for (j = 0 ; j < vidx.GetSize () ; j++) { float sqdist = csSquaredDist::PointPoint (center, vertices[vidx[j]]); if (sqdist > max_sqradius) max_sqradius = sqdist; } prt->object_sphere = csSphere (center, csQsqrt (max_sqradius)); prt->SetObjectPlane (poly.ComputePlane ()); } delete[] vt; object_bbox.StartBoundingBox (); for (i = 0 ; i < vertices.GetSize () ; i++) object_bbox.AddBoundingVertex (vertices[i]); object_radius = csQsqrt (csSquaredDist::PointPoint ( object_bbox.Max (), object_bbox.Min ())) * 0.5f; }
void csPortalContainer::ObjectToWorld (const csMovable& movable, const csReversibleTransform& movtrans) { movable_nr = movable.GetUpdateNumber (); movable_identity = movable.IsFullTransformIdentity (); size_t i; world_vertices.SetSize (vertices.GetSize ()); if (movable_identity) { world_vertices = vertices; for (i = 0 ; i < portals.GetSize () ; i++) { csPortal* prt = portals[i]; csPlane3 wp (prt->GetIntObjectPlane ()); prt->SetWorldPlane (wp); prt->world_sphere = prt->object_sphere; } } else { for (i = 0 ; i < vertices.GetSize () ; i++) world_vertices[i] = movtrans.This2Other (vertices[i]); for (i = 0 ; i < portals.GetSize () ; i++) { csPortal* prt = portals[i]; csPlane3 p; csVector3& world_vec = world_vertices[portals[i]->GetVertexIndices ()[0]]; movtrans.This2Other (prt->GetIntObjectPlane (), world_vec, p); p.Normalize (); prt->SetWorldPlane (p); prt->world_sphere = csSphere ( movtrans.This2Other (prt->object_sphere.GetCenter ()), prt->object_sphere.GetRadius ()); } } }
csSphere TransformTools::GetSphereSelected (iSelection* selection) { csBox3 box = GetBoxSelected (selection); float dist = sqrt (csSquaredDist::PointPoint (box.Min (), box.Max ())); return csSphere (box.GetCenter (), dist/2.0f); }
bool BodyMeshLoader::ParseColliders (iDocumentNode* node, iLoaderContext* ldr_context, CS::Animation::iBodyBone* bone) { csRef<iDocumentNodeIterator> it = node->GetNodes (); while (it->HasNext ()) { csRef<iDocumentNode> child = it->Next (); if (child->GetType () != CS_NODE_ELEMENT) continue; const char *value = child->GetValue (); csStringID id = xmltokens.Request (value); switch (id) { case XMLTOKEN_COLLIDERMESH: case XMLTOKEN_COLLIDERCONVEXMESH: { if (!child->GetAttributeValue ("mesh")) { synldr->ReportError (msgid, child, "No mesh specified for collidermesh"); return false; } // try to find a mesh factory csRef<iMeshWrapper> mesh; csRef<iMeshFactoryWrapper> meshFactory = ldr_context->FindMeshFactory (child->GetAttributeValue ("mesh")); if (meshFactory) mesh = meshFactory->CreateMeshWrapper (); // try to find a mesh else { mesh = ldr_context->FindMeshObject (child->GetAttributeValue ("mesh")); if (!mesh) { synldr->ReportError (msgid, child, "Unable to find mesh or factory %s while loading collider", CS::Quote::Single (child->GetAttributeValue ("mesh"))); return false; } } // create collider CS::Animation::iBodyBoneCollider* collider = bone->CreateBoneCollider (); if (id == XMLTOKEN_COLLIDERMESH) collider->SetMeshGeometry (mesh); else collider->SetConvexMeshGeometry (mesh); // parse params ParseColliderParams (child, collider); break; } case XMLTOKEN_COLLIDERBOX: { csVector3 v; if (!synldr->ParseVector (child, v)) { synldr->ReportError (msgid, child, "Error processing box parameters"); return false; } CS::Animation::iBodyBoneCollider* collider = bone->CreateBoneCollider (); collider->SetBoxGeometry (v); ParseColliderParams (child, collider); break; } case XMLTOKEN_COLLIDERSPHERE: { float r = child->GetAttributeValueAsFloat ("radius"); csVector3 v; if (!synldr->ParseVector (child, v)) { synldr->ReportError (msgid, child, "Error processing box parameters"); return false; } CS::Animation::iBodyBoneCollider* collider = bone->CreateBoneCollider (); collider->SetSphereGeometry (csSphere (v, r)); ParseColliderParams (child, collider); break; } case XMLTOKEN_COLLIDERCYLINDER: { float l = child->GetAttributeValueAsFloat ("length"); float r = child->GetAttributeValueAsFloat ("radius"); CS::Animation::iBodyBoneCollider* collider = bone->CreateBoneCollider (); collider->SetCylinderGeometry (l, r); ParseColliderParams (child, collider); break; } case XMLTOKEN_COLLIDERCAPSULE: { float l = child->GetAttributeValueAsFloat ("length"); float r = child->GetAttributeValueAsFloat ("radius"); CS::Animation::iBodyBoneCollider* collider = bone->CreateBoneCollider (); collider->SetCapsuleGeometry (l, r); ParseColliderParams (child, collider); break; } case XMLTOKEN_COLLIDERPLANE: { csPlane3 plane; synldr->ParsePlane (node, plane); CS::Animation::iBodyBoneCollider* collider = bone->CreateBoneCollider (); collider->SetPlaneGeometry (plane); ParseColliderParams (child, collider); break; } default: synldr->ReportBadToken (child); return false; } } return true; }