File indexing completed on 2025-02-16 03:29:32
0001 /* 0002 * Copyright (c) 2006-2010 Erin Catto http://www.box2d.org 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 0022 void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2) 0023 { 0024 m_vertex1 = v1; 0025 m_vertex2 = v2; 0026 m_hasVertex0 = false; 0027 m_hasVertex3 = false; 0028 } 0029 0030 b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const 0031 { 0032 void* mem = allocator->Allocate(sizeof(b2EdgeShape)); 0033 b2EdgeShape* clone = new (mem) b2EdgeShape; 0034 *clone = *this; 0035 return clone; 0036 } 0037 0038 int32 b2EdgeShape::GetChildCount() const 0039 { 0040 return 1; 0041 } 0042 0043 bool b2EdgeShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const 0044 { 0045 B2_NOT_USED(xf); 0046 B2_NOT_USED(p); 0047 return false; 0048 } 0049 0050 // p = p1 + t * d 0051 // v = v1 + s * e 0052 // p1 + t * d = v1 + s * e 0053 // s * e - t * d = p1 - v1 0054 bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, 0055 const b2Transform& xf, int32 childIndex) const 0056 { 0057 B2_NOT_USED(childIndex); 0058 0059 // Put the ray into the edge's frame of reference. 0060 b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p); 0061 b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p); 0062 b2Vec2 d = p2 - p1; 0063 0064 b2Vec2 v1 = m_vertex1; 0065 b2Vec2 v2 = m_vertex2; 0066 b2Vec2 e = v2 - v1; 0067 b2Vec2 normal(e.y, -e.x); 0068 normal.Normalize(); 0069 0070 // q = p1 + t * d 0071 // dot(normal, q - v1) = 0 0072 // dot(normal, p1 - v1) + t * dot(normal, d) = 0 0073 float32 numerator = b2Dot(normal, v1 - p1); 0074 float32 denominator = b2Dot(normal, d); 0075 0076 if (denominator == 0.0f) 0077 { 0078 return false; 0079 } 0080 0081 float32 t = numerator / denominator; 0082 if (t < 0.0f || input.maxFraction < t) 0083 { 0084 return false; 0085 } 0086 0087 b2Vec2 q = p1 + t * d; 0088 0089 // q = v1 + s * r 0090 // s = dot(q - v1, r) / dot(r, r) 0091 b2Vec2 r = v2 - v1; 0092 float32 rr = b2Dot(r, r); 0093 if (rr == 0.0f) 0094 { 0095 return false; 0096 } 0097 0098 float32 s = b2Dot(q - v1, r) / rr; 0099 if (s < 0.0f || 1.0f < s) 0100 { 0101 return false; 0102 } 0103 0104 output->fraction = t; 0105 if (numerator > 0.0f) 0106 { 0107 output->normal = -b2Mul(xf.q, normal); 0108 } 0109 else 0110 { 0111 output->normal = b2Mul(xf.q, normal); 0112 } 0113 return true; 0114 } 0115 0116 void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const 0117 { 0118 B2_NOT_USED(childIndex); 0119 0120 b2Vec2 v1 = b2Mul(xf, m_vertex1); 0121 b2Vec2 v2 = b2Mul(xf, m_vertex2); 0122 0123 b2Vec2 lower = b2Min(v1, v2); 0124 b2Vec2 upper = b2Max(v1, v2); 0125 0126 b2Vec2 r(m_radius, m_radius); 0127 aabb->lowerBound = lower - r; 0128 aabb->upperBound = upper + r; 0129 } 0130 0131 void b2EdgeShape::ComputeMass(b2MassData* massData, float32 density) const 0132 { 0133 B2_NOT_USED(density); 0134 0135 massData->mass = 0.0f; 0136 massData->center = 0.5f * (m_vertex1 + m_vertex2); 0137 massData->I = 0.0f; 0138 }