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/b2LoopShape.h>
0020 #include <Box2D/Collision/Shapes/b2EdgeShape.h>
0021 #include <new>
0022 #include <cstring>
0023 using namespace std;
0024 
0025 b2LoopShape::~b2LoopShape()
0026 {
0027     b2Free(m_vertices);
0028     m_vertices = NULL;
0029     m_count = 0;
0030 }
0031 
0032 void b2LoopShape::Create(const b2Vec2* vertices, int32 count)
0033 {
0034     b2Assert(m_vertices == NULL && m_count == 0);
0035     b2Assert(count >= 2);
0036     m_count = count;
0037     m_vertices = (b2Vec2*)b2Alloc(count * sizeof(b2Vec2));
0038     memcpy(m_vertices, vertices, m_count * sizeof(b2Vec2));
0039 }
0040 
0041 b2Shape* b2LoopShape::Clone(b2BlockAllocator* allocator) const
0042 {
0043     void* mem = allocator->Allocate(sizeof(b2LoopShape));
0044     b2LoopShape* clone = new (mem) b2LoopShape;
0045     clone->Create(m_vertices, m_count);
0046     return clone;
0047 }
0048 
0049 int32 b2LoopShape::GetChildCount() const
0050 {
0051     return m_count;
0052 }
0053 
0054 void b2LoopShape::GetChildEdge(b2EdgeShape* edge, int32 index) const
0055 {
0056     b2Assert(2 <= m_count);
0057     b2Assert(0 <= index && index < m_count);
0058     edge->m_type = b2Shape::e_edge;
0059     edge->m_radius = m_radius;
0060     edge->m_hasVertex0 = true;
0061     edge->m_hasVertex3 = true;
0062 
0063     int32 i0 = index - 1 >= 0 ? index - 1 : m_count - 1;
0064     int32 i1 = index;
0065     int32 i2 = index + 1 < m_count ? index + 1 : 0;
0066     int32 i3 = index + 2;
0067     while (i3 >= m_count)
0068     {
0069         i3 -= m_count;
0070     }
0071 
0072     edge->m_vertex0 = m_vertices[i0];
0073     edge->m_vertex1 = m_vertices[i1];
0074     edge->m_vertex2 = m_vertices[i2];
0075     edge->m_vertex3 = m_vertices[i3];
0076 }
0077 
0078 bool b2LoopShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
0079 {
0080     B2_NOT_USED(xf);
0081     B2_NOT_USED(p);
0082     return false;
0083 }
0084 
0085 bool b2LoopShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
0086                             const b2Transform& xf, int32 childIndex) const
0087 {
0088     b2Assert(childIndex < m_count);
0089 
0090     b2EdgeShape edgeShape;
0091 
0092     int32 i1 = childIndex;
0093     int32 i2 = childIndex + 1;
0094     if (i2 == m_count)
0095     {
0096         i2 = 0;
0097     }
0098 
0099     edgeShape.m_vertex1 = m_vertices[i1];
0100     edgeShape.m_vertex2 = m_vertices[i2];
0101 
0102     return edgeShape.RayCast(output, input, xf, 0);
0103 }
0104 
0105 void b2LoopShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
0106 {
0107     b2Assert(childIndex < m_count);
0108 
0109     int32 i1 = childIndex;
0110     int32 i2 = childIndex + 1;
0111     if (i2 == m_count)
0112     {
0113         i2 = 0;
0114     }
0115 
0116     b2Vec2 v1 = b2Mul(xf, m_vertices[i1]);
0117     b2Vec2 v2 = b2Mul(xf, m_vertices[i2]);
0118 
0119     aabb->lowerBound = b2Min(v1, v2);
0120     aabb->upperBound = b2Max(v1, v2);
0121 }
0122 
0123 void b2LoopShape::ComputeMass(b2MassData* massData, qreal density) const
0124 {
0125     B2_NOT_USED(density);
0126 
0127     massData->mass = 0.0f;
0128     massData->center.SetZero();
0129     massData->I = 0.0f;
0130 }