File indexing completed on 2025-08-03 03:49:54
0001 /* 0002 * Copyright (c) 2006-2010 Erin Catto http://www.gphysics.com 0003 * 0004 * This software is provided 'as-is', without any express or implied 0005 * warranty. In no event will the authors be held liable for any damages 0006 * arising from the use of this software. 0007 * Permission is granted to anyone to use this software for any purpose, 0008 * including commercial applications, and to alter it and redistribute it 0009 * freely, subject to the following restrictions: 0010 * 1. The origin of this software must not be misrepresented; you must not 0011 * claim that you wrote the original software. If you use this software 0012 * in a product, an acknowledgment in the product documentation would be 0013 * appreciated but is not required. 0014 * 2. Altered source versions must be plainly marked as such, and must not be 0015 * misrepresented as being the original software. 0016 * 3. This notice may not be removed or altered from any source distribution. 0017 */ 0018 0019 #include <Box2D/Collision/Shapes/b2EdgeShape.h> 0020 #include <new> 0021 using namespace std; 0022 0023 void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2) 0024 { 0025 m_vertex1 = v1; 0026 m_vertex2 = v2; 0027 m_hasVertex0 = false; 0028 m_hasVertex3 = false; 0029 } 0030 0031 b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const 0032 { 0033 void* mem = allocator->Allocate(sizeof(b2EdgeShape)); 0034 b2EdgeShape* clone = new (mem) b2EdgeShape; 0035 *clone = *this; 0036 return clone; 0037 } 0038 0039 int32 b2EdgeShape::GetChildCount() const 0040 { 0041 return 1; 0042 } 0043 0044 bool b2EdgeShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const 0045 { 0046 B2_NOT_USED(xf); 0047 B2_NOT_USED(p); 0048 return false; 0049 } 0050 0051 // p = p1 + t * d 0052 // v = v1 + s * e 0053 // p1 + t * d = v1 + s * e 0054 // s * e - t * d = p1 - v1 0055 bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, 0056 const b2Transform& xf, int32 childIndex) const 0057 { 0058 B2_NOT_USED(childIndex); 0059 0060 // Put the ray into the edge's frame of reference. 0061 b2Vec2 p1 = b2MulT(xf.R, input.p1 - xf.position); 0062 b2Vec2 p2 = b2MulT(xf.R, input.p2 - xf.position); 0063 b2Vec2 d = p2 - p1; 0064 0065 b2Vec2 v1 = m_vertex1; 0066 b2Vec2 v2 = m_vertex2; 0067 b2Vec2 e = v2 - v1; 0068 b2Vec2 normal(e.y, -e.x); 0069 normal.Normalize(); 0070 0071 // q = p1 + t * d 0072 // dot(normal, q - v1) = 0 0073 // dot(normal, p1 - v1) + t * dot(normal, d) = 0 0074 qreal numerator = b2Dot(normal, v1 - p1); 0075 qreal denominator = b2Dot(normal, d); 0076 0077 if (denominator == 0.0f) 0078 { 0079 return false; 0080 } 0081 0082 qreal t = numerator / denominator; 0083 if (t < 0.0f || 1.0f < t) 0084 { 0085 return false; 0086 } 0087 0088 b2Vec2 q = p1 + t * d; 0089 0090 // q = v1 + s * r 0091 // s = dot(q - v1, r) / dot(r, r) 0092 b2Vec2 r = v2 - v1; 0093 qreal rr = b2Dot(r, r); 0094 if (rr == 0.0f) 0095 { 0096 return false; 0097 } 0098 0099 qreal s = b2Dot(q - v1, r) / rr; 0100 if (s < 0.0f || 1.0f < s) 0101 { 0102 return false; 0103 } 0104 0105 output->fraction = t; 0106 if (numerator > 0.0f) 0107 { 0108 output->normal = -normal; 0109 } 0110 else 0111 { 0112 output->normal = normal; 0113 } 0114 return true; 0115 } 0116 0117 void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const 0118 { 0119 B2_NOT_USED(childIndex); 0120 0121 b2Vec2 v1 = b2Mul(xf, m_vertex1); 0122 b2Vec2 v2 = b2Mul(xf, m_vertex2); 0123 0124 b2Vec2 lower = b2Min(v1, v2); 0125 b2Vec2 upper = b2Max(v1, v2); 0126 0127 b2Vec2 r(m_radius, m_radius); 0128 aabb->lowerBound = lower - r; 0129 aabb->upperBound = upper + r; 0130 } 0131 0132 void b2EdgeShape::ComputeMass(b2MassData* massData, qreal density) const 0133 { 0134 B2_NOT_USED(density); 0135 0136 massData->mass = 0.0f; 0137 massData->center = 0.5f * (m_vertex1 + m_vertex2); 0138 massData->I = 0.0f; 0139 }