示例#1
0
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;

}
示例#2
0
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 ());
    }
  }
}
示例#3
0
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);
}
示例#4
0
  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;
  }