protected bool _perInstanceIntersectionTest(SSAbstractMesh abstrMesh, int i, ref SSRay localRay, out float localContact) { var pos = instanceData.readPosition(i); var masterScale = instanceData.readMasterScale(i); var scale = instanceData.readComponentScale(i) * masterScale; if (abstrMesh == null) { // no way to be any more precise except hitting a generic sphere float radius = Math.Max(scale.Z, Math.Max(scale.X, scale.Y)); var sphere = new SSSphere(pos, radius); return(sphere.IntersectsRay(ref localRay, out localContact)); } else { // When using SSAbstractMesh we can invoke its preciseIntersect() Matrix4 instanceMat = Matrix4.CreateScale(scale) * Matrix4.CreateTranslation(pos); SSRay instanceRay = localRay.Transformed(instanceMat.Inverted()); float instanceContact; if (abstrMesh.preciseIntersect(ref instanceRay, out instanceContact)) { Vector3 instanceContactPt = instanceRay.pos + instanceContact * instanceRay.dir; Vector3 localContactPt = Vector3.Transform(instanceContactPt, instanceMat); localContact = (localContactPt - localRay.pos).Length; return(true); } else { localContact = float.PositiveInfinity; return(false); } } }
protected virtual bool validate(SSSphere newBodyInfo) { // override to handle collision tests efficiently for a specific shape of a field // or add other clipping tests.. newBodyInfo.radius += m_safetyDistance; if (m_bodyRadius == 0.0f) { return(true); } List <ssBVHNode <SSSphere> > intersectList = m_bodiesSoFar.traverse(newBodyInfo.ToAABB()); foreach (ssBVHNode <SSSphere> node in intersectList) { if (node.gobjects != null) { foreach (SSSphere sphere in node.gobjects) { if (newBodyInfo.IntersectsSphere(sphere)) { return(false); // invalid } } } } m_bodiesSoFar.addObject(newBodyInfo); return(true); // valid }
public bool IntersectsSphere(SSSphere sphere) { return(IntersectsSphere(sphere.center, sphere.radius)); }