float float3::AngleBetween(const float3 &other) const { float cosa = Dot(other) / Sqrt(LengthSq() * other.LengthSq()); if (cosa >= 1.f) return 0.f; else if (cosa <= -1.f) return pi; else return acos(cosa); }
//-------------------------------------------------------------------------------------------------------- // checks point-intersection with sphere (point is relative to owner) //-------------------------------------------------------------------------------------------------------- Bool GCollisionObj::IntersectionSpherePoint(float3 Point) { // translate so point is local to sphere Point += m_Offset; // get dist to point float DistSq = Point.LengthSq(); if ( DistSq > (m_SphereRadius*m_SphereRadius) ) return FALSE; return TRUE; }
void RigidBody::ApplyTorqueImpulse(const float3& torqueImpulse) { // Cannot modify server-authoritative physics object if (!HasAuthority()) return; // If impulse is very small, do not wake up the body and apply if (torqueImpulse.LengthSq() < cTorqueThresholdSq) return; if (!impl->body) CreateBody(); if (impl->body) { Activate(); impl->body->applyTorqueImpulse(torqueImpulse); } }
void RigidBody::ApplyImpulse(const float3& impulse, const float3& position) { // Cannot modify server-authoritative physics object if (!HasAuthority()) return; // If impulse is very small, do not wake up the body and apply if (impulse.LengthSq() < cImpulseThresholdSq) return; if (!impl->body) CreateBody(); if (impl->body) { Activate(); if (position.Equals(float3::zero)) impl->body->applyCentralImpulse(impulse); else impl->body->applyImpulse(impulse, position); } }
float3 float3::ProjectTo(const float3 &direction) const { assume(!direction.IsZero()); return direction * this->Dot(direction) / direction.LengthSq(); }
float4 float4::ProjectTo3(const float3 &target) const { assume(!target.IsZero()); assume(this->IsWZeroOrOne()); return float4(target * Dot(xyz(), target) / target.LengthSq(), w); }
bool AABB::IntersectLineAABB_CPP(const float3 &linePos, const float3 &lineDir, float &tNear, float &tFar) const { assume2(lineDir.IsNormalized(), lineDir, lineDir.LengthSq()); assume2(tNear <= tFar && "AABB::IntersectLineAABB: User gave a degenerate line as input for the intersection test!", tNear, tFar); // The user should have inputted values for tNear and tFar to specify the desired subrange [tNear, tFar] of the line // for this intersection test. // For a Line-AABB test, pass in // tNear = -FLOAT_INF; // tFar = FLOAT_INF; // For a Ray-AABB test, pass in // tNear = 0.f; // tFar = FLOAT_INF; // For a LineSegment-AABB test, pass in // tNear = 0.f; // tFar = LineSegment.Length(); // Test each cardinal plane (X, Y and Z) in turn. if (!EqualAbs(lineDir.x, 0.f)) { float recipDir = RecipFast(lineDir.x); float t1 = (minPoint.x - linePos.x) * recipDir; float t2 = (maxPoint.x - linePos.x) * recipDir; // tNear tracks distance to intersect (enter) the AABB. // tFar tracks the distance to exit the AABB. if (t1 < t2) tNear = Max(t1, tNear), tFar = Min(t2, tFar); else // Swap t1 and t2. tNear = Max(t2, tNear), tFar = Min(t1, tFar); if (tNear > tFar) return false; // Box is missed since we "exit" before entering it. } else if (linePos.x < minPoint.x || linePos.x > maxPoint.x) return false; // The ray can't possibly enter the box, abort. if (!EqualAbs(lineDir.y, 0.f)) { float recipDir = RecipFast(lineDir.y); float t1 = (minPoint.y - linePos.y) * recipDir; float t2 = (maxPoint.y - linePos.y) * recipDir; if (t1 < t2) tNear = Max(t1, tNear), tFar = Min(t2, tFar); else // Swap t1 and t2. tNear = Max(t2, tNear), tFar = Min(t1, tFar); if (tNear > tFar) return false; // Box is missed since we "exit" before entering it. } else if (linePos.y < minPoint.y || linePos.y > maxPoint.y) return false; // The ray can't possibly enter the box, abort. if (!EqualAbs(lineDir.z, 0.f)) // ray is parallel to plane in question { float recipDir = RecipFast(lineDir.z); float t1 = (minPoint.z - linePos.z) * recipDir; float t2 = (maxPoint.z - linePos.z) * recipDir; if (t1 < t2) tNear = Max(t1, tNear), tFar = Min(t2, tFar); else // Swap t1 and t2. tNear = Max(t2, tNear), tFar = Min(t1, tFar); } else if (linePos.z < minPoint.z || linePos.z > maxPoint.z) return false; // The ray can't possibly enter the box, abort. return tNear <= tFar; }
bool float3::IsPerpendicular(const float3 &other, float epsilonSq) const { float dot = Dot(other); return dot*dot <= epsilonSq * LengthSq() * other.LengthSq(); }