diff options
author | chai <chaifix@163.com> | 2018-10-23 12:23:58 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-10-23 12:23:58 +0800 |
commit | 40fc27154fe754181934dc7ee31375e6bdfb33fc (patch) | |
tree | 897ad98d759bc308ef66561181ba88b85f2ccd47 /src | |
parent | 1480c9445100075c9e1a894eb07c0ef727b509a1 (diff) |
*merge from minimal
Diffstat (limited to 'src')
401 files changed, 13506 insertions, 34364 deletions
diff --git a/src/jinc.cpp b/src/jinc.cpp deleted file mode 100644 index 86744a1..0000000 --- a/src/jinc.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// luabinaryУɿִļ -#include <string> - -bool compile(std::string directory) -{ - return 0; -} diff --git a/src/libjin/3rdparty/Box2D/Box2D.h b/src/libjin/3rdparty/Box2D/Box2D.h deleted file mode 100644 index 28ae428..0000000 --- a/src/libjin/3rdparty/Box2D/Box2D.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef BOX2D_H -#define BOX2D_H - -/** -\mainpage Box2D API Documentation - -\section intro_sec Getting Started - -For documentation please see http://box2d.org/documentation.html - -For discussion please visit http://box2d.org/forum -*/ - -// These include files constitute the main Box2D API - -#include "Box2D/Common/b2Settings.h" -#include "Box2D/Common/b2Draw.h" -#include "Box2D/Common/b2Timer.h" - -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" - -#include "Box2D/Collision/b2BroadPhase.h" -#include "Box2D/Collision/b2Distance.h" -#include "Box2D/Collision/b2DynamicTree.h" -#include "Box2D/Collision/b2TimeOfImpact.h" - -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2WorldCallbacks.h" -#include "Box2D/Dynamics/b2TimeStep.h" -#include "Box2D/Dynamics/b2World.h" - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -#include "Box2D/Dynamics/Joints/b2DistanceJoint.h" -#include "Box2D/Dynamics/Joints/b2FrictionJoint.h" -#include "Box2D/Dynamics/Joints/b2GearJoint.h" -#include "Box2D/Dynamics/Joints/b2MotorJoint.h" -#include "Box2D/Dynamics/Joints/b2MouseJoint.h" -#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" -#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" -#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" -#include "Box2D/Dynamics/Joints/b2RopeJoint.h" -#include "Box2D/Dynamics/Joints/b2WeldJoint.h" -#include "Box2D/Dynamics/Joints/b2WheelJoint.h" - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2ChainShape.cpp b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2ChainShape.cpp deleted file mode 100644 index a709585..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2ChainShape.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include <new> -#include <string.h> - -b2ChainShape::~b2ChainShape() -{ - Clear(); -} - -void b2ChainShape::Clear() -{ - b2Free(m_vertices); - m_vertices = nullptr; - m_count = 0; -} - -void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count) -{ - b2Assert(m_vertices == nullptr && m_count == 0); - b2Assert(count >= 3); - if (count < 3) - { - return; - } - - for (int32 i = 1; i < count; ++i) - { - b2Vec2 v1 = vertices[i-1]; - b2Vec2 v2 = vertices[i]; - // If the code crashes here, it means your vertices are too close together. - b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop); - } - - m_count = count + 1; - m_vertices = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2)); - memcpy(m_vertices, vertices, count * sizeof(b2Vec2)); - m_vertices[count] = m_vertices[0]; - m_prevVertex = m_vertices[m_count - 2]; - m_nextVertex = m_vertices[1]; - m_hasPrevVertex = true; - m_hasNextVertex = true; -} - -void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 count) -{ - b2Assert(m_vertices == nullptr && m_count == 0); - b2Assert(count >= 2); - for (int32 i = 1; i < count; ++i) - { - // If the code crashes here, it means your vertices are too close together. - b2Assert(b2DistanceSquared(vertices[i-1], vertices[i]) > b2_linearSlop * b2_linearSlop); - } - - m_count = count; - m_vertices = (b2Vec2*)b2Alloc(count * sizeof(b2Vec2)); - memcpy(m_vertices, vertices, m_count * sizeof(b2Vec2)); - - m_hasPrevVertex = false; - m_hasNextVertex = false; - - m_prevVertex.SetZero(); - m_nextVertex.SetZero(); -} - -void b2ChainShape::SetPrevVertex(const b2Vec2& prevVertex) -{ - m_prevVertex = prevVertex; - m_hasPrevVertex = true; -} - -void b2ChainShape::SetNextVertex(const b2Vec2& nextVertex) -{ - m_nextVertex = nextVertex; - m_hasNextVertex = true; -} - -b2Shape* b2ChainShape::Clone(b2BlockAllocator* allocator) const -{ - void* mem = allocator->Allocate(sizeof(b2ChainShape)); - b2ChainShape* clone = new (mem) b2ChainShape; - clone->CreateChain(m_vertices, m_count); - clone->m_prevVertex = m_prevVertex; - clone->m_nextVertex = m_nextVertex; - clone->m_hasPrevVertex = m_hasPrevVertex; - clone->m_hasNextVertex = m_hasNextVertex; - return clone; -} - -int32 b2ChainShape::GetChildCount() const -{ - // edge count = vertex count - 1 - return m_count - 1; -} - -void b2ChainShape::GetChildEdge(b2EdgeShape* edge, int32 index) const -{ - b2Assert(0 <= index && index < m_count - 1); - edge->m_type = b2Shape::e_edge; - edge->m_radius = m_radius; - - edge->m_vertex1 = m_vertices[index + 0]; - edge->m_vertex2 = m_vertices[index + 1]; - - if (index > 0) - { - edge->m_vertex0 = m_vertices[index - 1]; - edge->m_hasVertex0 = true; - } - else - { - edge->m_vertex0 = m_prevVertex; - edge->m_hasVertex0 = m_hasPrevVertex; - } - - if (index < m_count - 2) - { - edge->m_vertex3 = m_vertices[index + 2]; - edge->m_hasVertex3 = true; - } - else - { - edge->m_vertex3 = m_nextVertex; - edge->m_hasVertex3 = m_hasNextVertex; - } -} - -bool b2ChainShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const -{ - B2_NOT_USED(xf); - B2_NOT_USED(p); - return false; -} - -bool b2ChainShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& xf, int32 childIndex) const -{ - b2Assert(childIndex < m_count); - - b2EdgeShape edgeShape; - - int32 i1 = childIndex; - int32 i2 = childIndex + 1; - if (i2 == m_count) - { - i2 = 0; - } - - edgeShape.m_vertex1 = m_vertices[i1]; - edgeShape.m_vertex2 = m_vertices[i2]; - - return edgeShape.RayCast(output, input, xf, 0); -} - -void b2ChainShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const -{ - b2Assert(childIndex < m_count); - - int32 i1 = childIndex; - int32 i2 = childIndex + 1; - if (i2 == m_count) - { - i2 = 0; - } - - b2Vec2 v1 = b2Mul(xf, m_vertices[i1]); - b2Vec2 v2 = b2Mul(xf, m_vertices[i2]); - - aabb->lowerBound = b2Min(v1, v2); - aabb->upperBound = b2Max(v1, v2); -} - -void b2ChainShape::ComputeMass(b2MassData* massData, float32 density) const -{ - B2_NOT_USED(density); - - massData->mass = 0.0f; - massData->center.SetZero(); - massData->I = 0.0f; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2ChainShape.h b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2ChainShape.h deleted file mode 100644 index 7c8c1a8..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2ChainShape.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CHAIN_SHAPE_H -#define B2_CHAIN_SHAPE_H - -#include "Box2D/Collision/Shapes/b2Shape.h" - -class b2EdgeShape; - -/// A chain shape is a free form sequence of line segments. -/// The chain has two-sided collision, so you can use inside and outside collision. -/// Therefore, you may use any winding order. -/// Since there may be many vertices, they are allocated using b2Alloc. -/// Connectivity information is used to create smooth collisions. -/// WARNING: The chain will not collide properly if there are self-intersections. -class b2ChainShape : public b2Shape -{ -public: - b2ChainShape(); - - /// The destructor frees the vertices using b2Free. - ~b2ChainShape(); - - /// Clear all data. - void Clear(); - - /// Create a loop. This automatically adjusts connectivity. - /// @param vertices an array of vertices, these are copied - /// @param count the vertex count - void CreateLoop(const b2Vec2* vertices, int32 count); - - /// Create a chain with isolated end vertices. - /// @param vertices an array of vertices, these are copied - /// @param count the vertex count - void CreateChain(const b2Vec2* vertices, int32 count); - - /// Establish connectivity to a vertex that precedes the first vertex. - /// Don't call this for loops. - void SetPrevVertex(const b2Vec2& prevVertex); - - /// Establish connectivity to a vertex that follows the last vertex. - /// Don't call this for loops. - void SetNextVertex(const b2Vec2& nextVertex); - - /// Implement b2Shape. Vertices are cloned using b2Alloc. - b2Shape* Clone(b2BlockAllocator* allocator) const override; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const override; - - /// Get a child edge. - void GetChildEdge(b2EdgeShape* edge, int32 index) const; - - /// This always return false. - /// @see b2Shape::TestPoint - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const override; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const override; - - /// Chains have zero mass. - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const override; - - /// The vertices. Owned by this class. - b2Vec2* m_vertices; - - /// The vertex count. - int32 m_count; - - b2Vec2 m_prevVertex, m_nextVertex; - bool m_hasPrevVertex, m_hasNextVertex; -}; - -inline b2ChainShape::b2ChainShape() -{ - m_type = e_chain; - m_radius = b2_polygonRadius; - m_vertices = nullptr; - m_count = 0; - m_hasPrevVertex = false; - m_hasNextVertex = false; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2CircleShape.cpp b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2CircleShape.cpp deleted file mode 100644 index fa24dc8..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2CircleShape.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include <new> - -b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const -{ - void* mem = allocator->Allocate(sizeof(b2CircleShape)); - b2CircleShape* clone = new (mem) b2CircleShape; - *clone = *this; - return clone; -} - -int32 b2CircleShape::GetChildCount() const -{ - return 1; -} - -bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const -{ - b2Vec2 center = transform.p + b2Mul(transform.q, m_p); - b2Vec2 d = p - center; - return b2Dot(d, d) <= m_radius * m_radius; -} - -// Collision Detection in Interactive 3D Environments by Gino van den Bergen -// From Section 3.1.2 -// x = s + a * r -// norm(x) = radius -bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const -{ - B2_NOT_USED(childIndex); - - b2Vec2 position = transform.p + b2Mul(transform.q, m_p); - b2Vec2 s = input.p1 - position; - float32 b = b2Dot(s, s) - m_radius * m_radius; - - // Solve quadratic equation. - b2Vec2 r = input.p2 - input.p1; - float32 c = b2Dot(s, r); - float32 rr = b2Dot(r, r); - float32 sigma = c * c - rr * b; - - // Check for negative discriminant and short segment. - if (sigma < 0.0f || rr < b2_epsilon) - { - return false; - } - - // Find the point of intersection of the line with the circle. - float32 a = -(c + b2Sqrt(sigma)); - - // Is the intersection point on the segment? - if (0.0f <= a && a <= input.maxFraction * rr) - { - a /= rr; - output->fraction = a; - output->normal = s + a * r; - output->normal.Normalize(); - return true; - } - - return false; -} - -void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const -{ - B2_NOT_USED(childIndex); - - b2Vec2 p = transform.p + b2Mul(transform.q, m_p); - aabb->lowerBound.Set(p.x - m_radius, p.y - m_radius); - aabb->upperBound.Set(p.x + m_radius, p.y + m_radius); -} - -void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const -{ - massData->mass = density * b2_pi * m_radius * m_radius; - massData->center = m_p; - - // inertia about the local origin - massData->I = massData->mass * (0.5f * m_radius * m_radius + b2Dot(m_p, m_p)); -} diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2CircleShape.h b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2CircleShape.h deleted file mode 100644 index d2c646e..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2CircleShape.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CIRCLE_SHAPE_H -#define B2_CIRCLE_SHAPE_H - -#include "Box2D/Collision/Shapes/b2Shape.h" - -/// A circle shape. -class b2CircleShape : public b2Shape -{ -public: - b2CircleShape(); - - /// Implement b2Shape. - b2Shape* Clone(b2BlockAllocator* allocator) const override; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const override; - - /// Implement b2Shape. - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const override; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const override; - - /// Position - b2Vec2 m_p; -}; - -inline b2CircleShape::b2CircleShape() -{ - m_type = e_circle; - m_radius = 0.0f; - m_p.SetZero(); -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2EdgeShape.cpp b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2EdgeShape.cpp deleted file mode 100644 index 7b8dd57..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2EdgeShape.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include <new> - -void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2) -{ - m_vertex1 = v1; - m_vertex2 = v2; - m_hasVertex0 = false; - m_hasVertex3 = false; -} - -b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const -{ - void* mem = allocator->Allocate(sizeof(b2EdgeShape)); - b2EdgeShape* clone = new (mem) b2EdgeShape; - *clone = *this; - return clone; -} - -int32 b2EdgeShape::GetChildCount() const -{ - return 1; -} - -bool b2EdgeShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const -{ - B2_NOT_USED(xf); - B2_NOT_USED(p); - return false; -} - -// p = p1 + t * d -// v = v1 + s * e -// p1 + t * d = v1 + s * e -// s * e - t * d = p1 - v1 -bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& xf, int32 childIndex) const -{ - B2_NOT_USED(childIndex); - - // Put the ray into the edge's frame of reference. - b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p); - b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p); - b2Vec2 d = p2 - p1; - - b2Vec2 v1 = m_vertex1; - b2Vec2 v2 = m_vertex2; - b2Vec2 e = v2 - v1; - b2Vec2 normal(e.y, -e.x); - normal.Normalize(); - - // q = p1 + t * d - // dot(normal, q - v1) = 0 - // dot(normal, p1 - v1) + t * dot(normal, d) = 0 - float32 numerator = b2Dot(normal, v1 - p1); - float32 denominator = b2Dot(normal, d); - - if (denominator == 0.0f) - { - return false; - } - - float32 t = numerator / denominator; - if (t < 0.0f || input.maxFraction < t) - { - return false; - } - - b2Vec2 q = p1 + t * d; - - // q = v1 + s * r - // s = dot(q - v1, r) / dot(r, r) - b2Vec2 r = v2 - v1; - float32 rr = b2Dot(r, r); - if (rr == 0.0f) - { - return false; - } - - float32 s = b2Dot(q - v1, r) / rr; - if (s < 0.0f || 1.0f < s) - { - return false; - } - - output->fraction = t; - if (numerator > 0.0f) - { - output->normal = -b2Mul(xf.q, normal); - } - else - { - output->normal = b2Mul(xf.q, normal); - } - return true; -} - -void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const -{ - B2_NOT_USED(childIndex); - - b2Vec2 v1 = b2Mul(xf, m_vertex1); - b2Vec2 v2 = b2Mul(xf, m_vertex2); - - b2Vec2 lower = b2Min(v1, v2); - b2Vec2 upper = b2Max(v1, v2); - - b2Vec2 r(m_radius, m_radius); - aabb->lowerBound = lower - r; - aabb->upperBound = upper + r; -} - -void b2EdgeShape::ComputeMass(b2MassData* massData, float32 density) const -{ - B2_NOT_USED(density); - - massData->mass = 0.0f; - massData->center = 0.5f * (m_vertex1 + m_vertex2); - massData->I = 0.0f; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2EdgeShape.h b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2EdgeShape.h deleted file mode 100644 index 63b1a56..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2EdgeShape.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_EDGE_SHAPE_H -#define B2_EDGE_SHAPE_H - -#include "Box2D/Collision/Shapes/b2Shape.h" - -/// A line segment (edge) shape. These can be connected in chains or loops -/// to other edge shapes. The connectivity information is used to ensure -/// correct contact normals. -class b2EdgeShape : public b2Shape -{ -public: - b2EdgeShape(); - - /// Set this as an isolated edge. - void Set(const b2Vec2& v1, const b2Vec2& v2); - - /// Implement b2Shape. - b2Shape* Clone(b2BlockAllocator* allocator) const override; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const override; - - /// @see b2Shape::TestPoint - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const override; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const override; - - /// These are the edge vertices - b2Vec2 m_vertex1, m_vertex2; - - /// Optional adjacent vertices. These are used for smooth collision. - b2Vec2 m_vertex0, m_vertex3; - bool m_hasVertex0, m_hasVertex3; -}; - -inline b2EdgeShape::b2EdgeShape() -{ - m_type = e_edge; - m_radius = b2_polygonRadius; - m_vertex0.x = 0.0f; - m_vertex0.y = 0.0f; - m_vertex3.x = 0.0f; - m_vertex3.y = 0.0f; - m_hasVertex0 = false; - m_hasVertex3 = false; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2PolygonShape.cpp b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2PolygonShape.cpp deleted file mode 100644 index 3c8c47d..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2PolygonShape.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/Shapes/b2PolygonShape.h" -#include <new> - -b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const -{ - void* mem = allocator->Allocate(sizeof(b2PolygonShape)); - b2PolygonShape* clone = new (mem) b2PolygonShape; - *clone = *this; - return clone; -} - -void b2PolygonShape::SetAsBox(float32 hx, float32 hy) -{ - m_count = 4; - m_vertices[0].Set(-hx, -hy); - m_vertices[1].Set( hx, -hy); - m_vertices[2].Set( hx, hy); - m_vertices[3].Set(-hx, hy); - m_normals[0].Set(0.0f, -1.0f); - m_normals[1].Set(1.0f, 0.0f); - m_normals[2].Set(0.0f, 1.0f); - m_normals[3].Set(-1.0f, 0.0f); - m_centroid.SetZero(); -} - -void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle) -{ - m_count = 4; - m_vertices[0].Set(-hx, -hy); - m_vertices[1].Set( hx, -hy); - m_vertices[2].Set( hx, hy); - m_vertices[3].Set(-hx, hy); - m_normals[0].Set(0.0f, -1.0f); - m_normals[1].Set(1.0f, 0.0f); - m_normals[2].Set(0.0f, 1.0f); - m_normals[3].Set(-1.0f, 0.0f); - m_centroid = center; - - b2Transform xf; - xf.p = center; - xf.q.Set(angle); - - // Transform vertices and normals. - for (int32 i = 0; i < m_count; ++i) - { - m_vertices[i] = b2Mul(xf, m_vertices[i]); - m_normals[i] = b2Mul(xf.q, m_normals[i]); - } -} - -int32 b2PolygonShape::GetChildCount() const -{ - return 1; -} - -static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count) -{ - b2Assert(count >= 3); - - b2Vec2 c; c.Set(0.0f, 0.0f); - float32 area = 0.0f; - - // pRef is the reference point for forming triangles. - // It's location doesn't change the result (except for rounding error). - b2Vec2 pRef(0.0f, 0.0f); -#if 0 - // This code would put the reference point inside the polygon. - for (int32 i = 0; i < count; ++i) - { - pRef += vs[i]; - } - pRef *= 1.0f / count; -#endif - - const float32 inv3 = 1.0f / 3.0f; - - for (int32 i = 0; i < count; ++i) - { - // Triangle vertices. - b2Vec2 p1 = pRef; - b2Vec2 p2 = vs[i]; - b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0]; - - b2Vec2 e1 = p2 - p1; - b2Vec2 e2 = p3 - p1; - - float32 D = b2Cross(e1, e2); - - float32 triangleArea = 0.5f * D; - area += triangleArea; - - // Area weighted centroid - c += triangleArea * inv3 * (p1 + p2 + p3); - } - - // Centroid - b2Assert(area > b2_epsilon); - c *= 1.0f / area; - return c; -} - -void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) -{ - b2Assert(3 <= count && count <= b2_maxPolygonVertices); - if (count < 3) - { - SetAsBox(1.0f, 1.0f); - return; - } - - int32 n = b2Min(count, b2_maxPolygonVertices); - - // Perform welding and copy vertices into local buffer. - b2Vec2 ps[b2_maxPolygonVertices]; - int32 tempCount = 0; - for (int32 i = 0; i < n; ++i) - { - b2Vec2 v = vertices[i]; - - bool unique = true; - for (int32 j = 0; j < tempCount; ++j) - { - if (b2DistanceSquared(v, ps[j]) < ((0.5f * b2_linearSlop) * (0.5f * b2_linearSlop))) - { - unique = false; - break; - } - } - - if (unique) - { - ps[tempCount++] = v; - } - } - - n = tempCount; - if (n < 3) - { - // Polygon is degenerate. - b2Assert(false); - SetAsBox(1.0f, 1.0f); - return; - } - - // Create the convex hull using the Gift wrapping algorithm - // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm - - // Find the right most point on the hull - int32 i0 = 0; - float32 x0 = ps[0].x; - for (int32 i = 1; i < n; ++i) - { - float32 x = ps[i].x; - if (x > x0 || (x == x0 && ps[i].y < ps[i0].y)) - { - i0 = i; - x0 = x; - } - } - - int32 hull[b2_maxPolygonVertices]; - int32 m = 0; - int32 ih = i0; - - for (;;) - { - b2Assert(m < b2_maxPolygonVertices); - hull[m] = ih; - - int32 ie = 0; - for (int32 j = 1; j < n; ++j) - { - if (ie == ih) - { - ie = j; - continue; - } - - b2Vec2 r = ps[ie] - ps[hull[m]]; - b2Vec2 v = ps[j] - ps[hull[m]]; - float32 c = b2Cross(r, v); - if (c < 0.0f) - { - ie = j; - } - - // Collinearity check - if (c == 0.0f && v.LengthSquared() > r.LengthSquared()) - { - ie = j; - } - } - - ++m; - ih = ie; - - if (ie == i0) - { - break; - } - } - - if (m < 3) - { - // Polygon is degenerate. - b2Assert(false); - SetAsBox(1.0f, 1.0f); - return; - } - - m_count = m; - - // Copy vertices. - for (int32 i = 0; i < m; ++i) - { - m_vertices[i] = ps[hull[i]]; - } - - // Compute normals. Ensure the edges have non-zero length. - for (int32 i = 0; i < m; ++i) - { - int32 i1 = i; - int32 i2 = i + 1 < m ? i + 1 : 0; - b2Vec2 edge = m_vertices[i2] - m_vertices[i1]; - b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon); - m_normals[i] = b2Cross(edge, 1.0f); - m_normals[i].Normalize(); - } - - // Compute the polygon centroid. - m_centroid = ComputeCentroid(m_vertices, m); -} - -bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const -{ - b2Vec2 pLocal = b2MulT(xf.q, p - xf.p); - - for (int32 i = 0; i < m_count; ++i) - { - float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]); - if (dot > 0.0f) - { - return false; - } - } - - return true; -} - -bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& xf, int32 childIndex) const -{ - B2_NOT_USED(childIndex); - - // Put the ray into the polygon's frame of reference. - b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p); - b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p); - b2Vec2 d = p2 - p1; - - float32 lower = 0.0f, upper = input.maxFraction; - - int32 index = -1; - - for (int32 i = 0; i < m_count; ++i) - { - // p = p1 + a * d - // dot(normal, p - v) = 0 - // dot(normal, p1 - v) + a * dot(normal, d) = 0 - float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1); - float32 denominator = b2Dot(m_normals[i], d); - - if (denominator == 0.0f) - { - if (numerator < 0.0f) - { - return false; - } - } - else - { - // Note: we want this predicate without division: - // lower < numerator / denominator, where denominator < 0 - // Since denominator < 0, we have to flip the inequality: - // lower < numerator / denominator <==> denominator * lower > numerator. - if (denominator < 0.0f && numerator < lower * denominator) - { - // Increase lower. - // The segment enters this half-space. - lower = numerator / denominator; - index = i; - } - else if (denominator > 0.0f && numerator < upper * denominator) - { - // Decrease upper. - // The segment exits this half-space. - upper = numerator / denominator; - } - } - - // The use of epsilon here causes the assert on lower to trip - // in some cases. Apparently the use of epsilon was to make edge - // shapes work, but now those are handled separately. - //if (upper < lower - b2_epsilon) - if (upper < lower) - { - return false; - } - } - - b2Assert(0.0f <= lower && lower <= input.maxFraction); - - if (index >= 0) - { - output->fraction = lower; - output->normal = b2Mul(xf.q, m_normals[index]); - return true; - } - - return false; -} - -void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const -{ - B2_NOT_USED(childIndex); - - b2Vec2 lower = b2Mul(xf, m_vertices[0]); - b2Vec2 upper = lower; - - for (int32 i = 1; i < m_count; ++i) - { - b2Vec2 v = b2Mul(xf, m_vertices[i]); - lower = b2Min(lower, v); - upper = b2Max(upper, v); - } - - b2Vec2 r(m_radius, m_radius); - aabb->lowerBound = lower - r; - aabb->upperBound = upper + r; -} - -void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const -{ - // Polygon mass, centroid, and inertia. - // Let rho be the polygon density in mass per unit area. - // Then: - // mass = rho * int(dA) - // centroid.x = (1/mass) * rho * int(x * dA) - // centroid.y = (1/mass) * rho * int(y * dA) - // I = rho * int((x*x + y*y) * dA) - // - // We can compute these integrals by summing all the integrals - // for each triangle of the polygon. To evaluate the integral - // for a single triangle, we make a change of variables to - // the (u,v) coordinates of the triangle: - // x = x0 + e1x * u + e2x * v - // y = y0 + e1y * u + e2y * v - // where 0 <= u && 0 <= v && u + v <= 1. - // - // We integrate u from [0,1-v] and then v from [0,1]. - // We also need to use the Jacobian of the transformation: - // D = cross(e1, e2) - // - // Simplification: triangle centroid = (1/3) * (p1 + p2 + p3) - // - // The rest of the derivation is handled by computer algebra. - - b2Assert(m_count >= 3); - - b2Vec2 center; center.Set(0.0f, 0.0f); - float32 area = 0.0f; - float32 I = 0.0f; - - // s is the reference point for forming triangles. - // It's location doesn't change the result (except for rounding error). - b2Vec2 s(0.0f, 0.0f); - - // This code would put the reference point inside the polygon. - for (int32 i = 0; i < m_count; ++i) - { - s += m_vertices[i]; - } - s *= 1.0f / m_count; - - const float32 k_inv3 = 1.0f / 3.0f; - - for (int32 i = 0; i < m_count; ++i) - { - // Triangle vertices. - b2Vec2 e1 = m_vertices[i] - s; - b2Vec2 e2 = i + 1 < m_count ? m_vertices[i+1] - s : m_vertices[0] - s; - - float32 D = b2Cross(e1, e2); - - float32 triangleArea = 0.5f * D; - area += triangleArea; - - // Area weighted centroid - center += triangleArea * k_inv3 * (e1 + e2); - - float32 ex1 = e1.x, ey1 = e1.y; - float32 ex2 = e2.x, ey2 = e2.y; - - float32 intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2; - float32 inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2; - - I += (0.25f * k_inv3 * D) * (intx2 + inty2); - } - - // Total mass - massData->mass = density * area; - - // Center of mass - b2Assert(area > b2_epsilon); - center *= 1.0f / area; - massData->center = center + s; - - // Inertia tensor relative to the local origin (point s). - massData->I = density * I; - - // Shift to center of mass then to original body origin. - massData->I += massData->mass * (b2Dot(massData->center, massData->center) - b2Dot(center, center)); -} - -bool b2PolygonShape::Validate() const -{ - for (int32 i = 0; i < m_count; ++i) - { - int32 i1 = i; - int32 i2 = i < m_count - 1 ? i1 + 1 : 0; - b2Vec2 p = m_vertices[i1]; - b2Vec2 e = m_vertices[i2] - p; - - for (int32 j = 0; j < m_count; ++j) - { - if (j == i1 || j == i2) - { - continue; - } - - b2Vec2 v = m_vertices[j] - p; - float32 c = b2Cross(e, v); - if (c < 0.0f) - { - return false; - } - } - } - - return true; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2PolygonShape.h b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2PolygonShape.h deleted file mode 100644 index 26c5e61..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2PolygonShape.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_POLYGON_SHAPE_H -#define B2_POLYGON_SHAPE_H - -#include "Box2D/Collision/Shapes/b2Shape.h" - -/// A convex polygon. It is assumed that the interior of the polygon is to -/// the left of each edge. -/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices. -/// In most cases you should not need many vertices for a convex polygon. -class b2PolygonShape : public b2Shape -{ -public: - b2PolygonShape(); - - /// Implement b2Shape. - b2Shape* Clone(b2BlockAllocator* allocator) const override; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const override; - - /// Create a convex hull from the given array of local points. - /// The count must be in the range [3, b2_maxPolygonVertices]. - /// @warning the points may be re-ordered, even if they form a convex polygon - /// @warning collinear points are handled but not removed. Collinear points - /// may lead to poor stacking behavior. - void Set(const b2Vec2* points, int32 count); - - /// Build vertices to represent an axis-aligned box centered on the local origin. - /// @param hx the half-width. - /// @param hy the half-height. - void SetAsBox(float32 hx, float32 hy); - - /// Build vertices to represent an oriented box. - /// @param hx the half-width. - /// @param hy the half-height. - /// @param center the center of the box in local coordinates. - /// @param angle the rotation of the box in local coordinates. - void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle); - - /// @see b2Shape::TestPoint - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const override; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const override; - - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const override; - - /// Validate convexity. This is a very time consuming operation. - /// @returns true if valid - bool Validate() const; - - b2Vec2 m_centroid; - b2Vec2 m_vertices[b2_maxPolygonVertices]; - b2Vec2 m_normals[b2_maxPolygonVertices]; - int32 m_count; -}; - -inline b2PolygonShape::b2PolygonShape() -{ - m_type = e_polygon; - m_radius = b2_polygonRadius; - m_count = 0; - m_centroid.SetZero(); -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2Shape.h b/src/libjin/3rdparty/Box2D/Collision/Shapes/b2Shape.h deleted file mode 100644 index 653e362..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/Shapes/b2Shape.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_SHAPE_H -#define B2_SHAPE_H - -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Common/b2Math.h" -#include "Box2D/Collision/b2Collision.h" - -/// This holds the mass data computed for a shape. -struct b2MassData -{ - /// The mass of the shape, usually in kilograms. - float32 mass; - - /// The position of the shape's centroid relative to the shape's origin. - b2Vec2 center; - - /// The rotational inertia of the shape about the local origin. - float32 I; -}; - -/// A shape is used for collision detection. You can create a shape however you like. -/// Shapes used for simulation in b2World are created automatically when a b2Fixture -/// is created. Shapes may encapsulate a one or more child shapes. -class b2Shape -{ -public: - - enum Type - { - e_circle = 0, - e_edge = 1, - e_polygon = 2, - e_chain = 3, - e_typeCount = 4 - }; - - virtual ~b2Shape() {} - - /// Clone the concrete shape using the provided allocator. - virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0; - - /// Get the type of this shape. You can use this to down cast to the concrete shape. - /// @return the shape type. - Type GetType() const; - - /// Get the number of child primitives. - virtual int32 GetChildCount() const = 0; - - /// Test a point for containment in this shape. This only works for convex shapes. - /// @param xf the shape world transform. - /// @param p a point in world coordinates. - virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0; - - /// Cast a ray against a child shape. - /// @param output the ray-cast results. - /// @param input the ray-cast input parameters. - /// @param transform the transform to be applied to the shape. - /// @param childIndex the child shape index - virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const = 0; - - /// Given a transform, compute the associated axis aligned bounding box for a child shape. - /// @param aabb returns the axis aligned box. - /// @param xf the world transform of the shape. - /// @param childIndex the child shape - virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const = 0; - - /// Compute the mass properties of this shape using its dimensions and density. - /// The inertia tensor is computed about the local origin. - /// @param massData returns the mass data for this shape. - /// @param density the density in kilograms per meter squared. - virtual void ComputeMass(b2MassData* massData, float32 density) const = 0; - - Type m_type; - - /// Radius of a shape. For polygonal shapes this must be b2_polygonRadius. There is no support for - /// making rounded polygons. - float32 m_radius; -}; - -inline b2Shape::Type b2Shape::GetType() const -{ - return m_type; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/b2BroadPhase.cpp b/src/libjin/3rdparty/Box2D/Collision/b2BroadPhase.cpp deleted file mode 100644 index e96339d..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2BroadPhase.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2BroadPhase.h" - -b2BroadPhase::b2BroadPhase() -{ - m_proxyCount = 0; - - m_pairCapacity = 16; - m_pairCount = 0; - m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); - - m_moveCapacity = 16; - m_moveCount = 0; - m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32)); -} - -b2BroadPhase::~b2BroadPhase() -{ - b2Free(m_moveBuffer); - b2Free(m_pairBuffer); -} - -int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData) -{ - int32 proxyId = m_tree.CreateProxy(aabb, userData); - ++m_proxyCount; - BufferMove(proxyId); - return proxyId; -} - -void b2BroadPhase::DestroyProxy(int32 proxyId) -{ - UnBufferMove(proxyId); - --m_proxyCount; - m_tree.DestroyProxy(proxyId); -} - -void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement) -{ - bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement); - if (buffer) - { - BufferMove(proxyId); - } -} - -void b2BroadPhase::TouchProxy(int32 proxyId) -{ - BufferMove(proxyId); -} - -void b2BroadPhase::BufferMove(int32 proxyId) -{ - if (m_moveCount == m_moveCapacity) - { - int32* oldBuffer = m_moveBuffer; - m_moveCapacity *= 2; - m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32)); - memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32)); - b2Free(oldBuffer); - } - - m_moveBuffer[m_moveCount] = proxyId; - ++m_moveCount; -} - -void b2BroadPhase::UnBufferMove(int32 proxyId) -{ - for (int32 i = 0; i < m_moveCount; ++i) - { - if (m_moveBuffer[i] == proxyId) - { - m_moveBuffer[i] = e_nullProxy; - } - } -} - -// This is called from b2DynamicTree::Query when we are gathering pairs. -bool b2BroadPhase::QueryCallback(int32 proxyId) -{ - // A proxy cannot form a pair with itself. - if (proxyId == m_queryProxyId) - { - return true; - } - - // Grow the pair buffer as needed. - if (m_pairCount == m_pairCapacity) - { - b2Pair* oldBuffer = m_pairBuffer; - m_pairCapacity *= 2; - m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); - memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair)); - b2Free(oldBuffer); - } - - m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId); - m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId); - ++m_pairCount; - - return true; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2BroadPhase.h b/src/libjin/3rdparty/Box2D/Collision/b2BroadPhase.h deleted file mode 100644 index d2965ed..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2BroadPhase.h +++ /dev/null @@ -1,257 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_BROAD_PHASE_H -#define B2_BROAD_PHASE_H - -#include "Box2D/Common/b2Settings.h" -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/b2DynamicTree.h" -#include <algorithm> - -struct b2Pair -{ - int32 proxyIdA; - int32 proxyIdB; -}; - -/// The broad-phase is used for computing pairs and performing volume queries and ray casts. -/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs. -/// It is up to the client to consume the new pairs and to track subsequent overlap. -class b2BroadPhase -{ -public: - - enum - { - e_nullProxy = -1 - }; - - b2BroadPhase(); - ~b2BroadPhase(); - - /// Create a proxy with an initial AABB. Pairs are not reported until - /// UpdatePairs is called. - int32 CreateProxy(const b2AABB& aabb, void* userData); - - /// Destroy a proxy. It is up to the client to remove any pairs. - void DestroyProxy(int32 proxyId); - - /// Call MoveProxy as many times as you like, then when you are done - /// call UpdatePairs to finalized the proxy pairs (for your time step). - void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement); - - /// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs. - void TouchProxy(int32 proxyId); - - /// Get the fat AABB for a proxy. - const b2AABB& GetFatAABB(int32 proxyId) const; - - /// Get user data from a proxy. Returns nullptr if the id is invalid. - void* GetUserData(int32 proxyId) const; - - /// Test overlap of fat AABBs. - bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const; - - /// Get the number of proxies. - int32 GetProxyCount() const; - - /// Update the pairs. This results in pair callbacks. This can only add pairs. - template <typename T> - void UpdatePairs(T* callback); - - /// Query an AABB for overlapping proxies. The callback class - /// is called for each proxy that overlaps the supplied AABB. - template <typename T> - void Query(T* callback, const b2AABB& aabb) const; - - /// Ray-cast against the proxies in the tree. This relies on the callback - /// to perform a exact ray-cast in the case were the proxy contains a shape. - /// The callback also performs the any collision filtering. This has performance - /// roughly equal to k * log(n), where k is the number of collisions and n is the - /// number of proxies in the tree. - /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). - /// @param callback a callback class that is called for each proxy that is hit by the ray. - template <typename T> - void RayCast(T* callback, const b2RayCastInput& input) const; - - /// Get the height of the embedded tree. - int32 GetTreeHeight() const; - - /// Get the balance of the embedded tree. - int32 GetTreeBalance() const; - - /// Get the quality metric of the embedded tree. - float32 GetTreeQuality() const; - - /// Shift the world origin. Useful for large worlds. - /// The shift formula is: position -= newOrigin - /// @param newOrigin the new origin with respect to the old origin - void ShiftOrigin(const b2Vec2& newOrigin); - -private: - - friend class b2DynamicTree; - - void BufferMove(int32 proxyId); - void UnBufferMove(int32 proxyId); - - bool QueryCallback(int32 proxyId); - - b2DynamicTree m_tree; - - int32 m_proxyCount; - - int32* m_moveBuffer; - int32 m_moveCapacity; - int32 m_moveCount; - - b2Pair* m_pairBuffer; - int32 m_pairCapacity; - int32 m_pairCount; - - int32 m_queryProxyId; -}; - -/// This is used to sort pairs. -inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2) -{ - if (pair1.proxyIdA < pair2.proxyIdA) - { - return true; - } - - if (pair1.proxyIdA == pair2.proxyIdA) - { - return pair1.proxyIdB < pair2.proxyIdB; - } - - return false; -} - -inline void* b2BroadPhase::GetUserData(int32 proxyId) const -{ - return m_tree.GetUserData(proxyId); -} - -inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const -{ - const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA); - const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB); - return b2TestOverlap(aabbA, aabbB); -} - -inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const -{ - return m_tree.GetFatAABB(proxyId); -} - -inline int32 b2BroadPhase::GetProxyCount() const -{ - return m_proxyCount; -} - -inline int32 b2BroadPhase::GetTreeHeight() const -{ - return m_tree.GetHeight(); -} - -inline int32 b2BroadPhase::GetTreeBalance() const -{ - return m_tree.GetMaxBalance(); -} - -inline float32 b2BroadPhase::GetTreeQuality() const -{ - return m_tree.GetAreaRatio(); -} - -template <typename T> -void b2BroadPhase::UpdatePairs(T* callback) -{ - // Reset pair buffer - m_pairCount = 0; - - // Perform tree queries for all moving proxies. - for (int32 i = 0; i < m_moveCount; ++i) - { - m_queryProxyId = m_moveBuffer[i]; - if (m_queryProxyId == e_nullProxy) - { - continue; - } - - // We have to query the tree with the fat AABB so that - // we don't fail to create a pair that may touch later. - const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId); - - // Query tree, create pairs and add them pair buffer. - m_tree.Query(this, fatAABB); - } - - // Reset move buffer - m_moveCount = 0; - - // Sort the pair buffer to expose duplicates. - std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan); - - // Send the pairs back to the client. - int32 i = 0; - while (i < m_pairCount) - { - b2Pair* primaryPair = m_pairBuffer + i; - void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA); - void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB); - - callback->AddPair(userDataA, userDataB); - ++i; - - // Skip any duplicate pairs. - while (i < m_pairCount) - { - b2Pair* pair = m_pairBuffer + i; - if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB) - { - break; - } - ++i; - } - } - - // Try to keep the tree balanced. - //m_tree.Rebalance(4); -} - -template <typename T> -inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const -{ - m_tree.Query(callback, aabb); -} - -template <typename T> -inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const -{ - m_tree.RayCast(callback, input); -} - -inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin) -{ - m_tree.ShiftOrigin(newOrigin); -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/b2CollideCircle.cpp b/src/libjin/3rdparty/Box2D/Collision/b2CollideCircle.cpp deleted file mode 100644 index f39f057..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2CollideCircle.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* -* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" - -void b2CollideCircles( - b2Manifold* manifold, - const b2CircleShape* circleA, const b2Transform& xfA, - const b2CircleShape* circleB, const b2Transform& xfB) -{ - manifold->pointCount = 0; - - b2Vec2 pA = b2Mul(xfA, circleA->m_p); - b2Vec2 pB = b2Mul(xfB, circleB->m_p); - - b2Vec2 d = pB - pA; - float32 distSqr = b2Dot(d, d); - float32 rA = circleA->m_radius, rB = circleB->m_radius; - float32 radius = rA + rB; - if (distSqr > radius * radius) - { - return; - } - - manifold->type = b2Manifold::e_circles; - manifold->localPoint = circleA->m_p; - manifold->localNormal.SetZero(); - manifold->pointCount = 1; - - manifold->points[0].localPoint = circleB->m_p; - manifold->points[0].id.key = 0; -} - -void b2CollidePolygonAndCircle( - b2Manifold* manifold, - const b2PolygonShape* polygonA, const b2Transform& xfA, - const b2CircleShape* circleB, const b2Transform& xfB) -{ - manifold->pointCount = 0; - - // Compute circle position in the frame of the polygon. - b2Vec2 c = b2Mul(xfB, circleB->m_p); - b2Vec2 cLocal = b2MulT(xfA, c); - - // Find the min separating edge. - int32 normalIndex = 0; - float32 separation = -b2_maxFloat; - float32 radius = polygonA->m_radius + circleB->m_radius; - int32 vertexCount = polygonA->m_count; - const b2Vec2* vertices = polygonA->m_vertices; - const b2Vec2* normals = polygonA->m_normals; - - for (int32 i = 0; i < vertexCount; ++i) - { - float32 s = b2Dot(normals[i], cLocal - vertices[i]); - - if (s > radius) - { - // Early out. - return; - } - - if (s > separation) - { - separation = s; - normalIndex = i; - } - } - - // Vertices that subtend the incident face. - int32 vertIndex1 = normalIndex; - int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0; - b2Vec2 v1 = vertices[vertIndex1]; - b2Vec2 v2 = vertices[vertIndex2]; - - // If the center is inside the polygon ... - if (separation < b2_epsilon) - { - manifold->pointCount = 1; - manifold->type = b2Manifold::e_faceA; - manifold->localNormal = normals[normalIndex]; - manifold->localPoint = 0.5f * (v1 + v2); - manifold->points[0].localPoint = circleB->m_p; - manifold->points[0].id.key = 0; - return; - } - - // Compute barycentric coordinates - float32 u1 = b2Dot(cLocal - v1, v2 - v1); - float32 u2 = b2Dot(cLocal - v2, v1 - v2); - if (u1 <= 0.0f) - { - if (b2DistanceSquared(cLocal, v1) > radius * radius) - { - return; - } - - manifold->pointCount = 1; - manifold->type = b2Manifold::e_faceA; - manifold->localNormal = cLocal - v1; - manifold->localNormal.Normalize(); - manifold->localPoint = v1; - manifold->points[0].localPoint = circleB->m_p; - manifold->points[0].id.key = 0; - } - else if (u2 <= 0.0f) - { - if (b2DistanceSquared(cLocal, v2) > radius * radius) - { - return; - } - - manifold->pointCount = 1; - manifold->type = b2Manifold::e_faceA; - manifold->localNormal = cLocal - v2; - manifold->localNormal.Normalize(); - manifold->localPoint = v2; - manifold->points[0].localPoint = circleB->m_p; - manifold->points[0].id.key = 0; - } - else - { - b2Vec2 faceCenter = 0.5f * (v1 + v2); - float32 s = b2Dot(cLocal - faceCenter, normals[vertIndex1]); - if (s > radius) - { - return; - } - - manifold->pointCount = 1; - manifold->type = b2Manifold::e_faceA; - manifold->localNormal = normals[vertIndex1]; - manifold->localPoint = faceCenter; - manifold->points[0].localPoint = circleB->m_p; - manifold->points[0].id.key = 0; - } -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2CollideEdge.cpp b/src/libjin/3rdparty/Box2D/Collision/b2CollideEdge.cpp deleted file mode 100644 index 793d714..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2CollideEdge.cpp +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Copyright (c) 2007-2009 Erin Catto http://www.box2d.org - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" - - -// Compute contact points for edge versus circle. -// This accounts for edge connectivity. -void b2CollideEdgeAndCircle(b2Manifold* manifold, - const b2EdgeShape* edgeA, const b2Transform& xfA, - const b2CircleShape* circleB, const b2Transform& xfB) -{ - manifold->pointCount = 0; - - // Compute circle in frame of edge - b2Vec2 Q = b2MulT(xfA, b2Mul(xfB, circleB->m_p)); - - b2Vec2 A = edgeA->m_vertex1, B = edgeA->m_vertex2; - b2Vec2 e = B - A; - - // Barycentric coordinates - float32 u = b2Dot(e, B - Q); - float32 v = b2Dot(e, Q - A); - - float32 radius = edgeA->m_radius + circleB->m_radius; - - b2ContactFeature cf; - cf.indexB = 0; - cf.typeB = b2ContactFeature::e_vertex; - - // Region A - if (v <= 0.0f) - { - b2Vec2 P = A; - b2Vec2 d = Q - P; - float32 dd = b2Dot(d, d); - if (dd > radius * radius) - { - return; - } - - // Is there an edge connected to A? - if (edgeA->m_hasVertex0) - { - b2Vec2 A1 = edgeA->m_vertex0; - b2Vec2 B1 = A; - b2Vec2 e1 = B1 - A1; - float32 u1 = b2Dot(e1, B1 - Q); - - // Is the circle in Region AB of the previous edge? - if (u1 > 0.0f) - { - return; - } - } - - cf.indexA = 0; - cf.typeA = b2ContactFeature::e_vertex; - manifold->pointCount = 1; - manifold->type = b2Manifold::e_circles; - manifold->localNormal.SetZero(); - manifold->localPoint = P; - manifold->points[0].id.key = 0; - manifold->points[0].id.cf = cf; - manifold->points[0].localPoint = circleB->m_p; - return; - } - - // Region B - if (u <= 0.0f) - { - b2Vec2 P = B; - b2Vec2 d = Q - P; - float32 dd = b2Dot(d, d); - if (dd > radius * radius) - { - return; - } - - // Is there an edge connected to B? - if (edgeA->m_hasVertex3) - { - b2Vec2 B2 = edgeA->m_vertex3; - b2Vec2 A2 = B; - b2Vec2 e2 = B2 - A2; - float32 v2 = b2Dot(e2, Q - A2); - - // Is the circle in Region AB of the next edge? - if (v2 > 0.0f) - { - return; - } - } - - cf.indexA = 1; - cf.typeA = b2ContactFeature::e_vertex; - manifold->pointCount = 1; - manifold->type = b2Manifold::e_circles; - manifold->localNormal.SetZero(); - manifold->localPoint = P; - manifold->points[0].id.key = 0; - manifold->points[0].id.cf = cf; - manifold->points[0].localPoint = circleB->m_p; - return; - } - - // Region AB - float32 den = b2Dot(e, e); - b2Assert(den > 0.0f); - b2Vec2 P = (1.0f / den) * (u * A + v * B); - b2Vec2 d = Q - P; - float32 dd = b2Dot(d, d); - if (dd > radius * radius) - { - return; - } - - b2Vec2 n(-e.y, e.x); - if (b2Dot(n, Q - A) < 0.0f) - { - n.Set(-n.x, -n.y); - } - n.Normalize(); - - cf.indexA = 0; - cf.typeA = b2ContactFeature::e_face; - manifold->pointCount = 1; - manifold->type = b2Manifold::e_faceA; - manifold->localNormal = n; - manifold->localPoint = A; - manifold->points[0].id.key = 0; - manifold->points[0].id.cf = cf; - manifold->points[0].localPoint = circleB->m_p; -} - -// This structure is used to keep track of the best separating axis. -struct b2EPAxis -{ - enum Type - { - e_unknown, - e_edgeA, - e_edgeB - }; - - Type type; - int32 index; - float32 separation; -}; - -// This holds polygon B expressed in frame A. -struct b2TempPolygon -{ - b2Vec2 vertices[b2_maxPolygonVertices]; - b2Vec2 normals[b2_maxPolygonVertices]; - int32 count; -}; - -// Reference face used for clipping -struct b2ReferenceFace -{ - int32 i1, i2; - - b2Vec2 v1, v2; - - b2Vec2 normal; - - b2Vec2 sideNormal1; - float32 sideOffset1; - - b2Vec2 sideNormal2; - float32 sideOffset2; -}; - -// This class collides and edge and a polygon, taking into account edge adjacency. -struct b2EPCollider -{ - void Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA, - const b2PolygonShape* polygonB, const b2Transform& xfB); - b2EPAxis ComputeEdgeSeparation(); - b2EPAxis ComputePolygonSeparation(); - - enum VertexType - { - e_isolated, - e_concave, - e_convex - }; - - b2TempPolygon m_polygonB; - - b2Transform m_xf; - b2Vec2 m_centroidB; - b2Vec2 m_v0, m_v1, m_v2, m_v3; - b2Vec2 m_normal0, m_normal1, m_normal2; - b2Vec2 m_normal; - VertexType m_type1, m_type2; - b2Vec2 m_lowerLimit, m_upperLimit; - float32 m_radius; - bool m_front; -}; - -// Algorithm: -// 1. Classify v1 and v2 -// 2. Classify polygon centroid as front or back -// 3. Flip normal if necessary -// 4. Initialize normal range to [-pi, pi] about face normal -// 5. Adjust normal range according to adjacent edges -// 6. Visit each separating axes, only accept axes within the range -// 7. Return if _any_ axis indicates separation -// 8. Clip -void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA, - const b2PolygonShape* polygonB, const b2Transform& xfB) -{ - m_xf = b2MulT(xfA, xfB); - - m_centroidB = b2Mul(m_xf, polygonB->m_centroid); - - m_v0 = edgeA->m_vertex0; - m_v1 = edgeA->m_vertex1; - m_v2 = edgeA->m_vertex2; - m_v3 = edgeA->m_vertex3; - - bool hasVertex0 = edgeA->m_hasVertex0; - bool hasVertex3 = edgeA->m_hasVertex3; - - b2Vec2 edge1 = m_v2 - m_v1; - edge1.Normalize(); - m_normal1.Set(edge1.y, -edge1.x); - float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1); - float32 offset0 = 0.0f, offset2 = 0.0f; - bool convex1 = false, convex2 = false; - - // Is there a preceding edge? - if (hasVertex0) - { - b2Vec2 edge0 = m_v1 - m_v0; - edge0.Normalize(); - m_normal0.Set(edge0.y, -edge0.x); - convex1 = b2Cross(edge0, edge1) >= 0.0f; - offset0 = b2Dot(m_normal0, m_centroidB - m_v0); - } - - // Is there a following edge? - if (hasVertex3) - { - b2Vec2 edge2 = m_v3 - m_v2; - edge2.Normalize(); - m_normal2.Set(edge2.y, -edge2.x); - convex2 = b2Cross(edge1, edge2) > 0.0f; - offset2 = b2Dot(m_normal2, m_centroidB - m_v2); - } - - // Determine front or back collision. Determine collision normal limits. - if (hasVertex0 && hasVertex3) - { - if (convex1 && convex2) - { - m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = m_normal0; - m_upperLimit = m_normal2; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = -m_normal1; - m_upperLimit = -m_normal1; - } - } - else if (convex1) - { - m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f); - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = m_normal0; - m_upperLimit = m_normal1; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = -m_normal2; - m_upperLimit = -m_normal1; - } - } - else if (convex2) - { - m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f); - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = m_normal1; - m_upperLimit = m_normal2; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = -m_normal1; - m_upperLimit = -m_normal0; - } - } - else - { - m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = m_normal1; - m_upperLimit = m_normal1; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = -m_normal2; - m_upperLimit = -m_normal0; - } - } - } - else if (hasVertex0) - { - if (convex1) - { - m_front = offset0 >= 0.0f || offset1 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = m_normal0; - m_upperLimit = -m_normal1; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = m_normal1; - m_upperLimit = -m_normal1; - } - } - else - { - m_front = offset0 >= 0.0f && offset1 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = m_normal1; - m_upperLimit = -m_normal1; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = m_normal1; - m_upperLimit = -m_normal0; - } - } - } - else if (hasVertex3) - { - if (convex2) - { - m_front = offset1 >= 0.0f || offset2 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = -m_normal1; - m_upperLimit = m_normal2; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = -m_normal1; - m_upperLimit = m_normal1; - } - } - else - { - m_front = offset1 >= 0.0f && offset2 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = -m_normal1; - m_upperLimit = m_normal1; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = -m_normal2; - m_upperLimit = m_normal1; - } - } - } - else - { - m_front = offset1 >= 0.0f; - if (m_front) - { - m_normal = m_normal1; - m_lowerLimit = -m_normal1; - m_upperLimit = -m_normal1; - } - else - { - m_normal = -m_normal1; - m_lowerLimit = m_normal1; - m_upperLimit = m_normal1; - } - } - - // Get polygonB in frameA - m_polygonB.count = polygonB->m_count; - for (int32 i = 0; i < polygonB->m_count; ++i) - { - m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]); - m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]); - } - - m_radius = polygonB->m_radius + edgeA->m_radius; - - manifold->pointCount = 0; - - b2EPAxis edgeAxis = ComputeEdgeSeparation(); - - // If no valid normal can be found than this edge should not collide. - if (edgeAxis.type == b2EPAxis::e_unknown) - { - return; - } - - if (edgeAxis.separation > m_radius) - { - return; - } - - b2EPAxis polygonAxis = ComputePolygonSeparation(); - if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius) - { - return; - } - - // Use hysteresis for jitter reduction. - const float32 k_relativeTol = 0.98f; - const float32 k_absoluteTol = 0.001f; - - b2EPAxis primaryAxis; - if (polygonAxis.type == b2EPAxis::e_unknown) - { - primaryAxis = edgeAxis; - } - else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol) - { - primaryAxis = polygonAxis; - } - else - { - primaryAxis = edgeAxis; - } - - b2ClipVertex ie[2]; - b2ReferenceFace rf; - if (primaryAxis.type == b2EPAxis::e_edgeA) - { - manifold->type = b2Manifold::e_faceA; - - // Search for the polygon normal that is most anti-parallel to the edge normal. - int32 bestIndex = 0; - float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]); - for (int32 i = 1; i < m_polygonB.count; ++i) - { - float32 value = b2Dot(m_normal, m_polygonB.normals[i]); - if (value < bestValue) - { - bestValue = value; - bestIndex = i; - } - } - - int32 i1 = bestIndex; - int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0; - - ie[0].v = m_polygonB.vertices[i1]; - ie[0].id.cf.indexA = 0; - ie[0].id.cf.indexB = static_cast<uint8>(i1); - ie[0].id.cf.typeA = b2ContactFeature::e_face; - ie[0].id.cf.typeB = b2ContactFeature::e_vertex; - - ie[1].v = m_polygonB.vertices[i2]; - ie[1].id.cf.indexA = 0; - ie[1].id.cf.indexB = static_cast<uint8>(i2); - ie[1].id.cf.typeA = b2ContactFeature::e_face; - ie[1].id.cf.typeB = b2ContactFeature::e_vertex; - - if (m_front) - { - rf.i1 = 0; - rf.i2 = 1; - rf.v1 = m_v1; - rf.v2 = m_v2; - rf.normal = m_normal1; - } - else - { - rf.i1 = 1; - rf.i2 = 0; - rf.v1 = m_v2; - rf.v2 = m_v1; - rf.normal = -m_normal1; - } - } - else - { - manifold->type = b2Manifold::e_faceB; - - ie[0].v = m_v1; - ie[0].id.cf.indexA = 0; - ie[0].id.cf.indexB = static_cast<uint8>(primaryAxis.index); - ie[0].id.cf.typeA = b2ContactFeature::e_vertex; - ie[0].id.cf.typeB = b2ContactFeature::e_face; - - ie[1].v = m_v2; - ie[1].id.cf.indexA = 0; - ie[1].id.cf.indexB = static_cast<uint8>(primaryAxis.index); - ie[1].id.cf.typeA = b2ContactFeature::e_vertex; - ie[1].id.cf.typeB = b2ContactFeature::e_face; - - rf.i1 = primaryAxis.index; - rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0; - rf.v1 = m_polygonB.vertices[rf.i1]; - rf.v2 = m_polygonB.vertices[rf.i2]; - rf.normal = m_polygonB.normals[rf.i1]; - } - - rf.sideNormal1.Set(rf.normal.y, -rf.normal.x); - rf.sideNormal2 = -rf.sideNormal1; - rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1); - rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2); - - // Clip incident edge against extruded edge1 side edges. - b2ClipVertex clipPoints1[2]; - b2ClipVertex clipPoints2[2]; - int32 np; - - // Clip to box side 1 - np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1); - - if (np < b2_maxManifoldPoints) - { - return; - } - - // Clip to negative box side 1 - np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2); - - if (np < b2_maxManifoldPoints) - { - return; - } - - // Now clipPoints2 contains the clipped points. - if (primaryAxis.type == b2EPAxis::e_edgeA) - { - manifold->localNormal = rf.normal; - manifold->localPoint = rf.v1; - } - else - { - manifold->localNormal = polygonB->m_normals[rf.i1]; - manifold->localPoint = polygonB->m_vertices[rf.i1]; - } - - int32 pointCount = 0; - for (int32 i = 0; i < b2_maxManifoldPoints; ++i) - { - float32 separation; - - separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1); - - if (separation <= m_radius) - { - b2ManifoldPoint* cp = manifold->points + pointCount; - - if (primaryAxis.type == b2EPAxis::e_edgeA) - { - cp->localPoint = b2MulT(m_xf, clipPoints2[i].v); - cp->id = clipPoints2[i].id; - } - else - { - cp->localPoint = clipPoints2[i].v; - cp->id.cf.typeA = clipPoints2[i].id.cf.typeB; - cp->id.cf.typeB = clipPoints2[i].id.cf.typeA; - cp->id.cf.indexA = clipPoints2[i].id.cf.indexB; - cp->id.cf.indexB = clipPoints2[i].id.cf.indexA; - } - - ++pointCount; - } - } - - manifold->pointCount = pointCount; -} - -b2EPAxis b2EPCollider::ComputeEdgeSeparation() -{ - b2EPAxis axis; - axis.type = b2EPAxis::e_edgeA; - axis.index = m_front ? 0 : 1; - axis.separation = FLT_MAX; - - for (int32 i = 0; i < m_polygonB.count; ++i) - { - float32 s = b2Dot(m_normal, m_polygonB.vertices[i] - m_v1); - if (s < axis.separation) - { - axis.separation = s; - } - } - - return axis; -} - -b2EPAxis b2EPCollider::ComputePolygonSeparation() -{ - b2EPAxis axis; - axis.type = b2EPAxis::e_unknown; - axis.index = -1; - axis.separation = -FLT_MAX; - - b2Vec2 perp(-m_normal.y, m_normal.x); - - for (int32 i = 0; i < m_polygonB.count; ++i) - { - b2Vec2 n = -m_polygonB.normals[i]; - - float32 s1 = b2Dot(n, m_polygonB.vertices[i] - m_v1); - float32 s2 = b2Dot(n, m_polygonB.vertices[i] - m_v2); - float32 s = b2Min(s1, s2); - - if (s > m_radius) - { - // No collision - axis.type = b2EPAxis::e_edgeB; - axis.index = i; - axis.separation = s; - return axis; - } - - // Adjacency - if (b2Dot(n, perp) >= 0.0f) - { - if (b2Dot(n - m_upperLimit, m_normal) < -b2_angularSlop) - { - continue; - } - } - else - { - if (b2Dot(n - m_lowerLimit, m_normal) < -b2_angularSlop) - { - continue; - } - } - - if (s > axis.separation) - { - axis.type = b2EPAxis::e_edgeB; - axis.index = i; - axis.separation = s; - } - } - - return axis; -} - -void b2CollideEdgeAndPolygon( b2Manifold* manifold, - const b2EdgeShape* edgeA, const b2Transform& xfA, - const b2PolygonShape* polygonB, const b2Transform& xfB) -{ - b2EPCollider collider; - collider.Collide(manifold, edgeA, xfA, polygonB, xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2CollidePolygon.cpp b/src/libjin/3rdparty/Box2D/Collision/b2CollidePolygon.cpp deleted file mode 100644 index 10211e7..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2CollidePolygon.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" - -// Find the max separation between poly1 and poly2 using edge normals from poly1. -static float32 b2FindMaxSeparation(int32* edgeIndex, - const b2PolygonShape* poly1, const b2Transform& xf1, - const b2PolygonShape* poly2, const b2Transform& xf2) -{ - int32 count1 = poly1->m_count; - int32 count2 = poly2->m_count; - const b2Vec2* n1s = poly1->m_normals; - const b2Vec2* v1s = poly1->m_vertices; - const b2Vec2* v2s = poly2->m_vertices; - b2Transform xf = b2MulT(xf2, xf1); - - int32 bestIndex = 0; - float32 maxSeparation = -b2_maxFloat; - for (int32 i = 0; i < count1; ++i) - { - // Get poly1 normal in frame2. - b2Vec2 n = b2Mul(xf.q, n1s[i]); - b2Vec2 v1 = b2Mul(xf, v1s[i]); - - // Find deepest point for normal i. - float32 si = b2_maxFloat; - for (int32 j = 0; j < count2; ++j) - { - float32 sij = b2Dot(n, v2s[j] - v1); - if (sij < si) - { - si = sij; - } - } - - if (si > maxSeparation) - { - maxSeparation = si; - bestIndex = i; - } - } - - *edgeIndex = bestIndex; - return maxSeparation; -} - -static void b2FindIncidentEdge(b2ClipVertex c[2], - const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1, - const b2PolygonShape* poly2, const b2Transform& xf2) -{ - const b2Vec2* normals1 = poly1->m_normals; - - int32 count2 = poly2->m_count; - const b2Vec2* vertices2 = poly2->m_vertices; - const b2Vec2* normals2 = poly2->m_normals; - - b2Assert(0 <= edge1 && edge1 < poly1->m_count); - - // Get the normal of the reference edge in poly2's frame. - b2Vec2 normal1 = b2MulT(xf2.q, b2Mul(xf1.q, normals1[edge1])); - - // Find the incident edge on poly2. - int32 index = 0; - float32 minDot = b2_maxFloat; - for (int32 i = 0; i < count2; ++i) - { - float32 dot = b2Dot(normal1, normals2[i]); - if (dot < minDot) - { - minDot = dot; - index = i; - } - } - - // Build the clip vertices for the incident edge. - int32 i1 = index; - int32 i2 = i1 + 1 < count2 ? i1 + 1 : 0; - - c[0].v = b2Mul(xf2, vertices2[i1]); - c[0].id.cf.indexA = (uint8)edge1; - c[0].id.cf.indexB = (uint8)i1; - c[0].id.cf.typeA = b2ContactFeature::e_face; - c[0].id.cf.typeB = b2ContactFeature::e_vertex; - - c[1].v = b2Mul(xf2, vertices2[i2]); - c[1].id.cf.indexA = (uint8)edge1; - c[1].id.cf.indexB = (uint8)i2; - c[1].id.cf.typeA = b2ContactFeature::e_face; - c[1].id.cf.typeB = b2ContactFeature::e_vertex; -} - -// Find edge normal of max separation on A - return if separating axis is found -// Find edge normal of max separation on B - return if separation axis is found -// Choose reference edge as min(minA, minB) -// Find incident edge -// Clip - -// The normal points from 1 to 2 -void b2CollidePolygons(b2Manifold* manifold, - const b2PolygonShape* polyA, const b2Transform& xfA, - const b2PolygonShape* polyB, const b2Transform& xfB) -{ - manifold->pointCount = 0; - float32 totalRadius = polyA->m_radius + polyB->m_radius; - - int32 edgeA = 0; - float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB); - if (separationA > totalRadius) - return; - - int32 edgeB = 0; - float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA); - if (separationB > totalRadius) - return; - - const b2PolygonShape* poly1; // reference polygon - const b2PolygonShape* poly2; // incident polygon - b2Transform xf1, xf2; - int32 edge1; // reference edge - uint8 flip; - const float32 k_tol = 0.1f * b2_linearSlop; - - if (separationB > separationA + k_tol) - { - poly1 = polyB; - poly2 = polyA; - xf1 = xfB; - xf2 = xfA; - edge1 = edgeB; - manifold->type = b2Manifold::e_faceB; - flip = 1; - } - else - { - poly1 = polyA; - poly2 = polyB; - xf1 = xfA; - xf2 = xfB; - edge1 = edgeA; - manifold->type = b2Manifold::e_faceA; - flip = 0; - } - - b2ClipVertex incidentEdge[2]; - b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); - - int32 count1 = poly1->m_count; - const b2Vec2* vertices1 = poly1->m_vertices; - - int32 iv1 = edge1; - int32 iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0; - - b2Vec2 v11 = vertices1[iv1]; - b2Vec2 v12 = vertices1[iv2]; - - b2Vec2 localTangent = v12 - v11; - localTangent.Normalize(); - - b2Vec2 localNormal = b2Cross(localTangent, 1.0f); - b2Vec2 planePoint = 0.5f * (v11 + v12); - - b2Vec2 tangent = b2Mul(xf1.q, localTangent); - b2Vec2 normal = b2Cross(tangent, 1.0f); - - v11 = b2Mul(xf1, v11); - v12 = b2Mul(xf1, v12); - - // Face offset. - float32 frontOffset = b2Dot(normal, v11); - - // Side offsets, extended by polytope skin thickness. - float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius; - float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius; - - // Clip incident edge against extruded edge1 side edges. - b2ClipVertex clipPoints1[2]; - b2ClipVertex clipPoints2[2]; - int np; - - // Clip to box side 1 - np = b2ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1, iv1); - - if (np < 2) - return; - - // Clip to negative box side 1 - np = b2ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2, iv2); - - if (np < 2) - { - return; - } - - // Now clipPoints2 contains the clipped points. - manifold->localNormal = localNormal; - manifold->localPoint = planePoint; - - int32 pointCount = 0; - for (int32 i = 0; i < b2_maxManifoldPoints; ++i) - { - float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset; - - if (separation <= totalRadius) - { - b2ManifoldPoint* cp = manifold->points + pointCount; - cp->localPoint = b2MulT(xf2, clipPoints2[i].v); - cp->id = clipPoints2[i].id; - if (flip) - { - // Swap features - b2ContactFeature cf = cp->id.cf; - cp->id.cf.indexA = cf.indexB; - cp->id.cf.indexB = cf.indexA; - cp->id.cf.typeA = cf.typeB; - cp->id.cf.typeB = cf.typeA; - } - ++pointCount; - } - } - - manifold->pointCount = pointCount; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2Collision.cpp b/src/libjin/3rdparty/Box2D/Collision/b2Collision.cpp deleted file mode 100644 index 10e0b59..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2Collision.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* -* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/b2Distance.h" - -void b2WorldManifold::Initialize(const b2Manifold* manifold, - const b2Transform& xfA, float32 radiusA, - const b2Transform& xfB, float32 radiusB) -{ - if (manifold->pointCount == 0) - { - return; - } - - switch (manifold->type) - { - case b2Manifold::e_circles: - { - normal.Set(1.0f, 0.0f); - b2Vec2 pointA = b2Mul(xfA, manifold->localPoint); - b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint); - if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon) - { - normal = pointB - pointA; - normal.Normalize(); - } - - b2Vec2 cA = pointA + radiusA * normal; - b2Vec2 cB = pointB - radiusB * normal; - points[0] = 0.5f * (cA + cB); - separations[0] = b2Dot(cB - cA, normal); - } - break; - - case b2Manifold::e_faceA: - { - normal = b2Mul(xfA.q, manifold->localNormal); - b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint); - - for (int32 i = 0; i < manifold->pointCount; ++i) - { - b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint); - b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal; - b2Vec2 cB = clipPoint - radiusB * normal; - points[i] = 0.5f * (cA + cB); - separations[i] = b2Dot(cB - cA, normal); - } - } - break; - - case b2Manifold::e_faceB: - { - normal = b2Mul(xfB.q, manifold->localNormal); - b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint); - - for (int32 i = 0; i < manifold->pointCount; ++i) - { - b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint); - b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal; - b2Vec2 cA = clipPoint - radiusA * normal; - points[i] = 0.5f * (cA + cB); - separations[i] = b2Dot(cA - cB, normal); - } - - // Ensure normal points from A to B. - normal = -normal; - } - break; - } -} - -void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], - const b2Manifold* manifold1, const b2Manifold* manifold2) -{ - for (int32 i = 0; i < b2_maxManifoldPoints; ++i) - { - state1[i] = b2_nullState; - state2[i] = b2_nullState; - } - - // Detect persists and removes. - for (int32 i = 0; i < manifold1->pointCount; ++i) - { - b2ContactID id = manifold1->points[i].id; - - state1[i] = b2_removeState; - - for (int32 j = 0; j < manifold2->pointCount; ++j) - { - if (manifold2->points[j].id.key == id.key) - { - state1[i] = b2_persistState; - break; - } - } - } - - // Detect persists and adds. - for (int32 i = 0; i < manifold2->pointCount; ++i) - { - b2ContactID id = manifold2->points[i].id; - - state2[i] = b2_addState; - - for (int32 j = 0; j < manifold1->pointCount; ++j) - { - if (manifold1->points[j].id.key == id.key) - { - state2[i] = b2_persistState; - break; - } - } - } -} - -// From Real-time Collision Detection, p179. -bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const -{ - float32 tmin = -b2_maxFloat; - float32 tmax = b2_maxFloat; - - b2Vec2 p = input.p1; - b2Vec2 d = input.p2 - input.p1; - b2Vec2 absD = b2Abs(d); - - b2Vec2 normal; - - for (int32 i = 0; i < 2; ++i) - { - if (absD(i) < b2_epsilon) - { - // Parallel. - if (p(i) < lowerBound(i) || upperBound(i) < p(i)) - { - return false; - } - } - else - { - float32 inv_d = 1.0f / d(i); - float32 t1 = (lowerBound(i) - p(i)) * inv_d; - float32 t2 = (upperBound(i) - p(i)) * inv_d; - - // Sign of the normal vector. - float32 s = -1.0f; - - if (t1 > t2) - { - b2Swap(t1, t2); - s = 1.0f; - } - - // Push the min up - if (t1 > tmin) - { - normal.SetZero(); - normal(i) = s; - tmin = t1; - } - - // Pull the max down - tmax = b2Min(tmax, t2); - - if (tmin > tmax) - { - return false; - } - } - } - - // Does the ray start inside the box? - // Does the ray intersect beyond the max fraction? - if (tmin < 0.0f || input.maxFraction < tmin) - { - return false; - } - - // Intersection. - output->fraction = tmin; - output->normal = normal; - return true; -} - -// Sutherland-Hodgman clipping. -int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], - const b2Vec2& normal, float32 offset, int32 vertexIndexA) -{ - // Start with no output points - int32 numOut = 0; - - // Calculate the distance of end points to the line - float32 distance0 = b2Dot(normal, vIn[0].v) - offset; - float32 distance1 = b2Dot(normal, vIn[1].v) - offset; - - // If the points are behind the plane - if (distance0 <= 0.0f) vOut[numOut++] = vIn[0]; - if (distance1 <= 0.0f) vOut[numOut++] = vIn[1]; - - // If the points are on different sides of the plane - if (distance0 * distance1 < 0.0f) - { - // Find intersection point of edge and plane - float32 interp = distance0 / (distance0 - distance1); - vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v); - - // VertexA is hitting edgeB. - vOut[numOut].id.cf.indexA = static_cast<uint8>(vertexIndexA); - vOut[numOut].id.cf.indexB = vIn[0].id.cf.indexB; - vOut[numOut].id.cf.typeA = b2ContactFeature::e_vertex; - vOut[numOut].id.cf.typeB = b2ContactFeature::e_face; - ++numOut; - } - - return numOut; -} - -bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, - const b2Shape* shapeB, int32 indexB, - const b2Transform& xfA, const b2Transform& xfB) -{ - b2DistanceInput input; - input.proxyA.Set(shapeA, indexA); - input.proxyB.Set(shapeB, indexB); - input.transformA = xfA; - input.transformB = xfB; - input.useRadii = true; - - b2SimplexCache cache; - cache.count = 0; - - b2DistanceOutput output; - - b2Distance(&output, &cache, &input); - - return output.distance < 10.0f * b2_epsilon; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2Collision.h b/src/libjin/3rdparty/Box2D/Collision/b2Collision.h deleted file mode 100644 index fe1f4cd..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2Collision.h +++ /dev/null @@ -1,277 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_COLLISION_H -#define B2_COLLISION_H - -#include "Box2D/Common/b2Math.h" -#include <limits.h> - -/// @file -/// Structures and functions used for computing contact points, distance -/// queries, and TOI queries. - -class b2Shape; -class b2CircleShape; -class b2EdgeShape; -class b2PolygonShape; - -const uint8 b2_nullFeature = UCHAR_MAX; - -/// The features that intersect to form the contact point -/// This must be 4 bytes or less. -struct b2ContactFeature -{ - enum Type - { - e_vertex = 0, - e_face = 1 - }; - - uint8 indexA; ///< Feature index on shapeA - uint8 indexB; ///< Feature index on shapeB - uint8 typeA; ///< The feature type on shapeA - uint8 typeB; ///< The feature type on shapeB -}; - -/// Contact ids to facilitate warm starting. -union b2ContactID -{ - b2ContactFeature cf; - uint32 key; ///< Used to quickly compare contact ids. -}; - -/// A manifold point is a contact point belonging to a contact -/// manifold. It holds details related to the geometry and dynamics -/// of the contact points. -/// The local point usage depends on the manifold type: -/// -e_circles: the local center of circleB -/// -e_faceA: the local center of cirlceB or the clip point of polygonB -/// -e_faceB: the clip point of polygonA -/// This structure is stored across time steps, so we keep it small. -/// Note: the impulses are used for internal caching and may not -/// provide reliable contact forces, especially for high speed collisions. -struct b2ManifoldPoint -{ - b2Vec2 localPoint; ///< usage depends on manifold type - float32 normalImpulse; ///< the non-penetration impulse - float32 tangentImpulse; ///< the friction impulse - b2ContactID id; ///< uniquely identifies a contact point between two shapes -}; - -/// A manifold for two touching convex shapes. -/// Box2D supports multiple types of contact: -/// - clip point versus plane with radius -/// - point versus point with radius (circles) -/// The local point usage depends on the manifold type: -/// -e_circles: the local center of circleA -/// -e_faceA: the center of faceA -/// -e_faceB: the center of faceB -/// Similarly the local normal usage: -/// -e_circles: not used -/// -e_faceA: the normal on polygonA -/// -e_faceB: the normal on polygonB -/// We store contacts in this way so that position correction can -/// account for movement, which is critical for continuous physics. -/// All contact scenarios must be expressed in one of these types. -/// This structure is stored across time steps, so we keep it small. -struct b2Manifold -{ - enum Type - { - e_circles, - e_faceA, - e_faceB - }; - - b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact - b2Vec2 localNormal; ///< not use for Type::e_points - b2Vec2 localPoint; ///< usage depends on manifold type - Type type; - int32 pointCount; ///< the number of manifold points -}; - -/// This is used to compute the current state of a contact manifold. -struct b2WorldManifold -{ - /// Evaluate the manifold with supplied transforms. This assumes - /// modest motion from the original state. This does not change the - /// point count, impulses, etc. The radii must come from the shapes - /// that generated the manifold. - void Initialize(const b2Manifold* manifold, - const b2Transform& xfA, float32 radiusA, - const b2Transform& xfB, float32 radiusB); - - b2Vec2 normal; ///< world vector pointing from A to B - b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection) - float32 separations[b2_maxManifoldPoints]; ///< a negative value indicates overlap, in meters -}; - -/// This is used for determining the state of contact points. -enum b2PointState -{ - b2_nullState, ///< point does not exist - b2_addState, ///< point was added in the update - b2_persistState, ///< point persisted across the update - b2_removeState ///< point was removed in the update -}; - -/// Compute the point states given two manifolds. The states pertain to the transition from manifold1 -/// to manifold2. So state1 is either persist or remove while state2 is either add or persist. -void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], - const b2Manifold* manifold1, const b2Manifold* manifold2); - -/// Used for computing contact manifolds. -struct b2ClipVertex -{ - b2Vec2 v; - b2ContactID id; -}; - -/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). -struct b2RayCastInput -{ - b2Vec2 p1, p2; - float32 maxFraction; -}; - -/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 -/// come from b2RayCastInput. -struct b2RayCastOutput -{ - b2Vec2 normal; - float32 fraction; -}; - -/// An axis aligned bounding box. -struct b2AABB -{ - /// Verify that the bounds are sorted. - bool IsValid() const; - - /// Get the center of the AABB. - b2Vec2 GetCenter() const - { - return 0.5f * (lowerBound + upperBound); - } - - /// Get the extents of the AABB (half-widths). - b2Vec2 GetExtents() const - { - return 0.5f * (upperBound - lowerBound); - } - - /// Get the perimeter length - float32 GetPerimeter() const - { - float32 wx = upperBound.x - lowerBound.x; - float32 wy = upperBound.y - lowerBound.y; - return 2.0f * (wx + wy); - } - - /// Combine an AABB into this one. - void Combine(const b2AABB& aabb) - { - lowerBound = b2Min(lowerBound, aabb.lowerBound); - upperBound = b2Max(upperBound, aabb.upperBound); - } - - /// Combine two AABBs into this one. - void Combine(const b2AABB& aabb1, const b2AABB& aabb2) - { - lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound); - upperBound = b2Max(aabb1.upperBound, aabb2.upperBound); - } - - /// Does this aabb contain the provided AABB. - bool Contains(const b2AABB& aabb) const - { - bool result = true; - result = result && lowerBound.x <= aabb.lowerBound.x; - result = result && lowerBound.y <= aabb.lowerBound.y; - result = result && aabb.upperBound.x <= upperBound.x; - result = result && aabb.upperBound.y <= upperBound.y; - return result; - } - - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; - - b2Vec2 lowerBound; ///< the lower vertex - b2Vec2 upperBound; ///< the upper vertex -}; - -/// Compute the collision manifold between two circles. -void b2CollideCircles(b2Manifold* manifold, - const b2CircleShape* circleA, const b2Transform& xfA, - const b2CircleShape* circleB, const b2Transform& xfB); - -/// Compute the collision manifold between a polygon and a circle. -void b2CollidePolygonAndCircle(b2Manifold* manifold, - const b2PolygonShape* polygonA, const b2Transform& xfA, - const b2CircleShape* circleB, const b2Transform& xfB); - -/// Compute the collision manifold between two polygons. -void b2CollidePolygons(b2Manifold* manifold, - const b2PolygonShape* polygonA, const b2Transform& xfA, - const b2PolygonShape* polygonB, const b2Transform& xfB); - -/// Compute the collision manifold between an edge and a circle. -void b2CollideEdgeAndCircle(b2Manifold* manifold, - const b2EdgeShape* polygonA, const b2Transform& xfA, - const b2CircleShape* circleB, const b2Transform& xfB); - -/// Compute the collision manifold between an edge and a circle. -void b2CollideEdgeAndPolygon(b2Manifold* manifold, - const b2EdgeShape* edgeA, const b2Transform& xfA, - const b2PolygonShape* circleB, const b2Transform& xfB); - -/// Clipping for contact manifolds. -int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], - const b2Vec2& normal, float32 offset, int32 vertexIndexA); - -/// Determine if two generic shapes overlap. -bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, - const b2Shape* shapeB, int32 indexB, - const b2Transform& xfA, const b2Transform& xfB); - -// ---------------- Inline Functions ------------------------------------------ - -inline bool b2AABB::IsValid() const -{ - b2Vec2 d = upperBound - lowerBound; - bool valid = d.x >= 0.0f && d.y >= 0.0f; - valid = valid && lowerBound.IsValid() && upperBound.IsValid(); - return valid; -} - -inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b) -{ - b2Vec2 d1, d2; - d1 = b.lowerBound - a.upperBound; - d2 = a.lowerBound - b.upperBound; - - if (d1.x > 0.0f || d1.y > 0.0f) - return false; - - if (d2.x > 0.0f || d2.y > 0.0f) - return false; - - return true; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/b2Distance.cpp b/src/libjin/3rdparty/Box2D/Collision/b2Distance.cpp deleted file mode 100644 index 194d747..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2Distance.cpp +++ /dev/null @@ -1,737 +0,0 @@ -/* -* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2Distance.h" -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" - -// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates. -int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; - -void b2DistanceProxy::Set(const b2Shape* shape, int32 index) -{ - switch (shape->GetType()) - { - case b2Shape::e_circle: - { - const b2CircleShape* circle = static_cast<const b2CircleShape*>(shape); - m_vertices = &circle->m_p; - m_count = 1; - m_radius = circle->m_radius; - } - break; - - case b2Shape::e_polygon: - { - const b2PolygonShape* polygon = static_cast<const b2PolygonShape*>(shape); - m_vertices = polygon->m_vertices; - m_count = polygon->m_count; - m_radius = polygon->m_radius; - } - break; - - case b2Shape::e_chain: - { - const b2ChainShape* chain = static_cast<const b2ChainShape*>(shape); - b2Assert(0 <= index && index < chain->m_count); - - m_buffer[0] = chain->m_vertices[index]; - if (index + 1 < chain->m_count) - { - m_buffer[1] = chain->m_vertices[index + 1]; - } - else - { - m_buffer[1] = chain->m_vertices[0]; - } - - m_vertices = m_buffer; - m_count = 2; - m_radius = chain->m_radius; - } - break; - - case b2Shape::e_edge: - { - const b2EdgeShape* edge = static_cast<const b2EdgeShape*>(shape); - m_vertices = &edge->m_vertex1; - m_count = 2; - m_radius = edge->m_radius; - } - break; - - default: - b2Assert(false); - } -} - -void b2DistanceProxy::Set(const b2Vec2* vertices, int32 count, float32 radius) -{ - m_vertices = vertices; - m_count = count; - m_radius = radius; -} - -struct b2SimplexVertex -{ - b2Vec2 wA; // support point in proxyA - b2Vec2 wB; // support point in proxyB - b2Vec2 w; // wB - wA - float32 a; // barycentric coordinate for closest point - int32 indexA; // wA index - int32 indexB; // wB index -}; - -struct b2Simplex -{ - void ReadCache( const b2SimplexCache* cache, - const b2DistanceProxy* proxyA, const b2Transform& transformA, - const b2DistanceProxy* proxyB, const b2Transform& transformB) - { - b2Assert(cache->count <= 3); - - // Copy data from cache. - m_count = cache->count; - b2SimplexVertex* vertices = &m_v1; - for (int32 i = 0; i < m_count; ++i) - { - b2SimplexVertex* v = vertices + i; - v->indexA = cache->indexA[i]; - v->indexB = cache->indexB[i]; - b2Vec2 wALocal = proxyA->GetVertex(v->indexA); - b2Vec2 wBLocal = proxyB->GetVertex(v->indexB); - v->wA = b2Mul(transformA, wALocal); - v->wB = b2Mul(transformB, wBLocal); - v->w = v->wB - v->wA; - v->a = 0.0f; - } - - // Compute the new simplex metric, if it is substantially different than - // old metric then flush the simplex. - if (m_count > 1) - { - float32 metric1 = cache->metric; - float32 metric2 = GetMetric(); - if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon) - { - // Reset the simplex. - m_count = 0; - } - } - - // If the cache is empty or invalid ... - if (m_count == 0) - { - b2SimplexVertex* v = vertices + 0; - v->indexA = 0; - v->indexB = 0; - b2Vec2 wALocal = proxyA->GetVertex(0); - b2Vec2 wBLocal = proxyB->GetVertex(0); - v->wA = b2Mul(transformA, wALocal); - v->wB = b2Mul(transformB, wBLocal); - v->w = v->wB - v->wA; - v->a = 1.0f; - m_count = 1; - } - } - - void WriteCache(b2SimplexCache* cache) const - { - cache->metric = GetMetric(); - cache->count = uint16(m_count); - const b2SimplexVertex* vertices = &m_v1; - for (int32 i = 0; i < m_count; ++i) - { - cache->indexA[i] = uint8(vertices[i].indexA); - cache->indexB[i] = uint8(vertices[i].indexB); - } - } - - b2Vec2 GetSearchDirection() const - { - switch (m_count) - { - case 1: - return -m_v1.w; - - case 2: - { - b2Vec2 e12 = m_v2.w - m_v1.w; - float32 sgn = b2Cross(e12, -m_v1.w); - if (sgn > 0.0f) - { - // Origin is left of e12. - return b2Cross(1.0f, e12); - } - else - { - // Origin is right of e12. - return b2Cross(e12, 1.0f); - } - } - - default: - b2Assert(false); - return b2Vec2_zero; - } - } - - b2Vec2 GetClosestPoint() const - { - switch (m_count) - { - case 0: - b2Assert(false); - return b2Vec2_zero; - - case 1: - return m_v1.w; - - case 2: - return m_v1.a * m_v1.w + m_v2.a * m_v2.w; - - case 3: - return b2Vec2_zero; - - default: - b2Assert(false); - return b2Vec2_zero; - } - } - - void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const - { - switch (m_count) - { - case 0: - b2Assert(false); - break; - - case 1: - *pA = m_v1.wA; - *pB = m_v1.wB; - break; - - case 2: - *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA; - *pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB; - break; - - case 3: - *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA; - *pB = *pA; - break; - - default: - b2Assert(false); - break; - } - } - - float32 GetMetric() const - { - switch (m_count) - { - case 0: - b2Assert(false); - return 0.0f; - - case 1: - return 0.0f; - - case 2: - return b2Distance(m_v1.w, m_v2.w); - - case 3: - return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w); - - default: - b2Assert(false); - return 0.0f; - } - } - - void Solve2(); - void Solve3(); - - b2SimplexVertex m_v1, m_v2, m_v3; - int32 m_count; -}; - - -// Solve a line segment using barycentric coordinates. -// -// p = a1 * w1 + a2 * w2 -// a1 + a2 = 1 -// -// The vector from the origin to the closest point on the line is -// perpendicular to the line. -// e12 = w2 - w1 -// dot(p, e) = 0 -// a1 * dot(w1, e) + a2 * dot(w2, e) = 0 -// -// 2-by-2 linear system -// [1 1 ][a1] = [1] -// [w1.e12 w2.e12][a2] = [0] -// -// Define -// d12_1 = dot(w2, e12) -// d12_2 = -dot(w1, e12) -// d12 = d12_1 + d12_2 -// -// Solution -// a1 = d12_1 / d12 -// a2 = d12_2 / d12 -void b2Simplex::Solve2() -{ - b2Vec2 w1 = m_v1.w; - b2Vec2 w2 = m_v2.w; - b2Vec2 e12 = w2 - w1; - - // w1 region - float32 d12_2 = -b2Dot(w1, e12); - if (d12_2 <= 0.0f) - { - // a2 <= 0, so we clamp it to 0 - m_v1.a = 1.0f; - m_count = 1; - return; - } - - // w2 region - float32 d12_1 = b2Dot(w2, e12); - if (d12_1 <= 0.0f) - { - // a1 <= 0, so we clamp it to 0 - m_v2.a = 1.0f; - m_count = 1; - m_v1 = m_v2; - return; - } - - // Must be in e12 region. - float32 inv_d12 = 1.0f / (d12_1 + d12_2); - m_v1.a = d12_1 * inv_d12; - m_v2.a = d12_2 * inv_d12; - m_count = 2; -} - -// Possible regions: -// - points[2] -// - edge points[0]-points[2] -// - edge points[1]-points[2] -// - inside the triangle -void b2Simplex::Solve3() -{ - b2Vec2 w1 = m_v1.w; - b2Vec2 w2 = m_v2.w; - b2Vec2 w3 = m_v3.w; - - // Edge12 - // [1 1 ][a1] = [1] - // [w1.e12 w2.e12][a2] = [0] - // a3 = 0 - b2Vec2 e12 = w2 - w1; - float32 w1e12 = b2Dot(w1, e12); - float32 w2e12 = b2Dot(w2, e12); - float32 d12_1 = w2e12; - float32 d12_2 = -w1e12; - - // Edge13 - // [1 1 ][a1] = [1] - // [w1.e13 w3.e13][a3] = [0] - // a2 = 0 - b2Vec2 e13 = w3 - w1; - float32 w1e13 = b2Dot(w1, e13); - float32 w3e13 = b2Dot(w3, e13); - float32 d13_1 = w3e13; - float32 d13_2 = -w1e13; - - // Edge23 - // [1 1 ][a2] = [1] - // [w2.e23 w3.e23][a3] = [0] - // a1 = 0 - b2Vec2 e23 = w3 - w2; - float32 w2e23 = b2Dot(w2, e23); - float32 w3e23 = b2Dot(w3, e23); - float32 d23_1 = w3e23; - float32 d23_2 = -w2e23; - - // Triangle123 - float32 n123 = b2Cross(e12, e13); - - float32 d123_1 = n123 * b2Cross(w2, w3); - float32 d123_2 = n123 * b2Cross(w3, w1); - float32 d123_3 = n123 * b2Cross(w1, w2); - - // w1 region - if (d12_2 <= 0.0f && d13_2 <= 0.0f) - { - m_v1.a = 1.0f; - m_count = 1; - return; - } - - // e12 - if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f) - { - float32 inv_d12 = 1.0f / (d12_1 + d12_2); - m_v1.a = d12_1 * inv_d12; - m_v2.a = d12_2 * inv_d12; - m_count = 2; - return; - } - - // e13 - if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f) - { - float32 inv_d13 = 1.0f / (d13_1 + d13_2); - m_v1.a = d13_1 * inv_d13; - m_v3.a = d13_2 * inv_d13; - m_count = 2; - m_v2 = m_v3; - return; - } - - // w2 region - if (d12_1 <= 0.0f && d23_2 <= 0.0f) - { - m_v2.a = 1.0f; - m_count = 1; - m_v1 = m_v2; - return; - } - - // w3 region - if (d13_1 <= 0.0f && d23_1 <= 0.0f) - { - m_v3.a = 1.0f; - m_count = 1; - m_v1 = m_v3; - return; - } - - // e23 - if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f) - { - float32 inv_d23 = 1.0f / (d23_1 + d23_2); - m_v2.a = d23_1 * inv_d23; - m_v3.a = d23_2 * inv_d23; - m_count = 2; - m_v1 = m_v3; - return; - } - - // Must be in triangle123 - float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3); - m_v1.a = d123_1 * inv_d123; - m_v2.a = d123_2 * inv_d123; - m_v3.a = d123_3 * inv_d123; - m_count = 3; -} - -void b2Distance(b2DistanceOutput* output, - b2SimplexCache* cache, - const b2DistanceInput* input) -{ - ++b2_gjkCalls; - - const b2DistanceProxy* proxyA = &input->proxyA; - const b2DistanceProxy* proxyB = &input->proxyB; - - b2Transform transformA = input->transformA; - b2Transform transformB = input->transformB; - - // Initialize the simplex. - b2Simplex simplex; - simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); - - // Get simplex vertices as an array. - b2SimplexVertex* vertices = &simplex.m_v1; - const int32 k_maxIters = 20; - - // These store the vertices of the last simplex so that we - // can check for duplicates and prevent cycling. - int32 saveA[3], saveB[3]; - int32 saveCount = 0; - - // Main iteration loop. - int32 iter = 0; - while (iter < k_maxIters) - { - // Copy simplex so we can identify duplicates. - saveCount = simplex.m_count; - for (int32 i = 0; i < saveCount; ++i) - { - saveA[i] = vertices[i].indexA; - saveB[i] = vertices[i].indexB; - } - - switch (simplex.m_count) - { - case 1: - break; - - case 2: - simplex.Solve2(); - break; - - case 3: - simplex.Solve3(); - break; - - default: - b2Assert(false); - } - - // If we have 3 points, then the origin is in the corresponding triangle. - if (simplex.m_count == 3) - { - break; - } - - // Get search direction. - b2Vec2 d = simplex.GetSearchDirection(); - - // Ensure the search direction is numerically fit. - if (d.LengthSquared() < b2_epsilon * b2_epsilon) - { - // The origin is probably contained by a line segment - // or triangle. Thus the shapes are overlapped. - - // We can't return zero here even though there may be overlap. - // In case the simplex is a point, segment, or triangle it is difficult - // to determine if the origin is contained in the CSO or very close to it. - break; - } - - // Compute a tentative new simplex vertex using support points. - b2SimplexVertex* vertex = vertices + simplex.m_count; - vertex->indexA = proxyA->GetSupport(b2MulT(transformA.q, -d)); - vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA)); - b2Vec2 wBLocal; - vertex->indexB = proxyB->GetSupport(b2MulT(transformB.q, d)); - vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB)); - vertex->w = vertex->wB - vertex->wA; - - // Iteration count is equated to the number of support point calls. - ++iter; - ++b2_gjkIters; - - // Check for duplicate support points. This is the main termination criteria. - bool duplicate = false; - for (int32 i = 0; i < saveCount; ++i) - { - if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i]) - { - duplicate = true; - break; - } - } - - // If we found a duplicate support point we must exit to avoid cycling. - if (duplicate) - { - break; - } - - // New vertex is ok and needed. - ++simplex.m_count; - } - - b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter); - - // Prepare output. - simplex.GetWitnessPoints(&output->pointA, &output->pointB); - output->distance = b2Distance(output->pointA, output->pointB); - output->iterations = iter; - - // Cache the simplex. - simplex.WriteCache(cache); - - // Apply radii if requested. - if (input->useRadii) - { - float32 rA = proxyA->m_radius; - float32 rB = proxyB->m_radius; - - if (output->distance > rA + rB && output->distance > b2_epsilon) - { - // Shapes are still no overlapped. - // Move the witness points to the outer surface. - output->distance -= rA + rB; - b2Vec2 normal = output->pointB - output->pointA; - normal.Normalize(); - output->pointA += rA * normal; - output->pointB -= rB * normal; - } - else - { - // Shapes are overlapped when radii are considered. - // Move the witness points to the middle. - b2Vec2 p = 0.5f * (output->pointA + output->pointB); - output->pointA = p; - output->pointB = p; - output->distance = 0.0f; - } - } -} - -// GJK-raycast -// Algorithm by Gino van den Bergen. -// "Smooth Mesh Contacts with GJK" in Game Physics Pearls. 2010 -bool b2ShapeCast(b2ShapeCastOutput * output, const b2ShapeCastInput * input) -{ - output->iterations = 0; - output->lambda = 1.0f; - output->normal.SetZero(); - output->point.SetZero(); - - const b2DistanceProxy* proxyA = &input->proxyA; - const b2DistanceProxy* proxyB = &input->proxyB; - - float32 radiusA = b2Max(proxyA->m_radius, b2_polygonRadius); - float32 radiusB = b2Max(proxyB->m_radius, b2_polygonRadius); - float32 radius = radiusA + radiusB; - - b2Transform xfA = input->transformA; - b2Transform xfB = input->transformB; - - b2Vec2 r = input->translationB; - b2Vec2 n(0.0f, 0.0f); - float32 lambda = 0.0f; - - // Initial simplex - b2Simplex simplex; - simplex.m_count = 0; - - // Get simplex vertices as an array. - b2SimplexVertex* vertices = &simplex.m_v1; - - // Get support point in -r direction - int32 indexA = proxyA->GetSupport(b2MulT(xfA.q, -r)); - b2Vec2 wA = b2Mul(xfA, proxyA->GetVertex(indexA)); - int32 indexB = proxyB->GetSupport(b2MulT(xfB.q, r)); - b2Vec2 wB = b2Mul(xfB, proxyB->GetVertex(indexB)); - b2Vec2 v = wA - wB; - - // Sigma is the target distance between polygons - float32 sigma = b2Max(b2_polygonRadius, radius - b2_polygonRadius); - const float32 tolerance = 0.5f * b2_linearSlop; - - // Main iteration loop. - const int32 k_maxIters = 20; - int32 iter = 0; - while (iter < k_maxIters && b2Abs(v.Length() - sigma) > tolerance) - { - b2Assert(simplex.m_count < 3); - - output->iterations += 1; - - // Support in direction -v (A - B) - indexA = proxyA->GetSupport(b2MulT(xfA.q, -v)); - wA = b2Mul(xfA, proxyA->GetVertex(indexA)); - indexB = proxyB->GetSupport(b2MulT(xfB.q, v)); - wB = b2Mul(xfB, proxyB->GetVertex(indexB)); - b2Vec2 p = wA - wB; - - // -v is a normal at p - v.Normalize(); - - // Intersect ray with plane - float32 vp = b2Dot(v, p); - float32 vr = b2Dot(v, r); - if (vp - sigma > lambda * vr) - { - if (vr <= 0.0f) - { - return false; - } - - lambda = (vp - sigma) / vr; - if (lambda > 1.0f) - { - return false; - } - - n = -v; - simplex.m_count = 0; - } - - // Reverse simplex since it works with B - A. - // Shift by lambda * r because we want the closest point to the current clip point. - // Note that the support point p is not shifted because we want the plane equation - // to be formed in unshifted space. - b2SimplexVertex* vertex = vertices + simplex.m_count; - vertex->indexA = indexB; - vertex->wA = wB + lambda * r; - vertex->indexB = indexA; - vertex->wB = wA; - vertex->w = vertex->wB - vertex->wA; - vertex->a = 1.0f; - simplex.m_count += 1; - - switch (simplex.m_count) - { - case 1: - break; - - case 2: - simplex.Solve2(); - break; - - case 3: - simplex.Solve3(); - break; - - default: - b2Assert(false); - } - - // If we have 3 points, then the origin is in the corresponding triangle. - if (simplex.m_count == 3) - { - // Overlap - return false; - } - - // Get search direction. - v = simplex.GetClosestPoint(); - - // Iteration count is equated to the number of support point calls. - ++iter; - } - - // Prepare output. - b2Vec2 pointA, pointB; - simplex.GetWitnessPoints(&pointB, &pointA); - - if (v.LengthSquared() > 0.0f) - { - n = -v; - n.Normalize(); - } - - output->point = pointA + radiusA * n; - output->normal = n; - output->lambda = lambda; - output->iterations = iter; - return true; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2Distance.h b/src/libjin/3rdparty/Box2D/Collision/b2Distance.h deleted file mode 100644 index d6eb985..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2Distance.h +++ /dev/null @@ -1,166 +0,0 @@ - -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_DISTANCE_H -#define B2_DISTANCE_H - -#include "Box2D/Common/b2Math.h" - -class b2Shape; - -/// A distance proxy is used by the GJK algorithm. -/// It encapsulates any shape. -struct b2DistanceProxy -{ - b2DistanceProxy() : m_vertices(nullptr), m_count(0), m_radius(0.0f) {} - - /// Initialize the proxy using the given shape. The shape - /// must remain in scope while the proxy is in use. - void Set(const b2Shape* shape, int32 index); - - /// Initialize the proxy using a vertex cloud and radius. The vertices - /// must remain in scope while the proxy is in use. - void Set(const b2Vec2* vertices, int32 count, float32 radius); - - /// Get the supporting vertex index in the given direction. - int32 GetSupport(const b2Vec2& d) const; - - /// Get the supporting vertex in the given direction. - const b2Vec2& GetSupportVertex(const b2Vec2& d) const; - - /// Get the vertex count. - int32 GetVertexCount() const; - - /// Get a vertex by index. Used by b2Distance. - const b2Vec2& GetVertex(int32 index) const; - - b2Vec2 m_buffer[2]; - const b2Vec2* m_vertices; - int32 m_count; - float32 m_radius; -}; - -/// Used to warm start b2Distance. -/// Set count to zero on first call. -struct b2SimplexCache -{ - float32 metric; ///< length or area - uint16 count; - uint8 indexA[3]; ///< vertices on shape A - uint8 indexB[3]; ///< vertices on shape B -}; - -/// Input for b2Distance. -/// You have to option to use the shape radii -/// in the computation. Even -struct b2DistanceInput -{ - b2DistanceProxy proxyA; - b2DistanceProxy proxyB; - b2Transform transformA; - b2Transform transformB; - bool useRadii; -}; - -/// Output for b2Distance. -struct b2DistanceOutput -{ - b2Vec2 pointA; ///< closest point on shapeA - b2Vec2 pointB; ///< closest point on shapeB - float32 distance; - int32 iterations; ///< number of GJK iterations used -}; - -/// Compute the closest points between two shapes. Supports any combination of: -/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output. -/// On the first call set b2SimplexCache.count to zero. -void b2Distance(b2DistanceOutput* output, - b2SimplexCache* cache, - const b2DistanceInput* input); - -/// Input parameters for b2ShapeCast -struct b2ShapeCastInput -{ - b2DistanceProxy proxyA; - b2DistanceProxy proxyB; - b2Transform transformA; - b2Transform transformB; - b2Vec2 translationB; -}; - -/// Output results for b2ShapeCast -struct b2ShapeCastOutput -{ - b2Vec2 point; - b2Vec2 normal; - float32 lambda; - int32 iterations; -}; - -/// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction. -bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); - -////////////////////////////////////////////////////////////////////////// - -inline int32 b2DistanceProxy::GetVertexCount() const -{ - return m_count; -} - -inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const -{ - b2Assert(0 <= index && index < m_count); - return m_vertices[index]; -} - -inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const -{ - int32 bestIndex = 0; - float32 bestValue = b2Dot(m_vertices[0], d); - for (int32 i = 1; i < m_count; ++i) - { - float32 value = b2Dot(m_vertices[i], d); - if (value > bestValue) - { - bestIndex = i; - bestValue = value; - } - } - - return bestIndex; -} - -inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const -{ - int32 bestIndex = 0; - float32 bestValue = b2Dot(m_vertices[0], d); - for (int32 i = 1; i < m_count; ++i) - { - float32 value = b2Dot(m_vertices[i], d); - if (value > bestValue) - { - bestIndex = i; - bestValue = value; - } - } - - return m_vertices[bestIndex]; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/b2DynamicTree.cpp b/src/libjin/3rdparty/Box2D/Collision/b2DynamicTree.cpp deleted file mode 100644 index 4432ec1..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2DynamicTree.cpp +++ /dev/null @@ -1,780 +0,0 @@ -/* -* Copyright (c) 2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2DynamicTree.h" -#include <string.h> - -b2DynamicTree::b2DynamicTree() -{ - m_root = b2_nullNode; - - m_nodeCapacity = 16; - m_nodeCount = 0; - m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode)); - memset(m_nodes, 0, m_nodeCapacity * sizeof(b2TreeNode)); - - // Build a linked list for the free list. - for (int32 i = 0; i < m_nodeCapacity - 1; ++i) - { - m_nodes[i].next = i + 1; - m_nodes[i].height = -1; - } - m_nodes[m_nodeCapacity-1].next = b2_nullNode; - m_nodes[m_nodeCapacity-1].height = -1; - m_freeList = 0; - - m_path = 0; - - m_insertionCount = 0; -} - -b2DynamicTree::~b2DynamicTree() -{ - // This frees the entire tree in one shot. - b2Free(m_nodes); -} - -// Allocate a node from the pool. Grow the pool if necessary. -int32 b2DynamicTree::AllocateNode() -{ - // Expand the node pool as needed. - if (m_freeList == b2_nullNode) - { - b2Assert(m_nodeCount == m_nodeCapacity); - - // The free list is empty. Rebuild a bigger pool. - b2TreeNode* oldNodes = m_nodes; - m_nodeCapacity *= 2; - m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode)); - memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2TreeNode)); - b2Free(oldNodes); - - // Build a linked list for the free list. The parent - // pointer becomes the "next" pointer. - for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i) - { - m_nodes[i].next = i + 1; - m_nodes[i].height = -1; - } - m_nodes[m_nodeCapacity-1].next = b2_nullNode; - m_nodes[m_nodeCapacity-1].height = -1; - m_freeList = m_nodeCount; - } - - // Peel a node off the free list. - int32 nodeId = m_freeList; - m_freeList = m_nodes[nodeId].next; - m_nodes[nodeId].parent = b2_nullNode; - m_nodes[nodeId].child1 = b2_nullNode; - m_nodes[nodeId].child2 = b2_nullNode; - m_nodes[nodeId].height = 0; - m_nodes[nodeId].userData = nullptr; - ++m_nodeCount; - return nodeId; -} - -// Return a node to the pool. -void b2DynamicTree::FreeNode(int32 nodeId) -{ - b2Assert(0 <= nodeId && nodeId < m_nodeCapacity); - b2Assert(0 < m_nodeCount); - m_nodes[nodeId].next = m_freeList; - m_nodes[nodeId].height = -1; - m_freeList = nodeId; - --m_nodeCount; -} - -// Create a proxy in the tree as a leaf node. We return the index -// of the node instead of a pointer so that we can grow -// the node pool. -int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData) -{ - int32 proxyId = AllocateNode(); - - // Fatten the aabb. - b2Vec2 r(b2_aabbExtension, b2_aabbExtension); - m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r; - m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r; - m_nodes[proxyId].userData = userData; - m_nodes[proxyId].height = 0; - - InsertLeaf(proxyId); - - return proxyId; -} - -void b2DynamicTree::DestroyProxy(int32 proxyId) -{ - b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); - b2Assert(m_nodes[proxyId].IsLeaf()); - - RemoveLeaf(proxyId); - FreeNode(proxyId); -} - -bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement) -{ - b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); - - b2Assert(m_nodes[proxyId].IsLeaf()); - - if (m_nodes[proxyId].aabb.Contains(aabb)) - { - return false; - } - - RemoveLeaf(proxyId); - - // Extend AABB. - b2AABB b = aabb; - b2Vec2 r(b2_aabbExtension, b2_aabbExtension); - b.lowerBound = b.lowerBound - r; - b.upperBound = b.upperBound + r; - - // Predict AABB displacement. - b2Vec2 d = b2_aabbMultiplier * displacement; - - if (d.x < 0.0f) - { - b.lowerBound.x += d.x; - } - else - { - b.upperBound.x += d.x; - } - - if (d.y < 0.0f) - { - b.lowerBound.y += d.y; - } - else - { - b.upperBound.y += d.y; - } - - m_nodes[proxyId].aabb = b; - - InsertLeaf(proxyId); - return true; -} - -void b2DynamicTree::InsertLeaf(int32 leaf) -{ - ++m_insertionCount; - - if (m_root == b2_nullNode) - { - m_root = leaf; - m_nodes[m_root].parent = b2_nullNode; - return; - } - - // Find the best sibling for this node - b2AABB leafAABB = m_nodes[leaf].aabb; - int32 index = m_root; - while (m_nodes[index].IsLeaf() == false) - { - int32 child1 = m_nodes[index].child1; - int32 child2 = m_nodes[index].child2; - - float32 area = m_nodes[index].aabb.GetPerimeter(); - - b2AABB combinedAABB; - combinedAABB.Combine(m_nodes[index].aabb, leafAABB); - float32 combinedArea = combinedAABB.GetPerimeter(); - - // Cost of creating a new parent for this node and the new leaf - float32 cost = 2.0f * combinedArea; - - // Minimum cost of pushing the leaf further down the tree - float32 inheritanceCost = 2.0f * (combinedArea - area); - - // Cost of descending into child1 - float32 cost1; - if (m_nodes[child1].IsLeaf()) - { - b2AABB aabb; - aabb.Combine(leafAABB, m_nodes[child1].aabb); - cost1 = aabb.GetPerimeter() + inheritanceCost; - } - else - { - b2AABB aabb; - aabb.Combine(leafAABB, m_nodes[child1].aabb); - float32 oldArea = m_nodes[child1].aabb.GetPerimeter(); - float32 newArea = aabb.GetPerimeter(); - cost1 = (newArea - oldArea) + inheritanceCost; - } - - // Cost of descending into child2 - float32 cost2; - if (m_nodes[child2].IsLeaf()) - { - b2AABB aabb; - aabb.Combine(leafAABB, m_nodes[child2].aabb); - cost2 = aabb.GetPerimeter() + inheritanceCost; - } - else - { - b2AABB aabb; - aabb.Combine(leafAABB, m_nodes[child2].aabb); - float32 oldArea = m_nodes[child2].aabb.GetPerimeter(); - float32 newArea = aabb.GetPerimeter(); - cost2 = newArea - oldArea + inheritanceCost; - } - - // Descend according to the minimum cost. - if (cost < cost1 && cost < cost2) - { - break; - } - - // Descend - if (cost1 < cost2) - { - index = child1; - } - else - { - index = child2; - } - } - - int32 sibling = index; - - // Create a new parent. - int32 oldParent = m_nodes[sibling].parent; - int32 newParent = AllocateNode(); - m_nodes[newParent].parent = oldParent; - m_nodes[newParent].userData = nullptr; - m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb); - m_nodes[newParent].height = m_nodes[sibling].height + 1; - - if (oldParent != b2_nullNode) - { - // The sibling was not the root. - if (m_nodes[oldParent].child1 == sibling) - { - m_nodes[oldParent].child1 = newParent; - } - else - { - m_nodes[oldParent].child2 = newParent; - } - - m_nodes[newParent].child1 = sibling; - m_nodes[newParent].child2 = leaf; - m_nodes[sibling].parent = newParent; - m_nodes[leaf].parent = newParent; - } - else - { - // The sibling was the root. - m_nodes[newParent].child1 = sibling; - m_nodes[newParent].child2 = leaf; - m_nodes[sibling].parent = newParent; - m_nodes[leaf].parent = newParent; - m_root = newParent; - } - - // Walk back up the tree fixing heights and AABBs - index = m_nodes[leaf].parent; - while (index != b2_nullNode) - { - index = Balance(index); - - int32 child1 = m_nodes[index].child1; - int32 child2 = m_nodes[index].child2; - - b2Assert(child1 != b2_nullNode); - b2Assert(child2 != b2_nullNode); - - m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height); - m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb); - - index = m_nodes[index].parent; - } - - //Validate(); -} - -void b2DynamicTree::RemoveLeaf(int32 leaf) -{ - if (leaf == m_root) - { - m_root = b2_nullNode; - return; - } - - int32 parent = m_nodes[leaf].parent; - int32 grandParent = m_nodes[parent].parent; - int32 sibling; - if (m_nodes[parent].child1 == leaf) - { - sibling = m_nodes[parent].child2; - } - else - { - sibling = m_nodes[parent].child1; - } - - if (grandParent != b2_nullNode) - { - // Destroy parent and connect sibling to grandParent. - if (m_nodes[grandParent].child1 == parent) - { - m_nodes[grandParent].child1 = sibling; - } - else - { - m_nodes[grandParent].child2 = sibling; - } - m_nodes[sibling].parent = grandParent; - FreeNode(parent); - - // Adjust ancestor bounds. - int32 index = grandParent; - while (index != b2_nullNode) - { - index = Balance(index); - - int32 child1 = m_nodes[index].child1; - int32 child2 = m_nodes[index].child2; - - m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb); - m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height); - - index = m_nodes[index].parent; - } - } - else - { - m_root = sibling; - m_nodes[sibling].parent = b2_nullNode; - FreeNode(parent); - } - - //Validate(); -} - -// Perform a left or right rotation if node A is imbalanced. -// Returns the new root index. -int32 b2DynamicTree::Balance(int32 iA) -{ - b2Assert(iA != b2_nullNode); - - b2TreeNode* A = m_nodes + iA; - if (A->IsLeaf() || A->height < 2) - { - return iA; - } - - int32 iB = A->child1; - int32 iC = A->child2; - b2Assert(0 <= iB && iB < m_nodeCapacity); - b2Assert(0 <= iC && iC < m_nodeCapacity); - - b2TreeNode* B = m_nodes + iB; - b2TreeNode* C = m_nodes + iC; - - int32 balance = C->height - B->height; - - // Rotate C up - if (balance > 1) - { - int32 iF = C->child1; - int32 iG = C->child2; - b2TreeNode* F = m_nodes + iF; - b2TreeNode* G = m_nodes + iG; - b2Assert(0 <= iF && iF < m_nodeCapacity); - b2Assert(0 <= iG && iG < m_nodeCapacity); - - // Swap A and C - C->child1 = iA; - C->parent = A->parent; - A->parent = iC; - - // A's old parent should point to C - if (C->parent != b2_nullNode) - { - if (m_nodes[C->parent].child1 == iA) - { - m_nodes[C->parent].child1 = iC; - } - else - { - b2Assert(m_nodes[C->parent].child2 == iA); - m_nodes[C->parent].child2 = iC; - } - } - else - { - m_root = iC; - } - - // Rotate - if (F->height > G->height) - { - C->child2 = iF; - A->child2 = iG; - G->parent = iA; - A->aabb.Combine(B->aabb, G->aabb); - C->aabb.Combine(A->aabb, F->aabb); - - A->height = 1 + b2Max(B->height, G->height); - C->height = 1 + b2Max(A->height, F->height); - } - else - { - C->child2 = iG; - A->child2 = iF; - F->parent = iA; - A->aabb.Combine(B->aabb, F->aabb); - C->aabb.Combine(A->aabb, G->aabb); - - A->height = 1 + b2Max(B->height, F->height); - C->height = 1 + b2Max(A->height, G->height); - } - - return iC; - } - - // Rotate B up - if (balance < -1) - { - int32 iD = B->child1; - int32 iE = B->child2; - b2TreeNode* D = m_nodes + iD; - b2TreeNode* E = m_nodes + iE; - b2Assert(0 <= iD && iD < m_nodeCapacity); - b2Assert(0 <= iE && iE < m_nodeCapacity); - - // Swap A and B - B->child1 = iA; - B->parent = A->parent; - A->parent = iB; - - // A's old parent should point to B - if (B->parent != b2_nullNode) - { - if (m_nodes[B->parent].child1 == iA) - { - m_nodes[B->parent].child1 = iB; - } - else - { - b2Assert(m_nodes[B->parent].child2 == iA); - m_nodes[B->parent].child2 = iB; - } - } - else - { - m_root = iB; - } - - // Rotate - if (D->height > E->height) - { - B->child2 = iD; - A->child1 = iE; - E->parent = iA; - A->aabb.Combine(C->aabb, E->aabb); - B->aabb.Combine(A->aabb, D->aabb); - - A->height = 1 + b2Max(C->height, E->height); - B->height = 1 + b2Max(A->height, D->height); - } - else - { - B->child2 = iE; - A->child1 = iD; - D->parent = iA; - A->aabb.Combine(C->aabb, D->aabb); - B->aabb.Combine(A->aabb, E->aabb); - - A->height = 1 + b2Max(C->height, D->height); - B->height = 1 + b2Max(A->height, E->height); - } - - return iB; - } - - return iA; -} - -int32 b2DynamicTree::GetHeight() const -{ - if (m_root == b2_nullNode) - { - return 0; - } - - return m_nodes[m_root].height; -} - -// -float32 b2DynamicTree::GetAreaRatio() const -{ - if (m_root == b2_nullNode) - { - return 0.0f; - } - - const b2TreeNode* root = m_nodes + m_root; - float32 rootArea = root->aabb.GetPerimeter(); - - float32 totalArea = 0.0f; - for (int32 i = 0; i < m_nodeCapacity; ++i) - { - const b2TreeNode* node = m_nodes + i; - if (node->height < 0) - { - // Free node in pool - continue; - } - - totalArea += node->aabb.GetPerimeter(); - } - - return totalArea / rootArea; -} - -// Compute the height of a sub-tree. -int32 b2DynamicTree::ComputeHeight(int32 nodeId) const -{ - b2Assert(0 <= nodeId && nodeId < m_nodeCapacity); - b2TreeNode* node = m_nodes + nodeId; - - if (node->IsLeaf()) - { - return 0; - } - - int32 height1 = ComputeHeight(node->child1); - int32 height2 = ComputeHeight(node->child2); - return 1 + b2Max(height1, height2); -} - -int32 b2DynamicTree::ComputeHeight() const -{ - int32 height = ComputeHeight(m_root); - return height; -} - -void b2DynamicTree::ValidateStructure(int32 index) const -{ - if (index == b2_nullNode) - { - return; - } - - if (index == m_root) - { - b2Assert(m_nodes[index].parent == b2_nullNode); - } - - const b2TreeNode* node = m_nodes + index; - - int32 child1 = node->child1; - int32 child2 = node->child2; - - if (node->IsLeaf()) - { - b2Assert(child1 == b2_nullNode); - b2Assert(child2 == b2_nullNode); - b2Assert(node->height == 0); - return; - } - - b2Assert(0 <= child1 && child1 < m_nodeCapacity); - b2Assert(0 <= child2 && child2 < m_nodeCapacity); - - b2Assert(m_nodes[child1].parent == index); - b2Assert(m_nodes[child2].parent == index); - - ValidateStructure(child1); - ValidateStructure(child2); -} - -void b2DynamicTree::ValidateMetrics(int32 index) const -{ - if (index == b2_nullNode) - { - return; - } - - const b2TreeNode* node = m_nodes + index; - - int32 child1 = node->child1; - int32 child2 = node->child2; - - if (node->IsLeaf()) - { - b2Assert(child1 == b2_nullNode); - b2Assert(child2 == b2_nullNode); - b2Assert(node->height == 0); - return; - } - - b2Assert(0 <= child1 && child1 < m_nodeCapacity); - b2Assert(0 <= child2 && child2 < m_nodeCapacity); - - int32 height1 = m_nodes[child1].height; - int32 height2 = m_nodes[child2].height; - int32 height; - height = 1 + b2Max(height1, height2); - b2Assert(node->height == height); - - b2AABB aabb; - aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb); - - b2Assert(aabb.lowerBound == node->aabb.lowerBound); - b2Assert(aabb.upperBound == node->aabb.upperBound); - - ValidateMetrics(child1); - ValidateMetrics(child2); -} - -void b2DynamicTree::Validate() const -{ -#if defined(b2DEBUG) - ValidateStructure(m_root); - ValidateMetrics(m_root); - - int32 freeCount = 0; - int32 freeIndex = m_freeList; - while (freeIndex != b2_nullNode) - { - b2Assert(0 <= freeIndex && freeIndex < m_nodeCapacity); - freeIndex = m_nodes[freeIndex].next; - ++freeCount; - } - - b2Assert(GetHeight() == ComputeHeight()); - - b2Assert(m_nodeCount + freeCount == m_nodeCapacity); -#endif -} - -int32 b2DynamicTree::GetMaxBalance() const -{ - int32 maxBalance = 0; - for (int32 i = 0; i < m_nodeCapacity; ++i) - { - const b2TreeNode* node = m_nodes + i; - if (node->height <= 1) - { - continue; - } - - b2Assert(node->IsLeaf() == false); - - int32 child1 = node->child1; - int32 child2 = node->child2; - int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height); - maxBalance = b2Max(maxBalance, balance); - } - - return maxBalance; -} - -void b2DynamicTree::RebuildBottomUp() -{ - int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32)); - int32 count = 0; - - // Build array of leaves. Free the rest. - for (int32 i = 0; i < m_nodeCapacity; ++i) - { - if (m_nodes[i].height < 0) - { - // free node in pool - continue; - } - - if (m_nodes[i].IsLeaf()) - { - m_nodes[i].parent = b2_nullNode; - nodes[count] = i; - ++count; - } - else - { - FreeNode(i); - } - } - - while (count > 1) - { - float32 minCost = b2_maxFloat; - int32 iMin = -1, jMin = -1; - for (int32 i = 0; i < count; ++i) - { - b2AABB aabbi = m_nodes[nodes[i]].aabb; - - for (int32 j = i + 1; j < count; ++j) - { - b2AABB aabbj = m_nodes[nodes[j]].aabb; - b2AABB b; - b.Combine(aabbi, aabbj); - float32 cost = b.GetPerimeter(); - if (cost < minCost) - { - iMin = i; - jMin = j; - minCost = cost; - } - } - } - - int32 index1 = nodes[iMin]; - int32 index2 = nodes[jMin]; - b2TreeNode* child1 = m_nodes + index1; - b2TreeNode* child2 = m_nodes + index2; - - int32 parentIndex = AllocateNode(); - b2TreeNode* parent = m_nodes + parentIndex; - parent->child1 = index1; - parent->child2 = index2; - parent->height = 1 + b2Max(child1->height, child2->height); - parent->aabb.Combine(child1->aabb, child2->aabb); - parent->parent = b2_nullNode; - - child1->parent = parentIndex; - child2->parent = parentIndex; - - nodes[jMin] = nodes[count-1]; - nodes[iMin] = parentIndex; - --count; - } - - m_root = nodes[0]; - b2Free(nodes); - - Validate(); -} - -void b2DynamicTree::ShiftOrigin(const b2Vec2& newOrigin) -{ - // Build array of leaves. Free the rest. - for (int32 i = 0; i < m_nodeCapacity; ++i) - { - m_nodes[i].aabb.lowerBound -= newOrigin; - m_nodes[i].aabb.upperBound -= newOrigin; - } -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2DynamicTree.h b/src/libjin/3rdparty/Box2D/Collision/b2DynamicTree.h deleted file mode 100644 index e52b44b..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2DynamicTree.h +++ /dev/null @@ -1,289 +0,0 @@ -/* -* Copyright (c) 2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_DYNAMIC_TREE_H -#define B2_DYNAMIC_TREE_H - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Common/b2GrowableStack.h" - -#define b2_nullNode (-1) - -/// A node in the dynamic tree. The client does not interact with this directly. -struct b2TreeNode -{ - bool IsLeaf() const - { - return child1 == b2_nullNode; - } - - /// Enlarged AABB - b2AABB aabb; - - void* userData; - - union - { - int32 parent; - int32 next; - }; - - int32 child1; - int32 child2; - - // leaf = 0, free node = -1 - int32 height; -}; - -/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt. -/// A dynamic tree arranges data in a binary tree to accelerate -/// queries such as volume queries and ray casts. Leafs are proxies -/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor -/// so that the proxy AABB is bigger than the client object. This allows the client -/// object to move by small amounts without triggering a tree update. -/// -/// Nodes are pooled and relocatable, so we use node indices rather than pointers. -class b2DynamicTree -{ -public: - /// Constructing the tree initializes the node pool. - b2DynamicTree(); - - /// Destroy the tree, freeing the node pool. - ~b2DynamicTree(); - - /// Create a proxy. Provide a tight fitting AABB and a userData pointer. - int32 CreateProxy(const b2AABB& aabb, void* userData); - - /// Destroy a proxy. This asserts if the id is invalid. - void DestroyProxy(int32 proxyId); - - /// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB, - /// then the proxy is removed from the tree and re-inserted. Otherwise - /// the function returns immediately. - /// @return true if the proxy was re-inserted. - bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement); - - /// Get proxy user data. - /// @return the proxy user data or 0 if the id is invalid. - void* GetUserData(int32 proxyId) const; - - /// Get the fat AABB for a proxy. - const b2AABB& GetFatAABB(int32 proxyId) const; - - /// Query an AABB for overlapping proxies. The callback class - /// is called for each proxy that overlaps the supplied AABB. - template <typename T> - void Query(T* callback, const b2AABB& aabb) const; - - /// Ray-cast against the proxies in the tree. This relies on the callback - /// to perform a exact ray-cast in the case were the proxy contains a shape. - /// The callback also performs the any collision filtering. This has performance - /// roughly equal to k * log(n), where k is the number of collisions and n is the - /// number of proxies in the tree. - /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). - /// @param callback a callback class that is called for each proxy that is hit by the ray. - template <typename T> - void RayCast(T* callback, const b2RayCastInput& input) const; - - /// Validate this tree. For testing. - void Validate() const; - - /// Compute the height of the binary tree in O(N) time. Should not be - /// called often. - int32 GetHeight() const; - - /// Get the maximum balance of an node in the tree. The balance is the difference - /// in height of the two children of a node. - int32 GetMaxBalance() const; - - /// Get the ratio of the sum of the node areas to the root area. - float32 GetAreaRatio() const; - - /// Build an optimal tree. Very expensive. For testing. - void RebuildBottomUp(); - - /// Shift the world origin. Useful for large worlds. - /// The shift formula is: position -= newOrigin - /// @param newOrigin the new origin with respect to the old origin - void ShiftOrigin(const b2Vec2& newOrigin); - -private: - - int32 AllocateNode(); - void FreeNode(int32 node); - - void InsertLeaf(int32 node); - void RemoveLeaf(int32 node); - - int32 Balance(int32 index); - - int32 ComputeHeight() const; - int32 ComputeHeight(int32 nodeId) const; - - void ValidateStructure(int32 index) const; - void ValidateMetrics(int32 index) const; - - int32 m_root; - - b2TreeNode* m_nodes; - int32 m_nodeCount; - int32 m_nodeCapacity; - - int32 m_freeList; - - /// This is used to incrementally traverse the tree for re-balancing. - uint32 m_path; - - int32 m_insertionCount; -}; - -inline void* b2DynamicTree::GetUserData(int32 proxyId) const -{ - b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); - return m_nodes[proxyId].userData; -} - -inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const -{ - b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); - return m_nodes[proxyId].aabb; -} - -template <typename T> -inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const -{ - b2GrowableStack<int32, 256> stack; - stack.Push(m_root); - - while (stack.GetCount() > 0) - { - int32 nodeId = stack.Pop(); - if (nodeId == b2_nullNode) - { - continue; - } - - const b2TreeNode* node = m_nodes + nodeId; - - if (b2TestOverlap(node->aabb, aabb)) - { - if (node->IsLeaf()) - { - bool proceed = callback->QueryCallback(nodeId); - if (proceed == false) - { - return; - } - } - else - { - stack.Push(node->child1); - stack.Push(node->child2); - } - } - } -} - -template <typename T> -inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const -{ - b2Vec2 p1 = input.p1; - b2Vec2 p2 = input.p2; - b2Vec2 r = p2 - p1; - b2Assert(r.LengthSquared() > 0.0f); - r.Normalize(); - - // v is perpendicular to the segment. - b2Vec2 v = b2Cross(1.0f, r); - b2Vec2 abs_v = b2Abs(v); - - // Separating axis for segment (Gino, p80). - // |dot(v, p1 - c)| > dot(|v|, h) - - float32 maxFraction = input.maxFraction; - - // Build a bounding box for the segment. - b2AABB segmentAABB; - { - b2Vec2 t = p1 + maxFraction * (p2 - p1); - segmentAABB.lowerBound = b2Min(p1, t); - segmentAABB.upperBound = b2Max(p1, t); - } - - b2GrowableStack<int32, 256> stack; - stack.Push(m_root); - - while (stack.GetCount() > 0) - { - int32 nodeId = stack.Pop(); - if (nodeId == b2_nullNode) - { - continue; - } - - const b2TreeNode* node = m_nodes + nodeId; - - if (b2TestOverlap(node->aabb, segmentAABB) == false) - { - continue; - } - - // Separating axis for segment (Gino, p80). - // |dot(v, p1 - c)| > dot(|v|, h) - b2Vec2 c = node->aabb.GetCenter(); - b2Vec2 h = node->aabb.GetExtents(); - float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h); - if (separation > 0.0f) - { - continue; - } - - if (node->IsLeaf()) - { - b2RayCastInput subInput; - subInput.p1 = input.p1; - subInput.p2 = input.p2; - subInput.maxFraction = maxFraction; - - float32 value = callback->RayCastCallback(subInput, nodeId); - - if (value == 0.0f) - { - // The client has terminated the ray cast. - return; - } - - if (value > 0.0f) - { - // Update segment bounding box. - maxFraction = value; - b2Vec2 t = p1 + maxFraction * (p2 - p1); - segmentAABB.lowerBound = b2Min(p1, t); - segmentAABB.upperBound = b2Max(p1, t); - } - } - else - { - stack.Push(node->child1); - stack.Push(node->child2); - } - } -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Collision/b2TimeOfImpact.cpp b/src/libjin/3rdparty/Box2D/Collision/b2TimeOfImpact.cpp deleted file mode 100644 index 4bc1769..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2TimeOfImpact.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/* -* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/b2Distance.h" -#include "Box2D/Collision/b2TimeOfImpact.h" -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" -#include "Box2D/Common/b2Timer.h" - -#include <stdio.h> - -float32 b2_toiTime, b2_toiMaxTime; -int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; -int32 b2_toiRootIters, b2_toiMaxRootIters; - -// -struct b2SeparationFunction -{ - enum Type - { - e_points, - e_faceA, - e_faceB - }; - - // TODO_ERIN might not need to return the separation - - float32 Initialize(const b2SimplexCache* cache, - const b2DistanceProxy* proxyA, const b2Sweep& sweepA, - const b2DistanceProxy* proxyB, const b2Sweep& sweepB, - float32 t1) - { - m_proxyA = proxyA; - m_proxyB = proxyB; - int32 count = cache->count; - b2Assert(0 < count && count < 3); - - m_sweepA = sweepA; - m_sweepB = sweepB; - - b2Transform xfA, xfB; - m_sweepA.GetTransform(&xfA, t1); - m_sweepB.GetTransform(&xfB, t1); - - if (count == 1) - { - m_type = e_points; - b2Vec2 localPointA = m_proxyA->GetVertex(cache->indexA[0]); - b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]); - b2Vec2 pointA = b2Mul(xfA, localPointA); - b2Vec2 pointB = b2Mul(xfB, localPointB); - m_axis = pointB - pointA; - float32 s = m_axis.Normalize(); - return s; - } - else if (cache->indexA[0] == cache->indexA[1]) - { - // Two points on B and one on A. - m_type = e_faceB; - b2Vec2 localPointB1 = proxyB->GetVertex(cache->indexB[0]); - b2Vec2 localPointB2 = proxyB->GetVertex(cache->indexB[1]); - - m_axis = b2Cross(localPointB2 - localPointB1, 1.0f); - m_axis.Normalize(); - b2Vec2 normal = b2Mul(xfB.q, m_axis); - - m_localPoint = 0.5f * (localPointB1 + localPointB2); - b2Vec2 pointB = b2Mul(xfB, m_localPoint); - - b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]); - b2Vec2 pointA = b2Mul(xfA, localPointA); - - float32 s = b2Dot(pointA - pointB, normal); - if (s < 0.0f) - { - m_axis = -m_axis; - s = -s; - } - return s; - } - else - { - // Two points on A and one or two points on B. - m_type = e_faceA; - b2Vec2 localPointA1 = m_proxyA->GetVertex(cache->indexA[0]); - b2Vec2 localPointA2 = m_proxyA->GetVertex(cache->indexA[1]); - - m_axis = b2Cross(localPointA2 - localPointA1, 1.0f); - m_axis.Normalize(); - b2Vec2 normal = b2Mul(xfA.q, m_axis); - - m_localPoint = 0.5f * (localPointA1 + localPointA2); - b2Vec2 pointA = b2Mul(xfA, m_localPoint); - - b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]); - b2Vec2 pointB = b2Mul(xfB, localPointB); - - float32 s = b2Dot(pointB - pointA, normal); - if (s < 0.0f) - { - m_axis = -m_axis; - s = -s; - } - return s; - } - } - - // - float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const - { - b2Transform xfA, xfB; - m_sweepA.GetTransform(&xfA, t); - m_sweepB.GetTransform(&xfB, t); - - switch (m_type) - { - case e_points: - { - b2Vec2 axisA = b2MulT(xfA.q, m_axis); - b2Vec2 axisB = b2MulT(xfB.q, -m_axis); - - *indexA = m_proxyA->GetSupport(axisA); - *indexB = m_proxyB->GetSupport(axisB); - - b2Vec2 localPointA = m_proxyA->GetVertex(*indexA); - b2Vec2 localPointB = m_proxyB->GetVertex(*indexB); - - b2Vec2 pointA = b2Mul(xfA, localPointA); - b2Vec2 pointB = b2Mul(xfB, localPointB); - - float32 separation = b2Dot(pointB - pointA, m_axis); - return separation; - } - - case e_faceA: - { - b2Vec2 normal = b2Mul(xfA.q, m_axis); - b2Vec2 pointA = b2Mul(xfA, m_localPoint); - - b2Vec2 axisB = b2MulT(xfB.q, -normal); - - *indexA = -1; - *indexB = m_proxyB->GetSupport(axisB); - - b2Vec2 localPointB = m_proxyB->GetVertex(*indexB); - b2Vec2 pointB = b2Mul(xfB, localPointB); - - float32 separation = b2Dot(pointB - pointA, normal); - return separation; - } - - case e_faceB: - { - b2Vec2 normal = b2Mul(xfB.q, m_axis); - b2Vec2 pointB = b2Mul(xfB, m_localPoint); - - b2Vec2 axisA = b2MulT(xfA.q, -normal); - - *indexB = -1; - *indexA = m_proxyA->GetSupport(axisA); - - b2Vec2 localPointA = m_proxyA->GetVertex(*indexA); - b2Vec2 pointA = b2Mul(xfA, localPointA); - - float32 separation = b2Dot(pointA - pointB, normal); - return separation; - } - - default: - b2Assert(false); - *indexA = -1; - *indexB = -1; - return 0.0f; - } - } - - // - float32 Evaluate(int32 indexA, int32 indexB, float32 t) const - { - b2Transform xfA, xfB; - m_sweepA.GetTransform(&xfA, t); - m_sweepB.GetTransform(&xfB, t); - - switch (m_type) - { - case e_points: - { - b2Vec2 localPointA = m_proxyA->GetVertex(indexA); - b2Vec2 localPointB = m_proxyB->GetVertex(indexB); - - b2Vec2 pointA = b2Mul(xfA, localPointA); - b2Vec2 pointB = b2Mul(xfB, localPointB); - float32 separation = b2Dot(pointB - pointA, m_axis); - - return separation; - } - - case e_faceA: - { - b2Vec2 normal = b2Mul(xfA.q, m_axis); - b2Vec2 pointA = b2Mul(xfA, m_localPoint); - - b2Vec2 localPointB = m_proxyB->GetVertex(indexB); - b2Vec2 pointB = b2Mul(xfB, localPointB); - - float32 separation = b2Dot(pointB - pointA, normal); - return separation; - } - - case e_faceB: - { - b2Vec2 normal = b2Mul(xfB.q, m_axis); - b2Vec2 pointB = b2Mul(xfB, m_localPoint); - - b2Vec2 localPointA = m_proxyA->GetVertex(indexA); - b2Vec2 pointA = b2Mul(xfA, localPointA); - - float32 separation = b2Dot(pointA - pointB, normal); - return separation; - } - - default: - b2Assert(false); - return 0.0f; - } - } - - const b2DistanceProxy* m_proxyA; - const b2DistanceProxy* m_proxyB; - b2Sweep m_sweepA, m_sweepB; - Type m_type; - b2Vec2 m_localPoint; - b2Vec2 m_axis; -}; - -// CCD via the local separating axis method. This seeks progression -// by computing the largest time at which separation is maintained. -void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) -{ - b2Timer timer; - - ++b2_toiCalls; - - output->state = b2TOIOutput::e_unknown; - output->t = input->tMax; - - const b2DistanceProxy* proxyA = &input->proxyA; - const b2DistanceProxy* proxyB = &input->proxyB; - - b2Sweep sweepA = input->sweepA; - b2Sweep sweepB = input->sweepB; - - // Large rotations can make the root finder fail, so we normalize the - // sweep angles. - sweepA.Normalize(); - sweepB.Normalize(); - - float32 tMax = input->tMax; - - float32 totalRadius = proxyA->m_radius + proxyB->m_radius; - float32 target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop); - float32 tolerance = 0.25f * b2_linearSlop; - b2Assert(target > tolerance); - - float32 t1 = 0.0f; - const int32 k_maxIterations = 20; // TODO_ERIN b2Settings - int32 iter = 0; - - // Prepare input for distance query. - b2SimplexCache cache; - cache.count = 0; - b2DistanceInput distanceInput; - distanceInput.proxyA = input->proxyA; - distanceInput.proxyB = input->proxyB; - distanceInput.useRadii = false; - - // The outer loop progressively attempts to compute new separating axes. - // This loop terminates when an axis is repeated (no progress is made). - for(;;) - { - b2Transform xfA, xfB; - sweepA.GetTransform(&xfA, t1); - sweepB.GetTransform(&xfB, t1); - - // Get the distance between shapes. We can also use the results - // to get a separating axis. - distanceInput.transformA = xfA; - distanceInput.transformB = xfB; - b2DistanceOutput distanceOutput; - b2Distance(&distanceOutput, &cache, &distanceInput); - - // If the shapes are overlapped, we give up on continuous collision. - if (distanceOutput.distance <= 0.0f) - { - // Failure! - output->state = b2TOIOutput::e_overlapped; - output->t = 0.0f; - break; - } - - if (distanceOutput.distance < target + tolerance) - { - // Victory! - output->state = b2TOIOutput::e_touching; - output->t = t1; - break; - } - - // Initialize the separating axis. - b2SeparationFunction fcn; - fcn.Initialize(&cache, proxyA, sweepA, proxyB, sweepB, t1); -#if 0 - // Dump the curve seen by the root finder - { - const int32 N = 100; - float32 dx = 1.0f / N; - float32 xs[N+1]; - float32 fs[N+1]; - - float32 x = 0.0f; - - for (int32 i = 0; i <= N; ++i) - { - sweepA.GetTransform(&xfA, x); - sweepB.GetTransform(&xfB, x); - float32 f = fcn.Evaluate(xfA, xfB) - target; - - printf("%g %g\n", x, f); - - xs[i] = x; - fs[i] = f; - - x += dx; - } - } -#endif - - // Compute the TOI on the separating axis. We do this by successively - // resolving the deepest point. This loop is bounded by the number of vertices. - bool done = false; - float32 t2 = tMax; - int32 pushBackIter = 0; - for (;;) - { - // Find the deepest point at t2. Store the witness point indices. - int32 indexA, indexB; - float32 s2 = fcn.FindMinSeparation(&indexA, &indexB, t2); - - // Is the final configuration separated? - if (s2 > target + tolerance) - { - // Victory! - output->state = b2TOIOutput::e_separated; - output->t = tMax; - done = true; - break; - } - - // Has the separation reached tolerance? - if (s2 > target - tolerance) - { - // Advance the sweeps - t1 = t2; - break; - } - - // Compute the initial separation of the witness points. - float32 s1 = fcn.Evaluate(indexA, indexB, t1); - - // Check for initial overlap. This might happen if the root finder - // runs out of iterations. - if (s1 < target - tolerance) - { - output->state = b2TOIOutput::e_failed; - output->t = t1; - done = true; - break; - } - - // Check for touching - if (s1 <= target + tolerance) - { - // Victory! t1 should hold the TOI (could be 0.0). - output->state = b2TOIOutput::e_touching; - output->t = t1; - done = true; - break; - } - - // Compute 1D root of: f(x) - target = 0 - int32 rootIterCount = 0; - float32 a1 = t1, a2 = t2; - for (;;) - { - // Use a mix of the secant rule and bisection. - float32 t; - if (rootIterCount & 1) - { - // Secant rule to improve convergence. - t = a1 + (target - s1) * (a2 - a1) / (s2 - s1); - } - else - { - // Bisection to guarantee progress. - t = 0.5f * (a1 + a2); - } - - ++rootIterCount; - ++b2_toiRootIters; - - float32 s = fcn.Evaluate(indexA, indexB, t); - - if (b2Abs(s - target) < tolerance) - { - // t2 holds a tentative value for t1 - t2 = t; - break; - } - - // Ensure we continue to bracket the root. - if (s > target) - { - a1 = t; - s1 = s; - } - else - { - a2 = t; - s2 = s; - } - - if (rootIterCount == 50) - { - break; - } - } - - b2_toiMaxRootIters = b2Max(b2_toiMaxRootIters, rootIterCount); - - ++pushBackIter; - - if (pushBackIter == b2_maxPolygonVertices) - { - break; - } - } - - ++iter; - ++b2_toiIters; - - if (done) - { - break; - } - - if (iter == k_maxIterations) - { - // Root finder got stuck. Semi-victory. - output->state = b2TOIOutput::e_failed; - output->t = t1; - break; - } - } - - b2_toiMaxIters = b2Max(b2_toiMaxIters, iter); - - float32 time = timer.GetMilliseconds(); - b2_toiMaxTime = b2Max(b2_toiMaxTime, time); - b2_toiTime += time; -} diff --git a/src/libjin/3rdparty/Box2D/Collision/b2TimeOfImpact.h b/src/libjin/3rdparty/Box2D/Collision/b2TimeOfImpact.h deleted file mode 100644 index 3af2c32..0000000 --- a/src/libjin/3rdparty/Box2D/Collision/b2TimeOfImpact.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_TIME_OF_IMPACT_H -#define B2_TIME_OF_IMPACT_H - -#include "Box2D/Common/b2Math.h" -#include "Box2D/Collision/b2Distance.h" - -/// Input parameters for b2TimeOfImpact -struct b2TOIInput -{ - b2DistanceProxy proxyA; - b2DistanceProxy proxyB; - b2Sweep sweepA; - b2Sweep sweepB; - float32 tMax; // defines sweep interval [0, tMax] -}; - -/// Output parameters for b2TimeOfImpact. -struct b2TOIOutput -{ - enum State - { - e_unknown, - e_failed, - e_overlapped, - e_touching, - e_separated - }; - - State state; - float32 t; -}; - -/// Compute the upper bound on time before two shapes penetrate. Time is represented as -/// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate, -/// non-tunneling collisions. If you change the time interval, you should call this function -/// again. -/// Note: use b2Distance to compute the contact point and normal at the time of impact. -void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input); - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2BlockAllocator.cpp b/src/libjin/3rdparty/Box2D/Common/b2BlockAllocator.cpp deleted file mode 100644 index b721de8..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2BlockAllocator.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Common/b2BlockAllocator.h" -#include <limits.h> -#include <string.h> -#include <stddef.h> - -int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = -{ - 16, // 0 - 32, // 1 - 64, // 2 - 96, // 3 - 128, // 4 - 160, // 5 - 192, // 6 - 224, // 7 - 256, // 8 - 320, // 9 - 384, // 10 - 448, // 11 - 512, // 12 - 640, // 13 -}; -uint8 b2BlockAllocator::s_blockSizeLookup[b2_maxBlockSize + 1]; -bool b2BlockAllocator::s_blockSizeLookupInitialized; - -struct b2Chunk -{ - int32 blockSize; - b2Block* blocks; -}; - -struct b2Block -{ - b2Block* next; -}; - -b2BlockAllocator::b2BlockAllocator() -{ - b2Assert(b2_blockSizes < UCHAR_MAX); - - m_chunkSpace = b2_chunkArrayIncrement; - m_chunkCount = 0; - m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk)); - - memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk)); - memset(m_freeLists, 0, sizeof(m_freeLists)); - - if (s_blockSizeLookupInitialized == false) - { - int32 j = 0; - for (int32 i = 1; i <= b2_maxBlockSize; ++i) - { - b2Assert(j < b2_blockSizes); - if (i <= s_blockSizes[j]) - { - s_blockSizeLookup[i] = (uint8)j; - } - else - { - ++j; - s_blockSizeLookup[i] = (uint8)j; - } - } - - s_blockSizeLookupInitialized = true; - } -} - -b2BlockAllocator::~b2BlockAllocator() -{ - for (int32 i = 0; i < m_chunkCount; ++i) - { - b2Free(m_chunks[i].blocks); - } - - b2Free(m_chunks); -} - -void* b2BlockAllocator::Allocate(int32 size) -{ - if (size == 0) - return nullptr; - - b2Assert(0 < size); - - if (size > b2_maxBlockSize) - { - return b2Alloc(size); - } - - int32 index = s_blockSizeLookup[size]; - b2Assert(0 <= index && index < b2_blockSizes); - - if (m_freeLists[index]) - { - b2Block* block = m_freeLists[index]; - m_freeLists[index] = block->next; - return block; - } - else - { - if (m_chunkCount == m_chunkSpace) - { - b2Chunk* oldChunks = m_chunks; - m_chunkSpace += b2_chunkArrayIncrement; - m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk)); - memcpy(m_chunks, oldChunks, m_chunkCount * sizeof(b2Chunk)); - memset(m_chunks + m_chunkCount, 0, b2_chunkArrayIncrement * sizeof(b2Chunk)); - b2Free(oldChunks); - } - - b2Chunk* chunk = m_chunks + m_chunkCount; - chunk->blocks = (b2Block*)b2Alloc(b2_chunkSize); -#if defined(_DEBUG) - memset(chunk->blocks, 0xcd, b2_chunkSize); -#endif - int32 blockSize = s_blockSizes[index]; - chunk->blockSize = blockSize; - int32 blockCount = b2_chunkSize / blockSize; - b2Assert(blockCount * blockSize <= b2_chunkSize); - for (int32 i = 0; i < blockCount - 1; ++i) - { - b2Block* block = (b2Block*)((int8*)chunk->blocks + blockSize * i); - b2Block* next = (b2Block*)((int8*)chunk->blocks + blockSize * (i + 1)); - block->next = next; - } - b2Block* last = (b2Block*)((int8*)chunk->blocks + blockSize * (blockCount - 1)); - last->next = nullptr; - - m_freeLists[index] = chunk->blocks->next; - ++m_chunkCount; - - return chunk->blocks; - } -} - -void b2BlockAllocator::Free(void* p, int32 size) -{ - if (size == 0) - { - return; - } - - b2Assert(0 < size); - - if (size > b2_maxBlockSize) - { - b2Free(p); - return; - } - - int32 index = s_blockSizeLookup[size]; - b2Assert(0 <= index && index < b2_blockSizes); - -#ifdef _DEBUG - // Verify the memory address and size is valid. - int32 blockSize = s_blockSizes[index]; - bool found = false; - for (int32 i = 0; i < m_chunkCount; ++i) - { - b2Chunk* chunk = m_chunks + i; - if (chunk->blockSize != blockSize) - { - b2Assert( (int8*)p + blockSize <= (int8*)chunk->blocks || - (int8*)chunk->blocks + b2_chunkSize <= (int8*)p); - } - else - { - if ((int8*)chunk->blocks <= (int8*)p && (int8*)p + blockSize <= (int8*)chunk->blocks + b2_chunkSize) - { - found = true; - } - } - } - - b2Assert(found); - - memset(p, 0xfd, blockSize); -#endif - - b2Block* block = (b2Block*)p; - block->next = m_freeLists[index]; - m_freeLists[index] = block; -} - -void b2BlockAllocator::Clear() -{ - for (int32 i = 0; i < m_chunkCount; ++i) - { - b2Free(m_chunks[i].blocks); - } - - m_chunkCount = 0; - memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk)); - - memset(m_freeLists, 0, sizeof(m_freeLists)); -} diff --git a/src/libjin/3rdparty/Box2D/Common/b2BlockAllocator.h b/src/libjin/3rdparty/Box2D/Common/b2BlockAllocator.h deleted file mode 100644 index 8dfa254..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2BlockAllocator.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_BLOCK_ALLOCATOR_H -#define B2_BLOCK_ALLOCATOR_H - -#include "Box2D/Common/b2Settings.h" - -const int32 b2_chunkSize = 16 * 1024; -const int32 b2_maxBlockSize = 640; -const int32 b2_blockSizes = 14; -const int32 b2_chunkArrayIncrement = 128; - -struct b2Block; -struct b2Chunk; - -/// This is a small object allocator used for allocating small -/// objects that persist for more than one time step. -/// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp -class b2BlockAllocator -{ -public: - b2BlockAllocator(); - ~b2BlockAllocator(); - - /// Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize. - void* Allocate(int32 size); - - /// Free memory. This will use b2Free if the size is larger than b2_maxBlockSize. - void Free(void* p, int32 size); - - void Clear(); - -private: - - b2Chunk* m_chunks; - int32 m_chunkCount; - int32 m_chunkSpace; - - b2Block* m_freeLists[b2_blockSizes]; - - static int32 s_blockSizes[b2_blockSizes]; - static uint8 s_blockSizeLookup[b2_maxBlockSize + 1]; - static bool s_blockSizeLookupInitialized; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2Draw.cpp b/src/libjin/3rdparty/Box2D/Common/b2Draw.cpp deleted file mode 100644 index 4d412cd..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Draw.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Copyright (c) 2011 Erin Catto http://box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Common/b2Draw.h" - -b2Draw::b2Draw() -{ - m_drawFlags = 0; -} - -void b2Draw::SetFlags(uint32 flags) -{ - m_drawFlags = flags; -} - -uint32 b2Draw::GetFlags() const -{ - return m_drawFlags; -} - -void b2Draw::AppendFlags(uint32 flags) -{ - m_drawFlags |= flags; -} - -void b2Draw::ClearFlags(uint32 flags) -{ - m_drawFlags &= ~flags; -} diff --git a/src/libjin/3rdparty/Box2D/Common/b2Draw.h b/src/libjin/3rdparty/Box2D/Common/b2Draw.h deleted file mode 100644 index ef81826..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Draw.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -* Copyright (c) 2011 Erin Catto http://box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_DRAW_H -#define B2_DRAW_H - -#include "Box2D/Common/b2Math.h" - -/// Color for debug drawing. Each value has the range [0,1]. -struct b2Color -{ - b2Color() {} - b2Color(float32 rIn, float32 gIn, float32 bIn, float32 aIn = 1.0f) - { - r = rIn; g = gIn; b = bIn; a = aIn; - } - - void Set(float32 rIn, float32 gIn, float32 bIn, float32 aIn = 1.0f) - { - r = rIn; g = gIn; b = bIn; a = aIn; - } - - float32 r, g, b, a; -}; - -/// Implement and register this class with a b2World to provide debug drawing of physics -/// entities in your game. -class b2Draw -{ -public: - b2Draw(); - - virtual ~b2Draw() {} - - enum - { - e_shapeBit = 0x0001, ///< draw shapes - e_jointBit = 0x0002, ///< draw joint connections - e_aabbBit = 0x0004, ///< draw axis aligned bounding boxes - e_pairBit = 0x0008, ///< draw broad-phase pairs - e_centerOfMassBit = 0x0010 ///< draw center of mass frame - }; - - /// Set the drawing flags. - void SetFlags(uint32 flags); - - /// Get the drawing flags. - uint32 GetFlags() const; - - /// Append flags to the current flags. - void AppendFlags(uint32 flags); - - /// Clear flags from the current flags. - void ClearFlags(uint32 flags); - - /// Draw a closed polygon provided in CCW order. - virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0; - - /// Draw a solid closed polygon provided in CCW order. - virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0; - - /// Draw a circle. - virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0; - - /// Draw a solid circle. - virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0; - - /// Draw a line segment. - virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0; - - /// Draw a transform. Choose your own length scale. - /// @param xf a transform. - virtual void DrawTransform(const b2Transform& xf) = 0; - - /// Draw a point. - virtual void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color) = 0; - -protected: - uint32 m_drawFlags; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2GrowableStack.h b/src/libjin/3rdparty/Box2D/Common/b2GrowableStack.h deleted file mode 100644 index 8d239c7..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2GrowableStack.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -* Copyright (c) 2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_GROWABLE_STACK_H -#define B2_GROWABLE_STACK_H -#include "Box2D/Common/b2Settings.h" -#include <string.h> - -/// This is a growable LIFO stack with an initial capacity of N. -/// If the stack size exceeds the initial capacity, the heap is used -/// to increase the size of the stack. -template <typename T, int32 N> -class b2GrowableStack -{ -public: - b2GrowableStack() - { - m_stack = m_array; - m_count = 0; - m_capacity = N; - } - - ~b2GrowableStack() - { - if (m_stack != m_array) - { - b2Free(m_stack); - m_stack = nullptr; - } - } - - void Push(const T& element) - { - if (m_count == m_capacity) - { - T* old = m_stack; - m_capacity *= 2; - m_stack = (T*)b2Alloc(m_capacity * sizeof(T)); - memcpy(m_stack, old, m_count * sizeof(T)); - if (old != m_array) - { - b2Free(old); - } - } - - m_stack[m_count] = element; - ++m_count; - } - - T Pop() - { - b2Assert(m_count > 0); - --m_count; - return m_stack[m_count]; - } - - int32 GetCount() - { - return m_count; - } - -private: - T* m_stack; - T m_array[N]; - int32 m_count; - int32 m_capacity; -}; - - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2Math.cpp b/src/libjin/3rdparty/Box2D/Common/b2Math.cpp deleted file mode 100644 index f9f5f39..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Math.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* -* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Common/b2Math.h" - -const b2Vec2 b2Vec2_zero(0.0f, 0.0f); - -/// Solve A * x = b, where b is a column vector. This is more efficient -/// than computing the inverse in one-shot cases. -b2Vec3 b2Mat33::Solve33(const b2Vec3& b) const -{ - float32 det = b2Dot(ex, b2Cross(ey, ez)); - if (det != 0.0f) - { - det = 1.0f / det; - } - b2Vec3 x; - x.x = det * b2Dot(b, b2Cross(ey, ez)); - x.y = det * b2Dot(ex, b2Cross(b, ez)); - x.z = det * b2Dot(ex, b2Cross(ey, b)); - return x; -} - -/// Solve A * x = b, where b is a column vector. This is more efficient -/// than computing the inverse in one-shot cases. -b2Vec2 b2Mat33::Solve22(const b2Vec2& b) const -{ - float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y; - float32 det = a11 * a22 - a12 * a21; - if (det != 0.0f) - { - det = 1.0f / det; - } - b2Vec2 x; - x.x = det * (a22 * b.x - a12 * b.y); - x.y = det * (a11 * b.y - a21 * b.x); - return x; -} - -/// -void b2Mat33::GetInverse22(b2Mat33* M) const -{ - float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y; - float32 det = a * d - b * c; - if (det != 0.0f) - { - det = 1.0f / det; - } - - M->ex.x = det * d; M->ey.x = -det * b; M->ex.z = 0.0f; - M->ex.y = -det * c; M->ey.y = det * a; M->ey.z = 0.0f; - M->ez.x = 0.0f; M->ez.y = 0.0f; M->ez.z = 0.0f; -} - -/// Returns the zero matrix if singular. -void b2Mat33::GetSymInverse33(b2Mat33* M) const -{ - float32 det = b2Dot(ex, b2Cross(ey, ez)); - if (det != 0.0f) - { - det = 1.0f / det; - } - - float32 a11 = ex.x, a12 = ey.x, a13 = ez.x; - float32 a22 = ey.y, a23 = ez.y; - float32 a33 = ez.z; - - M->ex.x = det * (a22 * a33 - a23 * a23); - M->ex.y = det * (a13 * a23 - a12 * a33); - M->ex.z = det * (a12 * a23 - a13 * a22); - - M->ey.x = M->ex.y; - M->ey.y = det * (a11 * a33 - a13 * a13); - M->ey.z = det * (a13 * a12 - a11 * a23); - - M->ez.x = M->ex.z; - M->ez.y = M->ey.z; - M->ez.z = det * (a11 * a22 - a12 * a12); -} diff --git a/src/libjin/3rdparty/Box2D/Common/b2Math.h b/src/libjin/3rdparty/Box2D/Common/b2Math.h deleted file mode 100644 index 7a816e5..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Math.h +++ /dev/null @@ -1,707 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_MATH_H -#define B2_MATH_H - -#include "Box2D/Common/b2Settings.h" -#include <math.h> - -/// This function is used to ensure that a floating point number is not a NaN or infinity. -inline bool b2IsValid(float32 x) -{ - return isfinite(x); -} - -#define b2Sqrt(x) sqrtf(x) -#define b2Atan2(y, x) atan2f(y, x) - -/// A 2D column vector. -struct b2Vec2 -{ - /// Default constructor does nothing (for performance). - b2Vec2() {} - - /// Construct using coordinates. - b2Vec2(float32 xIn, float32 yIn) : x(xIn), y(yIn) {} - - /// Set this vector to all zeros. - void SetZero() { x = 0.0f; y = 0.0f; } - - /// Set this vector to some specified coordinates. - void Set(float32 x_, float32 y_) { x = x_; y = y_; } - - /// Negate this vector. - b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; } - - /// Read from and indexed element. - float32 operator () (int32 i) const - { - return (&x)[i]; - } - - /// Write to an indexed element. - float32& operator () (int32 i) - { - return (&x)[i]; - } - - /// Add a vector to this vector. - void operator += (const b2Vec2& v) - { - x += v.x; y += v.y; - } - - /// Subtract a vector from this vector. - void operator -= (const b2Vec2& v) - { - x -= v.x; y -= v.y; - } - - /// Multiply this vector by a scalar. - void operator *= (float32 a) - { - x *= a; y *= a; - } - - /// Get the length of this vector (the norm). - float32 Length() const - { - return b2Sqrt(x * x + y * y); - } - - /// Get the length squared. For performance, use this instead of - /// b2Vec2::Length (if possible). - float32 LengthSquared() const - { - return x * x + y * y; - } - - /// Convert this vector into a unit vector. Returns the length. - float32 Normalize() - { - float32 length = Length(); - if (length < b2_epsilon) - { - return 0.0f; - } - float32 invLength = 1.0f / length; - x *= invLength; - y *= invLength; - - return length; - } - - /// Does this vector contain finite coordinates? - bool IsValid() const - { - return b2IsValid(x) && b2IsValid(y); - } - - /// Get the skew vector such that dot(skew_vec, other) == cross(vec, other) - b2Vec2 Skew() const - { - return b2Vec2(-y, x); - } - - float32 x, y; -}; - -/// A 2D column vector with 3 elements. -struct b2Vec3 -{ - /// Default constructor does nothing (for performance). - b2Vec3() {} - - /// Construct using coordinates. - b2Vec3(float32 xIn, float32 yIn, float32 zIn) : x(xIn), y(yIn), z(zIn) {} - - /// Set this vector to all zeros. - void SetZero() { x = 0.0f; y = 0.0f; z = 0.0f; } - - /// Set this vector to some specified coordinates. - void Set(float32 x_, float32 y_, float32 z_) { x = x_; y = y_; z = z_; } - - /// Negate this vector. - b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; } - - /// Add a vector to this vector. - void operator += (const b2Vec3& v) - { - x += v.x; y += v.y; z += v.z; - } - - /// Subtract a vector from this vector. - void operator -= (const b2Vec3& v) - { - x -= v.x; y -= v.y; z -= v.z; - } - - /// Multiply this vector by a scalar. - void operator *= (float32 s) - { - x *= s; y *= s; z *= s; - } - - float32 x, y, z; -}; - -/// A 2-by-2 matrix. Stored in column-major order. -struct b2Mat22 -{ - /// The default constructor does nothing (for performance). - b2Mat22() {} - - /// Construct this matrix using columns. - b2Mat22(const b2Vec2& c1, const b2Vec2& c2) - { - ex = c1; - ey = c2; - } - - /// Construct this matrix using scalars. - b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22) - { - ex.x = a11; ex.y = a21; - ey.x = a12; ey.y = a22; - } - - /// Initialize this matrix using columns. - void Set(const b2Vec2& c1, const b2Vec2& c2) - { - ex = c1; - ey = c2; - } - - /// Set this to the identity matrix. - void SetIdentity() - { - ex.x = 1.0f; ey.x = 0.0f; - ex.y = 0.0f; ey.y = 1.0f; - } - - /// Set this matrix to all zeros. - void SetZero() - { - ex.x = 0.0f; ey.x = 0.0f; - ex.y = 0.0f; ey.y = 0.0f; - } - - b2Mat22 GetInverse() const - { - float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y; - b2Mat22 B; - float32 det = a * d - b * c; - if (det != 0.0f) - { - det = 1.0f / det; - } - B.ex.x = det * d; B.ey.x = -det * b; - B.ex.y = -det * c; B.ey.y = det * a; - return B; - } - - /// Solve A * x = b, where b is a column vector. This is more efficient - /// than computing the inverse in one-shot cases. - b2Vec2 Solve(const b2Vec2& b) const - { - float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y; - float32 det = a11 * a22 - a12 * a21; - if (det != 0.0f) - { - det = 1.0f / det; - } - b2Vec2 x; - x.x = det * (a22 * b.x - a12 * b.y); - x.y = det * (a11 * b.y - a21 * b.x); - return x; - } - - b2Vec2 ex, ey; -}; - -/// A 3-by-3 matrix. Stored in column-major order. -struct b2Mat33 -{ - /// The default constructor does nothing (for performance). - b2Mat33() {} - - /// Construct this matrix using columns. - b2Mat33(const b2Vec3& c1, const b2Vec3& c2, const b2Vec3& c3) - { - ex = c1; - ey = c2; - ez = c3; - } - - /// Set this matrix to all zeros. - void SetZero() - { - ex.SetZero(); - ey.SetZero(); - ez.SetZero(); - } - - /// Solve A * x = b, where b is a column vector. This is more efficient - /// than computing the inverse in one-shot cases. - b2Vec3 Solve33(const b2Vec3& b) const; - - /// Solve A * x = b, where b is a column vector. This is more efficient - /// than computing the inverse in one-shot cases. Solve only the upper - /// 2-by-2 matrix equation. - b2Vec2 Solve22(const b2Vec2& b) const; - - /// Get the inverse of this matrix as a 2-by-2. - /// Returns the zero matrix if singular. - void GetInverse22(b2Mat33* M) const; - - /// Get the symmetric inverse of this matrix as a 3-by-3. - /// Returns the zero matrix if singular. - void GetSymInverse33(b2Mat33* M) const; - - b2Vec3 ex, ey, ez; -}; - -/// Rotation -struct b2Rot -{ - b2Rot() {} - - /// Initialize from an angle in radians - explicit b2Rot(float32 angle) - { - /// TODO_ERIN optimize - s = sinf(angle); - c = cosf(angle); - } - - /// Set using an angle in radians. - void Set(float32 angle) - { - /// TODO_ERIN optimize - s = sinf(angle); - c = cosf(angle); - } - - /// Set to the identity rotation - void SetIdentity() - { - s = 0.0f; - c = 1.0f; - } - - /// Get the angle in radians - float32 GetAngle() const - { - return b2Atan2(s, c); - } - - /// Get the x-axis - b2Vec2 GetXAxis() const - { - return b2Vec2(c, s); - } - - /// Get the u-axis - b2Vec2 GetYAxis() const - { - return b2Vec2(-s, c); - } - - /// Sine and cosine - float32 s, c; -}; - -/// A transform contains translation and rotation. It is used to represent -/// the position and orientation of rigid frames. -struct b2Transform -{ - /// The default constructor does nothing. - b2Transform() {} - - /// Initialize using a position vector and a rotation. - b2Transform(const b2Vec2& position, const b2Rot& rotation) : p(position), q(rotation) {} - - /// Set this to the identity transform. - void SetIdentity() - { - p.SetZero(); - q.SetIdentity(); - } - - /// Set this based on the position and angle. - void Set(const b2Vec2& position, float32 angle) - { - p = position; - q.Set(angle); - } - - b2Vec2 p; - b2Rot q; -}; - -/// This describes the motion of a body/shape for TOI computation. -/// Shapes are defined with respect to the body origin, which may -/// no coincide with the center of mass. However, to support dynamics -/// we must interpolate the center of mass position. -struct b2Sweep -{ - /// Get the interpolated transform at a specific time. - /// @param beta is a factor in [0,1], where 0 indicates alpha0. - void GetTransform(b2Transform* xfb, float32 beta) const; - - /// Advance the sweep forward, yielding a new initial state. - /// @param alpha the new initial time. - void Advance(float32 alpha); - - /// Normalize the angles. - void Normalize(); - - b2Vec2 localCenter; ///< local center of mass position - b2Vec2 c0, c; ///< center world positions - float32 a0, a; ///< world angles - - /// Fraction of the current time step in the range [0,1] - /// c0 and a0 are the positions at alpha0. - float32 alpha0; -}; - -/// Useful constant -extern const b2Vec2 b2Vec2_zero; - -/// Perform the dot product on two vectors. -inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b) -{ - return a.x * b.x + a.y * b.y; -} - -/// Perform the cross product on two vectors. In 2D this produces a scalar. -inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b) -{ - return a.x * b.y - a.y * b.x; -} - -/// Perform the cross product on a vector and a scalar. In 2D this produces -/// a vector. -inline b2Vec2 b2Cross(const b2Vec2& a, float32 s) -{ - return b2Vec2(s * a.y, -s * a.x); -} - -/// Perform the cross product on a scalar and a vector. In 2D this produces -/// a vector. -inline b2Vec2 b2Cross(float32 s, const b2Vec2& a) -{ - return b2Vec2(-s * a.y, s * a.x); -} - -/// Multiply a matrix times a vector. If a rotation matrix is provided, -/// then this transforms the vector from one frame to another. -inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v) -{ - return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y); -} - -/// Multiply a matrix transpose times a vector. If a rotation matrix is provided, -/// then this transforms the vector from one frame to another (inverse transform). -inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v) -{ - return b2Vec2(b2Dot(v, A.ex), b2Dot(v, A.ey)); -} - -/// Add two vectors component-wise. -inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b) -{ - return b2Vec2(a.x + b.x, a.y + b.y); -} - -/// Subtract two vectors component-wise. -inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b) -{ - return b2Vec2(a.x - b.x, a.y - b.y); -} - -inline b2Vec2 operator * (float32 s, const b2Vec2& a) -{ - return b2Vec2(s * a.x, s * a.y); -} - -inline bool operator == (const b2Vec2& a, const b2Vec2& b) -{ - return a.x == b.x && a.y == b.y; -} - -inline bool operator != (const b2Vec2& a, const b2Vec2& b) -{ - return a.x != b.x || a.y != b.y; -} - -inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b) -{ - b2Vec2 c = a - b; - return c.Length(); -} - -inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b) -{ - b2Vec2 c = a - b; - return b2Dot(c, c); -} - -inline b2Vec3 operator * (float32 s, const b2Vec3& a) -{ - return b2Vec3(s * a.x, s * a.y, s * a.z); -} - -/// Add two vectors component-wise. -inline b2Vec3 operator + (const b2Vec3& a, const b2Vec3& b) -{ - return b2Vec3(a.x + b.x, a.y + b.y, a.z + b.z); -} - -/// Subtract two vectors component-wise. -inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b) -{ - return b2Vec3(a.x - b.x, a.y - b.y, a.z - b.z); -} - -/// Perform the dot product on two vectors. -inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b) -{ - return a.x * b.x + a.y * b.y + a.z * b.z; -} - -/// Perform the cross product on two vectors. -inline b2Vec3 b2Cross(const b2Vec3& a, const b2Vec3& b) -{ - return b2Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); -} - -inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B) -{ - return b2Mat22(A.ex + B.ex, A.ey + B.ey); -} - -// A * B -inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B) -{ - return b2Mat22(b2Mul(A, B.ex), b2Mul(A, B.ey)); -} - -// A^T * B -inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B) -{ - b2Vec2 c1(b2Dot(A.ex, B.ex), b2Dot(A.ey, B.ex)); - b2Vec2 c2(b2Dot(A.ex, B.ey), b2Dot(A.ey, B.ey)); - return b2Mat22(c1, c2); -} - -/// Multiply a matrix times a vector. -inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v) -{ - return v.x * A.ex + v.y * A.ey + v.z * A.ez; -} - -/// Multiply a matrix times a vector. -inline b2Vec2 b2Mul22(const b2Mat33& A, const b2Vec2& v) -{ - return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y); -} - -/// Multiply two rotations: q * r -inline b2Rot b2Mul(const b2Rot& q, const b2Rot& r) -{ - // [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc] - // [qs qc] [rs rc] [qs*rc+qc*rs -qs*rs+qc*rc] - // s = qs * rc + qc * rs - // c = qc * rc - qs * rs - b2Rot qr; - qr.s = q.s * r.c + q.c * r.s; - qr.c = q.c * r.c - q.s * r.s; - return qr; -} - -/// Transpose multiply two rotations: qT * r -inline b2Rot b2MulT(const b2Rot& q, const b2Rot& r) -{ - // [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc] - // [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc] - // s = qc * rs - qs * rc - // c = qc * rc + qs * rs - b2Rot qr; - qr.s = q.c * r.s - q.s * r.c; - qr.c = q.c * r.c + q.s * r.s; - return qr; -} - -/// Rotate a vector -inline b2Vec2 b2Mul(const b2Rot& q, const b2Vec2& v) -{ - return b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y); -} - -/// Inverse rotate a vector -inline b2Vec2 b2MulT(const b2Rot& q, const b2Vec2& v) -{ - return b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y); -} - -inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v) -{ - float32 x = (T.q.c * v.x - T.q.s * v.y) + T.p.x; - float32 y = (T.q.s * v.x + T.q.c * v.y) + T.p.y; - - return b2Vec2(x, y); -} - -inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v) -{ - float32 px = v.x - T.p.x; - float32 py = v.y - T.p.y; - float32 x = (T.q.c * px + T.q.s * py); - float32 y = (-T.q.s * px + T.q.c * py); - - return b2Vec2(x, y); -} - -// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p -// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p -inline b2Transform b2Mul(const b2Transform& A, const b2Transform& B) -{ - b2Transform C; - C.q = b2Mul(A.q, B.q); - C.p = b2Mul(A.q, B.p) + A.p; - return C; -} - -// v2 = A.q' * (B.q * v1 + B.p - A.p) -// = A.q' * B.q * v1 + A.q' * (B.p - A.p) -inline b2Transform b2MulT(const b2Transform& A, const b2Transform& B) -{ - b2Transform C; - C.q = b2MulT(A.q, B.q); - C.p = b2MulT(A.q, B.p - A.p); - return C; -} - -template <typename T> -inline T b2Abs(T a) -{ - return a > T(0) ? a : -a; -} - -inline b2Vec2 b2Abs(const b2Vec2& a) -{ - return b2Vec2(b2Abs(a.x), b2Abs(a.y)); -} - -inline b2Mat22 b2Abs(const b2Mat22& A) -{ - return b2Mat22(b2Abs(A.ex), b2Abs(A.ey)); -} - -template <typename T> -inline T b2Min(T a, T b) -{ - return a < b ? a : b; -} - -inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b) -{ - return b2Vec2(b2Min(a.x, b.x), b2Min(a.y, b.y)); -} - -template <typename T> -inline T b2Max(T a, T b) -{ - return a > b ? a : b; -} - -inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b) -{ - return b2Vec2(b2Max(a.x, b.x), b2Max(a.y, b.y)); -} - -template <typename T> -inline T b2Clamp(T a, T low, T high) -{ - return b2Max(low, b2Min(a, high)); -} - -inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high) -{ - return b2Max(low, b2Min(a, high)); -} - -template<typename T> inline void b2Swap(T& a, T& b) -{ - T tmp = a; - a = b; - b = tmp; -} - -/// "Next Largest Power of 2 -/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm -/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with -/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next -/// largest power of 2. For a 32-bit value:" -inline uint32 b2NextPowerOfTwo(uint32 x) -{ - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - return x + 1; -} - -inline bool b2IsPowerOfTwo(uint32 x) -{ - bool result = x > 0 && (x & (x - 1)) == 0; - return result; -} - -inline void b2Sweep::GetTransform(b2Transform* xf, float32 beta) const -{ - xf->p = (1.0f - beta) * c0 + beta * c; - float32 angle = (1.0f - beta) * a0 + beta * a; - xf->q.Set(angle); - - // Shift to origin - xf->p -= b2Mul(xf->q, localCenter); -} - -inline void b2Sweep::Advance(float32 alpha) -{ - b2Assert(alpha0 < 1.0f); - float32 beta = (alpha - alpha0) / (1.0f - alpha0); - c0 += beta * (c - c0); - a0 += beta * (a - a0); - alpha0 = alpha; -} - -/// Normalize an angle in radians to be between -pi and pi -inline void b2Sweep::Normalize() -{ - float32 twoPi = 2.0f * b2_pi; - float32 d = twoPi * floorf(a0 / twoPi); - a0 -= d; - a -= d; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2Settings.cpp b/src/libjin/3rdparty/Box2D/Common/b2Settings.cpp deleted file mode 100644 index a59cefe..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Settings.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Common/b2Settings.h" -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> - -b2Version b2_version = {2, 3, 2}; - -// Memory allocators. Modify these to use your own allocator. -void* b2Alloc(int32 size) -{ - return malloc(size); -} - -void b2Free(void* mem) -{ - free(mem); -} - -// You can modify this to use your logging facility. -void b2Log(const char* string, ...) -{ - va_list args; - va_start(args, string); - vprintf(string, args); - va_end(args); -} diff --git a/src/libjin/3rdparty/Box2D/Common/b2Settings.h b/src/libjin/3rdparty/Box2D/Common/b2Settings.h deleted file mode 100644 index c69280f..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Settings.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_SETTINGS_H -#define B2_SETTINGS_H - -#include <stddef.h> -#include <assert.h> -#include <float.h> - -#if !defined(NDEBUG) - #define b2DEBUG -#endif - -#define B2_NOT_USED(x) ((void)(x)) -#define b2Assert(A) assert(A) - -typedef signed char int8; -typedef signed short int16; -typedef signed int int32; -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef float float32; -typedef double float64; - -#define b2_maxFloat FLT_MAX -#define b2_epsilon FLT_EPSILON -#define b2_pi 3.14159265359f - -/// @file -/// Global tuning constants based on meters-kilograms-seconds (MKS) units. -/// - -// Collision - -/// The maximum number of contact points between two convex shapes. Do -/// not change this value. -#define b2_maxManifoldPoints 2 - -/// The maximum number of vertices on a convex polygon. You cannot increase -/// this too much because b2BlockAllocator has a maximum object size. -#define b2_maxPolygonVertices 8 - -/// This is used to fatten AABBs in the dynamic tree. This allows proxies -/// to move by a small amount without triggering a tree adjustment. -/// This is in meters. -#define b2_aabbExtension 0.1f - -/// This is used to fatten AABBs in the dynamic tree. This is used to predict -/// the future position based on the current displacement. -/// This is a dimensionless multiplier. -#define b2_aabbMultiplier 2.0f - -/// A small length used as a collision and constraint tolerance. Usually it is -/// chosen to be numerically significant, but visually insignificant. -#define b2_linearSlop 0.005f - -/// A small angle used as a collision and constraint tolerance. Usually it is -/// chosen to be numerically significant, but visually insignificant. -#define b2_angularSlop (2.0f / 180.0f * b2_pi) - -/// The radius of the polygon/edge shape skin. This should not be modified. Making -/// this smaller means polygons will have an insufficient buffer for continuous collision. -/// Making it larger may create artifacts for vertex collision. -#define b2_polygonRadius (2.0f * b2_linearSlop) - -/// Maximum number of sub-steps per contact in continuous physics simulation. -#define b2_maxSubSteps 8 - - -// Dynamics - -/// Maximum number of contacts to be handled to solve a TOI impact. -#define b2_maxTOIContacts 32 - -/// A velocity threshold for elastic collisions. Any collision with a relative linear -/// velocity below this threshold will be treated as inelastic. -#define b2_velocityThreshold 1.0f - -/// The maximum linear position correction used when solving constraints. This helps to -/// prevent overshoot. -#define b2_maxLinearCorrection 0.2f - -/// The maximum angular position correction used when solving constraints. This helps to -/// prevent overshoot. -#define b2_maxAngularCorrection (8.0f / 180.0f * b2_pi) - -/// The maximum linear velocity of a body. This limit is very large and is used -/// to prevent numerical problems. You shouldn't need to adjust this. -#define b2_maxTranslation 2.0f -#define b2_maxTranslationSquared (b2_maxTranslation * b2_maxTranslation) - -/// The maximum angular velocity of a body. This limit is very large and is used -/// to prevent numerical problems. You shouldn't need to adjust this. -#define b2_maxRotation (0.5f * b2_pi) -#define b2_maxRotationSquared (b2_maxRotation * b2_maxRotation) - -/// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so -/// that overlap is removed in one time step. However using values close to 1 often lead -/// to overshoot. -#define b2_baumgarte 0.2f -#define b2_toiBaugarte 0.75f - - -// Sleep - -/// The time that a body must be still before it will go to sleep. -#define b2_timeToSleep 0.5f - -/// A body cannot sleep if its linear velocity is above this tolerance. -#define b2_linearSleepTolerance 0.01f - -/// A body cannot sleep if its angular velocity is above this tolerance. -#define b2_angularSleepTolerance (2.0f / 180.0f * b2_pi) - -// Memory Allocation - -/// Implement this function to use your own memory allocator. -void* b2Alloc(int32 size); - -/// If you implement b2Alloc, you should also implement this function. -void b2Free(void* mem); - -/// Logging function. -void b2Log(const char* string, ...); - -/// Version numbering scheme. -/// See http://en.wikipedia.org/wiki/Software_versioning -struct b2Version -{ - int32 major; ///< significant changes - int32 minor; ///< incremental changes - int32 revision; ///< bug fixes -}; - -/// Current version. -extern b2Version b2_version; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2StackAllocator.cpp b/src/libjin/3rdparty/Box2D/Common/b2StackAllocator.cpp deleted file mode 100644 index 1347f3c..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2StackAllocator.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Common/b2StackAllocator.h" -#include "Box2D/Common/b2Math.h" - -b2StackAllocator::b2StackAllocator() -{ - m_index = 0; - m_allocation = 0; - m_maxAllocation = 0; - m_entryCount = 0; -} - -b2StackAllocator::~b2StackAllocator() -{ - b2Assert(m_index == 0); - b2Assert(m_entryCount == 0); -} - -void* b2StackAllocator::Allocate(int32 size) -{ - b2Assert(m_entryCount < b2_maxStackEntries); - - b2StackEntry* entry = m_entries + m_entryCount; - entry->size = size; - if (m_index + size > b2_stackSize) - { - entry->data = (char*)b2Alloc(size); - entry->usedMalloc = true; - } - else - { - entry->data = m_data + m_index; - entry->usedMalloc = false; - m_index += size; - } - - m_allocation += size; - m_maxAllocation = b2Max(m_maxAllocation, m_allocation); - ++m_entryCount; - - return entry->data; -} - -void b2StackAllocator::Free(void* p) -{ - b2Assert(m_entryCount > 0); - b2StackEntry* entry = m_entries + m_entryCount - 1; - b2Assert(p == entry->data); - if (entry->usedMalloc) - { - b2Free(p); - } - else - { - m_index -= entry->size; - } - m_allocation -= entry->size; - --m_entryCount; - - p = nullptr; -} - -int32 b2StackAllocator::GetMaxAllocation() const -{ - return m_maxAllocation; -} diff --git a/src/libjin/3rdparty/Box2D/Common/b2StackAllocator.h b/src/libjin/3rdparty/Box2D/Common/b2StackAllocator.h deleted file mode 100644 index 27340e8..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2StackAllocator.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_STACK_ALLOCATOR_H -#define B2_STACK_ALLOCATOR_H - -#include "Box2D/Common/b2Settings.h" - -const int32 b2_stackSize = 100 * 1024; // 100k -const int32 b2_maxStackEntries = 32; - -struct b2StackEntry -{ - char* data; - int32 size; - bool usedMalloc; -}; - -// This is a stack allocator used for fast per step allocations. -// You must nest allocate/free pairs. The code will assert -// if you try to interleave multiple allocate/free pairs. -class b2StackAllocator -{ -public: - b2StackAllocator(); - ~b2StackAllocator(); - - void* Allocate(int32 size); - void Free(void* p); - - int32 GetMaxAllocation() const; - -private: - - char m_data[b2_stackSize]; - int32 m_index; - - int32 m_allocation; - int32 m_maxAllocation; - - b2StackEntry m_entries[b2_maxStackEntries]; - int32 m_entryCount; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2Timer.cpp b/src/libjin/3rdparty/Box2D/Common/b2Timer.cpp deleted file mode 100644 index 38f3dea..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Timer.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* -* Copyright (c) 2011 Erin Catto http://box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Common/b2Timer.h" - -#if defined(_WIN32) - -float64 b2Timer::s_invFrequency = 0.0f; - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include <windows.h> - -b2Timer::b2Timer() -{ - LARGE_INTEGER largeInteger; - - if (s_invFrequency == 0.0f) - { - QueryPerformanceFrequency(&largeInteger); - s_invFrequency = float64(largeInteger.QuadPart); - if (s_invFrequency > 0.0f) - { - s_invFrequency = 1000.0f / s_invFrequency; - } - } - - QueryPerformanceCounter(&largeInteger); - m_start = float64(largeInteger.QuadPart); -} - -void b2Timer::Reset() -{ - LARGE_INTEGER largeInteger; - QueryPerformanceCounter(&largeInteger); - m_start = float64(largeInteger.QuadPart); -} - -float32 b2Timer::GetMilliseconds() const -{ - LARGE_INTEGER largeInteger; - QueryPerformanceCounter(&largeInteger); - float64 count = float64(largeInteger.QuadPart); - float32 ms = float32(s_invFrequency * (count - m_start)); - return ms; -} - -#elif defined(__linux__) || defined (__APPLE__) - -#include <sys/time.h> - -b2Timer::b2Timer() -{ - Reset(); -} - -void b2Timer::Reset() -{ - timeval t; - gettimeofday(&t, 0); - m_start_sec = t.tv_sec; - m_start_usec = t.tv_usec; -} - -float32 b2Timer::GetMilliseconds() const -{ - timeval t; - gettimeofday(&t, 0); - time_t start_sec = m_start_sec; - suseconds_t start_usec = m_start_usec; - - // http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html - if (t.tv_usec < start_usec) - { - int nsec = (start_usec - t.tv_usec) / 1000000 + 1; - start_usec -= 1000000 * nsec; - start_sec += nsec; - } - - if (t.tv_usec - start_usec > 1000000) - { - int nsec = (t.tv_usec - start_usec) / 1000000; - start_usec += 1000000 * nsec; - start_sec -= nsec; - } - return 1000.0f * (t.tv_sec - start_sec) + 0.001f * (t.tv_usec - start_usec); -} - -#else - -b2Timer::b2Timer() -{ -} - -void b2Timer::Reset() -{ -} - -float32 b2Timer::GetMilliseconds() const -{ - return 0.0f; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Common/b2Timer.h b/src/libjin/3rdparty/Box2D/Common/b2Timer.h deleted file mode 100644 index a25e907..0000000 --- a/src/libjin/3rdparty/Box2D/Common/b2Timer.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* Copyright (c) 2011 Erin Catto http://box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_TIMER_H -#define B2_TIMER_H - -#include "Box2D/Common/b2Settings.h" - -/// Timer for profiling. This has platform specific code and may -/// not work on every platform. -class b2Timer -{ -public: - - /// Constructor - b2Timer(); - - /// Reset the timer. - void Reset(); - - /// Get the time since construction or the last reset. - float32 GetMilliseconds() const; - -private: - -#if defined(_WIN32) - float64 m_start; - static float64 s_invFrequency; -#elif defined(__linux__) || defined (__APPLE__) - unsigned long long m_start_sec; - unsigned long long m_start_usec; -#endif -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp deleted file mode 100644 index c930255..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" - -#include <new> - -b2Contact* b2ChainAndCircleContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2ChainAndCircleContact)); - return new (mem) b2ChainAndCircleContact(fixtureA, indexA, fixtureB, indexB); -} - -void b2ChainAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2ChainAndCircleContact*)contact)->~b2ChainAndCircleContact(); - allocator->Free(contact, sizeof(b2ChainAndCircleContact)); -} - -b2ChainAndCircleContact::b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB) -: b2Contact(fixtureA, indexA, fixtureB, indexB) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_chain); - b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); -} - -void b2ChainAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2ChainShape* chain = (b2ChainShape*)m_fixtureA->GetShape(); - b2EdgeShape edge; - chain->GetChildEdge(&edge, m_indexA); - b2CollideEdgeAndCircle( manifold, &edge, xfA, - (b2CircleShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h deleted file mode 100644 index 1421f90..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CHAIN_AND_CIRCLE_CONTACT_H -#define B2_CHAIN_AND_CIRCLE_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2ChainAndCircleContact : public b2Contact -{ -public: - static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); - ~b2ChainAndCircleContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp deleted file mode 100644 index 78431d5..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" - -#include <new> - -b2Contact* b2ChainAndPolygonContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2ChainAndPolygonContact)); - return new (mem) b2ChainAndPolygonContact(fixtureA, indexA, fixtureB, indexB); -} - -void b2ChainAndPolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2ChainAndPolygonContact*)contact)->~b2ChainAndPolygonContact(); - allocator->Free(contact, sizeof(b2ChainAndPolygonContact)); -} - -b2ChainAndPolygonContact::b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB) -: b2Contact(fixtureA, indexA, fixtureB, indexB) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_chain); - b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon); -} - -void b2ChainAndPolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2ChainShape* chain = (b2ChainShape*)m_fixtureA->GetShape(); - b2EdgeShape edge; - chain->GetChildEdge(&edge, m_indexA); - b2CollideEdgeAndPolygon( manifold, &edge, xfA, - (b2PolygonShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h deleted file mode 100644 index 89b8dd3..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CHAIN_AND_POLYGON_CONTACT_H -#define B2_CHAIN_AND_POLYGON_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2ChainAndPolygonContact : public b2Contact -{ -public: - static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); - ~b2ChainAndPolygonContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2CircleContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2CircleContact.cpp deleted file mode 100644 index 3b6c50b..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2CircleContact.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2CircleContact.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2WorldCallbacks.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Collision/b2TimeOfImpact.h" - -#include <new> - -b2Contact* b2CircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2CircleContact)); - return new (mem) b2CircleContact(fixtureA, fixtureB); -} - -void b2CircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2CircleContact*)contact)->~b2CircleContact(); - allocator->Free(contact, sizeof(b2CircleContact)); -} - -b2CircleContact::b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) - : b2Contact(fixtureA, 0, fixtureB, 0) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_circle); - b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); -} - -void b2CircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2CollideCircles(manifold, - (b2CircleShape*)m_fixtureA->GetShape(), xfA, - (b2CircleShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2CircleContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2CircleContact.h deleted file mode 100644 index d40c7fb..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2CircleContact.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CIRCLE_CONTACT_H -#define B2_CIRCLE_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2CircleContact : public b2Contact -{ -public: - static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); - ~b2CircleContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2Contact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2Contact.cpp deleted file mode 100644 index 41b0f78..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2Contact.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2Contact.h" -#include "Box2D/Dynamics/Contacts/b2CircleContact.h" -#include "Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h" -#include "Box2D/Dynamics/Contacts/b2PolygonContact.h" -#include "Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h" -#include "Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h" -#include "Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h" -#include "Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h" -#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" - -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/b2TimeOfImpact.h" -#include "Box2D/Collision/Shapes/b2Shape.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2World.h" - -b2ContactRegister b2Contact::s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; -bool b2Contact::s_initialized = false; - -void b2Contact::InitializeRegisters() -{ - AddType(b2CircleContact::Create, b2CircleContact::Destroy, b2Shape::e_circle, b2Shape::e_circle); - AddType(b2PolygonAndCircleContact::Create, b2PolygonAndCircleContact::Destroy, b2Shape::e_polygon, b2Shape::e_circle); - AddType(b2PolygonContact::Create, b2PolygonContact::Destroy, b2Shape::e_polygon, b2Shape::e_polygon); - AddType(b2EdgeAndCircleContact::Create, b2EdgeAndCircleContact::Destroy, b2Shape::e_edge, b2Shape::e_circle); - AddType(b2EdgeAndPolygonContact::Create, b2EdgeAndPolygonContact::Destroy, b2Shape::e_edge, b2Shape::e_polygon); - AddType(b2ChainAndCircleContact::Create, b2ChainAndCircleContact::Destroy, b2Shape::e_chain, b2Shape::e_circle); - AddType(b2ChainAndPolygonContact::Create, b2ChainAndPolygonContact::Destroy, b2Shape::e_chain, b2Shape::e_polygon); -} - -void b2Contact::AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destoryFcn, - b2Shape::Type type1, b2Shape::Type type2) -{ - b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount); - b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount); - - s_registers[type1][type2].createFcn = createFcn; - s_registers[type1][type2].destroyFcn = destoryFcn; - s_registers[type1][type2].primary = true; - - if (type1 != type2) - { - s_registers[type2][type1].createFcn = createFcn; - s_registers[type2][type1].destroyFcn = destoryFcn; - s_registers[type2][type1].primary = false; - } -} - -b2Contact* b2Contact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator) -{ - if (s_initialized == false) - { - InitializeRegisters(); - s_initialized = true; - } - - b2Shape::Type type1 = fixtureA->GetType(); - b2Shape::Type type2 = fixtureB->GetType(); - - b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount); - b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount); - - b2ContactCreateFcn* createFcn = s_registers[type1][type2].createFcn; - if (createFcn) - { - if (s_registers[type1][type2].primary) - { - return createFcn(fixtureA, indexA, fixtureB, indexB, allocator); - } - else - { - return createFcn(fixtureB, indexB, fixtureA, indexA, allocator); - } - } - else - { - return nullptr; - } -} - -void b2Contact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - b2Assert(s_initialized == true); - - b2Fixture* fixtureA = contact->m_fixtureA; - b2Fixture* fixtureB = contact->m_fixtureB; - - if (contact->m_manifold.pointCount > 0 && - fixtureA->IsSensor() == false && - fixtureB->IsSensor() == false) - { - fixtureA->GetBody()->SetAwake(true); - fixtureB->GetBody()->SetAwake(true); - } - - b2Shape::Type typeA = fixtureA->GetType(); - b2Shape::Type typeB = fixtureB->GetType(); - - b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount); - b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount); - - b2ContactDestroyFcn* destroyFcn = s_registers[typeA][typeB].destroyFcn; - destroyFcn(contact, allocator); -} - -b2Contact::b2Contact(b2Fixture* fA, int32 indexA, b2Fixture* fB, int32 indexB) -{ - m_flags = e_enabledFlag; - - m_fixtureA = fA; - m_fixtureB = fB; - - m_indexA = indexA; - m_indexB = indexB; - - m_manifold.pointCount = 0; - - m_prev = nullptr; - m_next = nullptr; - - m_nodeA.contact = nullptr; - m_nodeA.prev = nullptr; - m_nodeA.next = nullptr; - m_nodeA.other = nullptr; - - m_nodeB.contact = nullptr; - m_nodeB.prev = nullptr; - m_nodeB.next = nullptr; - m_nodeB.other = nullptr; - - m_toiCount = 0; - - m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction); - m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); - - m_tangentSpeed = 0.0f; -} - -// Update the contact manifold and touching status. -// Note: do not assume the fixture AABBs are overlapping or are valid. -void b2Contact::Update(b2ContactListener* listener) -{ - b2Manifold oldManifold = m_manifold; - - // Re-enable this contact. - m_flags |= e_enabledFlag; - - bool touching = false; - bool wasTouching = (m_flags & e_touchingFlag) == e_touchingFlag; - - bool sensorA = m_fixtureA->IsSensor(); - bool sensorB = m_fixtureB->IsSensor(); - bool sensor = sensorA || sensorB; - - b2Body* bodyA = m_fixtureA->GetBody(); - b2Body* bodyB = m_fixtureB->GetBody(); - const b2Transform& xfA = bodyA->GetTransform(); - const b2Transform& xfB = bodyB->GetTransform(); - - // Is this contact a sensor? - if (sensor) - { - const b2Shape* shapeA = m_fixtureA->GetShape(); - const b2Shape* shapeB = m_fixtureB->GetShape(); - touching = b2TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB); - - // Sensors don't generate manifolds. - m_manifold.pointCount = 0; - } - else - { - Evaluate(&m_manifold, xfA, xfB); - touching = m_manifold.pointCount > 0; - - // Match old contact ids to new contact ids and copy the - // stored impulses to warm start the solver. - for (int32 i = 0; i < m_manifold.pointCount; ++i) - { - b2ManifoldPoint* mp2 = m_manifold.points + i; - mp2->normalImpulse = 0.0f; - mp2->tangentImpulse = 0.0f; - b2ContactID id2 = mp2->id; - - for (int32 j = 0; j < oldManifold.pointCount; ++j) - { - b2ManifoldPoint* mp1 = oldManifold.points + j; - - if (mp1->id.key == id2.key) - { - mp2->normalImpulse = mp1->normalImpulse; - mp2->tangentImpulse = mp1->tangentImpulse; - break; - } - } - } - - if (touching != wasTouching) - { - bodyA->SetAwake(true); - bodyB->SetAwake(true); - } - } - - if (touching) - { - m_flags |= e_touchingFlag; - } - else - { - m_flags &= ~e_touchingFlag; - } - - if (wasTouching == false && touching == true && listener) - { - listener->BeginContact(this); - } - - if (wasTouching == true && touching == false && listener) - { - listener->EndContact(this); - } - - if (sensor == false && touching && listener) - { - listener->PreSolve(this, &oldManifold); - } -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2Contact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2Contact.h deleted file mode 100644 index df23d3c..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2Contact.h +++ /dev/null @@ -1,349 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CONTACT_H -#define B2_CONTACT_H - -#include "Box2D/Common/b2Math.h" -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/Shapes/b2Shape.h" -#include "Box2D/Dynamics/b2Fixture.h" - -class b2Body; -class b2Contact; -class b2Fixture; -class b2World; -class b2BlockAllocator; -class b2StackAllocator; -class b2ContactListener; - -/// Friction mixing law. The idea is to allow either fixture to drive the friction to zero. -/// For example, anything slides on ice. -inline float32 b2MixFriction(float32 friction1, float32 friction2) -{ - return b2Sqrt(friction1 * friction2); -} - -/// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface. -/// For example, a superball bounces on anything. -inline float32 b2MixRestitution(float32 restitution1, float32 restitution2) -{ - return restitution1 > restitution2 ? restitution1 : restitution2; -} - -typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, - b2BlockAllocator* allocator); -typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator); - -struct b2ContactRegister -{ - b2ContactCreateFcn* createFcn; - b2ContactDestroyFcn* destroyFcn; - bool primary; -}; - -/// A contact edge is used to connect bodies and contacts together -/// in a contact graph where each body is a node and each contact -/// is an edge. A contact edge belongs to a doubly linked list -/// maintained in each attached body. Each contact has two contact -/// nodes, one for each attached body. -struct b2ContactEdge -{ - b2Body* other; ///< provides quick access to the other body attached. - b2Contact* contact; ///< the contact - b2ContactEdge* prev; ///< the previous contact edge in the body's contact list - b2ContactEdge* next; ///< the next contact edge in the body's contact list -}; - -/// The class manages contact between two shapes. A contact exists for each overlapping -/// AABB in the broad-phase (except if filtered). Therefore a contact object may exist -/// that has no contact points. -class b2Contact -{ -public: - - /// Get the contact manifold. Do not modify the manifold unless you understand the - /// internals of Box2D. - b2Manifold* GetManifold(); - const b2Manifold* GetManifold() const; - - /// Get the world manifold. - void GetWorldManifold(b2WorldManifold* worldManifold) const; - - /// Is this contact touching? - bool IsTouching() const; - - /// Enable/disable this contact. This can be used inside the pre-solve - /// contact listener. The contact is only disabled for the current - /// time step (or sub-step in continuous collisions). - void SetEnabled(bool flag); - - /// Has this contact been disabled? - bool IsEnabled() const; - - /// Get the next contact in the world's contact list. - b2Contact* GetNext(); - const b2Contact* GetNext() const; - - /// Get fixture A in this contact. - b2Fixture* GetFixtureA(); - const b2Fixture* GetFixtureA() const; - - /// Get the child primitive index for fixture A. - int32 GetChildIndexA() const; - - /// Get fixture B in this contact. - b2Fixture* GetFixtureB(); - const b2Fixture* GetFixtureB() const; - - /// Get the child primitive index for fixture B. - int32 GetChildIndexB() const; - - /// Override the default friction mixture. You can call this in b2ContactListener::PreSolve. - /// This value persists until set or reset. - void SetFriction(float32 friction); - - /// Get the friction. - float32 GetFriction() const; - - /// Reset the friction mixture to the default value. - void ResetFriction(); - - /// Override the default restitution mixture. You can call this in b2ContactListener::PreSolve. - /// The value persists until you set or reset. - void SetRestitution(float32 restitution); - - /// Get the restitution. - float32 GetRestitution() const; - - /// Reset the restitution to the default value. - void ResetRestitution(); - - /// Set the desired tangent speed for a conveyor belt behavior. In meters per second. - void SetTangentSpeed(float32 speed); - - /// Get the desired tangent speed. In meters per second. - float32 GetTangentSpeed() const; - - /// Evaluate this contact with your own manifold and transforms. - virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0; - -protected: - friend class b2ContactManager; - friend class b2World; - friend class b2ContactSolver; - friend class b2Body; - friend class b2Fixture; - - // Flags stored in m_flags - enum - { - // Used when crawling contact graph when forming islands. - e_islandFlag = 0x0001, - - // Set when the shapes are touching. - e_touchingFlag = 0x0002, - - // This contact can be disabled (by user) - e_enabledFlag = 0x0004, - - // This contact needs filtering because a fixture filter was changed. - e_filterFlag = 0x0008, - - // This bullet contact had a TOI event - e_bulletHitFlag = 0x0010, - - // This contact has a valid TOI in m_toi - e_toiFlag = 0x0020 - }; - - /// Flag this contact for filtering. Filtering will occur the next time step. - void FlagForFiltering(); - - static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn, - b2Shape::Type typeA, b2Shape::Type typeB); - static void InitializeRegisters(); - static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2Contact() : m_fixtureA(nullptr), m_fixtureB(nullptr) {} - b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); - virtual ~b2Contact() {} - - void Update(b2ContactListener* listener); - - static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; - static bool s_initialized; - - uint32 m_flags; - - // World pool and list pointers. - b2Contact* m_prev; - b2Contact* m_next; - - // Nodes for connecting bodies. - b2ContactEdge m_nodeA; - b2ContactEdge m_nodeB; - - b2Fixture* m_fixtureA; - b2Fixture* m_fixtureB; - - int32 m_indexA; - int32 m_indexB; - - b2Manifold m_manifold; - - int32 m_toiCount; - float32 m_toi; - - float32 m_friction; - float32 m_restitution; - - float32 m_tangentSpeed; -}; - -inline b2Manifold* b2Contact::GetManifold() -{ - return &m_manifold; -} - -inline const b2Manifold* b2Contact::GetManifold() const -{ - return &m_manifold; -} - -inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const -{ - const b2Body* bodyA = m_fixtureA->GetBody(); - const b2Body* bodyB = m_fixtureB->GetBody(); - const b2Shape* shapeA = m_fixtureA->GetShape(); - const b2Shape* shapeB = m_fixtureB->GetShape(); - - worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius); -} - -inline void b2Contact::SetEnabled(bool flag) -{ - if (flag) - { - m_flags |= e_enabledFlag; - } - else - { - m_flags &= ~e_enabledFlag; - } -} - -inline bool b2Contact::IsEnabled() const -{ - return (m_flags & e_enabledFlag) == e_enabledFlag; -} - -inline bool b2Contact::IsTouching() const -{ - return (m_flags & e_touchingFlag) == e_touchingFlag; -} - -inline b2Contact* b2Contact::GetNext() -{ - return m_next; -} - -inline const b2Contact* b2Contact::GetNext() const -{ - return m_next; -} - -inline b2Fixture* b2Contact::GetFixtureA() -{ - return m_fixtureA; -} - -inline const b2Fixture* b2Contact::GetFixtureA() const -{ - return m_fixtureA; -} - -inline b2Fixture* b2Contact::GetFixtureB() -{ - return m_fixtureB; -} - -inline int32 b2Contact::GetChildIndexA() const -{ - return m_indexA; -} - -inline const b2Fixture* b2Contact::GetFixtureB() const -{ - return m_fixtureB; -} - -inline int32 b2Contact::GetChildIndexB() const -{ - return m_indexB; -} - -inline void b2Contact::FlagForFiltering() -{ - m_flags |= e_filterFlag; -} - -inline void b2Contact::SetFriction(float32 friction) -{ - m_friction = friction; -} - -inline float32 b2Contact::GetFriction() const -{ - return m_friction; -} - -inline void b2Contact::ResetFriction() -{ - m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction); -} - -inline void b2Contact::SetRestitution(float32 restitution) -{ - m_restitution = restitution; -} - -inline float32 b2Contact::GetRestitution() const -{ - return m_restitution; -} - -inline void b2Contact::ResetRestitution() -{ - m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); -} - -inline void b2Contact::SetTangentSpeed(float32 speed) -{ - m_tangentSpeed = speed; -} - -inline float32 b2Contact::GetTangentSpeed() const -{ - return m_tangentSpeed; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ContactSolver.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ContactSolver.cpp deleted file mode 100644 index 147968c..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +++ /dev/null @@ -1,838 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" - -#include "Box2D/Dynamics/Contacts/b2Contact.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2World.h" -#include "Box2D/Common/b2StackAllocator.h" - -// Solver debugging is normally disabled because the block solver sometimes has to deal with a poorly conditioned effective mass matrix. -#define B2_DEBUG_SOLVER 0 - -bool g_blockSolve = true; - -struct b2ContactPositionConstraint -{ - b2Vec2 localPoints[b2_maxManifoldPoints]; - b2Vec2 localNormal; - b2Vec2 localPoint; - int32 indexA; - int32 indexB; - float32 invMassA, invMassB; - b2Vec2 localCenterA, localCenterB; - float32 invIA, invIB; - b2Manifold::Type type; - float32 radiusA, radiusB; - int32 pointCount; -}; - -b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def) -{ - m_step = def->step; - m_allocator = def->allocator; - m_count = def->count; - m_positionConstraints = (b2ContactPositionConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactPositionConstraint)); - m_velocityConstraints = (b2ContactVelocityConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactVelocityConstraint)); - m_positions = def->positions; - m_velocities = def->velocities; - m_contacts = def->contacts; - - // Initialize position independent portions of the constraints. - for (int32 i = 0; i < m_count; ++i) - { - b2Contact* contact = m_contacts[i]; - - b2Fixture* fixtureA = contact->m_fixtureA; - b2Fixture* fixtureB = contact->m_fixtureB; - b2Shape* shapeA = fixtureA->GetShape(); - b2Shape* shapeB = fixtureB->GetShape(); - float32 radiusA = shapeA->m_radius; - float32 radiusB = shapeB->m_radius; - b2Body* bodyA = fixtureA->GetBody(); - b2Body* bodyB = fixtureB->GetBody(); - b2Manifold* manifold = contact->GetManifold(); - - int32 pointCount = manifold->pointCount; - b2Assert(pointCount > 0); - - b2ContactVelocityConstraint* vc = m_velocityConstraints + i; - vc->friction = contact->m_friction; - vc->restitution = contact->m_restitution; - vc->tangentSpeed = contact->m_tangentSpeed; - vc->indexA = bodyA->m_islandIndex; - vc->indexB = bodyB->m_islandIndex; - vc->invMassA = bodyA->m_invMass; - vc->invMassB = bodyB->m_invMass; - vc->invIA = bodyA->m_invI; - vc->invIB = bodyB->m_invI; - vc->contactIndex = i; - vc->pointCount = pointCount; - vc->K.SetZero(); - vc->normalMass.SetZero(); - - b2ContactPositionConstraint* pc = m_positionConstraints + i; - pc->indexA = bodyA->m_islandIndex; - pc->indexB = bodyB->m_islandIndex; - pc->invMassA = bodyA->m_invMass; - pc->invMassB = bodyB->m_invMass; - pc->localCenterA = bodyA->m_sweep.localCenter; - pc->localCenterB = bodyB->m_sweep.localCenter; - pc->invIA = bodyA->m_invI; - pc->invIB = bodyB->m_invI; - pc->localNormal = manifold->localNormal; - pc->localPoint = manifold->localPoint; - pc->pointCount = pointCount; - pc->radiusA = radiusA; - pc->radiusB = radiusB; - pc->type = manifold->type; - - for (int32 j = 0; j < pointCount; ++j) - { - b2ManifoldPoint* cp = manifold->points + j; - b2VelocityConstraintPoint* vcp = vc->points + j; - - if (m_step.warmStarting) - { - vcp->normalImpulse = m_step.dtRatio * cp->normalImpulse; - vcp->tangentImpulse = m_step.dtRatio * cp->tangentImpulse; - } - else - { - vcp->normalImpulse = 0.0f; - vcp->tangentImpulse = 0.0f; - } - - vcp->rA.SetZero(); - vcp->rB.SetZero(); - vcp->normalMass = 0.0f; - vcp->tangentMass = 0.0f; - vcp->velocityBias = 0.0f; - - pc->localPoints[j] = cp->localPoint; - } - } -} - -b2ContactSolver::~b2ContactSolver() -{ - m_allocator->Free(m_velocityConstraints); - m_allocator->Free(m_positionConstraints); -} - -// Initialize position dependent portions of the velocity constraints. -void b2ContactSolver::InitializeVelocityConstraints() -{ - for (int32 i = 0; i < m_count; ++i) - { - b2ContactVelocityConstraint* vc = m_velocityConstraints + i; - b2ContactPositionConstraint* pc = m_positionConstraints + i; - - float32 radiusA = pc->radiusA; - float32 radiusB = pc->radiusB; - b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold(); - - int32 indexA = vc->indexA; - int32 indexB = vc->indexB; - - float32 mA = vc->invMassA; - float32 mB = vc->invMassB; - float32 iA = vc->invIA; - float32 iB = vc->invIB; - b2Vec2 localCenterA = pc->localCenterA; - b2Vec2 localCenterB = pc->localCenterB; - - b2Vec2 cA = m_positions[indexA].c; - float32 aA = m_positions[indexA].a; - b2Vec2 vA = m_velocities[indexA].v; - float32 wA = m_velocities[indexA].w; - - b2Vec2 cB = m_positions[indexB].c; - float32 aB = m_positions[indexB].a; - b2Vec2 vB = m_velocities[indexB].v; - float32 wB = m_velocities[indexB].w; - - b2Assert(manifold->pointCount > 0); - - b2Transform xfA, xfB; - xfA.q.Set(aA); - xfB.q.Set(aB); - xfA.p = cA - b2Mul(xfA.q, localCenterA); - xfB.p = cB - b2Mul(xfB.q, localCenterB); - - b2WorldManifold worldManifold; - worldManifold.Initialize(manifold, xfA, radiusA, xfB, radiusB); - - vc->normal = worldManifold.normal; - - int32 pointCount = vc->pointCount; - for (int32 j = 0; j < pointCount; ++j) - { - b2VelocityConstraintPoint* vcp = vc->points + j; - - vcp->rA = worldManifold.points[j] - cA; - vcp->rB = worldManifold.points[j] - cB; - - float32 rnA = b2Cross(vcp->rA, vc->normal); - float32 rnB = b2Cross(vcp->rB, vc->normal); - - float32 kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB; - - vcp->normalMass = kNormal > 0.0f ? 1.0f / kNormal : 0.0f; - - b2Vec2 tangent = b2Cross(vc->normal, 1.0f); - - float32 rtA = b2Cross(vcp->rA, tangent); - float32 rtB = b2Cross(vcp->rB, tangent); - - float32 kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB; - - vcp->tangentMass = kTangent > 0.0f ? 1.0f / kTangent : 0.0f; - - // Setup a velocity bias for restitution. - vcp->velocityBias = 0.0f; - float32 vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA)); - if (vRel < -b2_velocityThreshold) - { - vcp->velocityBias = -vc->restitution * vRel; - } - } - - // If we have two points, then prepare the block solver. - if (vc->pointCount == 2 && g_blockSolve) - { - b2VelocityConstraintPoint* vcp1 = vc->points + 0; - b2VelocityConstraintPoint* vcp2 = vc->points + 1; - - float32 rn1A = b2Cross(vcp1->rA, vc->normal); - float32 rn1B = b2Cross(vcp1->rB, vc->normal); - float32 rn2A = b2Cross(vcp2->rA, vc->normal); - float32 rn2B = b2Cross(vcp2->rB, vc->normal); - - float32 k11 = mA + mB + iA * rn1A * rn1A + iB * rn1B * rn1B; - float32 k22 = mA + mB + iA * rn2A * rn2A + iB * rn2B * rn2B; - float32 k12 = mA + mB + iA * rn1A * rn2A + iB * rn1B * rn2B; - - // Ensure a reasonable condition number. - const float32 k_maxConditionNumber = 1000.0f; - if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) - { - // K is safe to invert. - vc->K.ex.Set(k11, k12); - vc->K.ey.Set(k12, k22); - vc->normalMass = vc->K.GetInverse(); - } - else - { - // The constraints are redundant, just use one. - // TODO_ERIN use deepest? - vc->pointCount = 1; - } - } - } -} - -void b2ContactSolver::WarmStart() -{ - // Warm start. - for (int32 i = 0; i < m_count; ++i) - { - b2ContactVelocityConstraint* vc = m_velocityConstraints + i; - - int32 indexA = vc->indexA; - int32 indexB = vc->indexB; - float32 mA = vc->invMassA; - float32 iA = vc->invIA; - float32 mB = vc->invMassB; - float32 iB = vc->invIB; - int32 pointCount = vc->pointCount; - - b2Vec2 vA = m_velocities[indexA].v; - float32 wA = m_velocities[indexA].w; - b2Vec2 vB = m_velocities[indexB].v; - float32 wB = m_velocities[indexB].w; - - b2Vec2 normal = vc->normal; - b2Vec2 tangent = b2Cross(normal, 1.0f); - - for (int32 j = 0; j < pointCount; ++j) - { - b2VelocityConstraintPoint* vcp = vc->points + j; - b2Vec2 P = vcp->normalImpulse * normal + vcp->tangentImpulse * tangent; - wA -= iA * b2Cross(vcp->rA, P); - vA -= mA * P; - wB += iB * b2Cross(vcp->rB, P); - vB += mB * P; - } - - m_velocities[indexA].v = vA; - m_velocities[indexA].w = wA; - m_velocities[indexB].v = vB; - m_velocities[indexB].w = wB; - } -} - -void b2ContactSolver::SolveVelocityConstraints() -{ - for (int32 i = 0; i < m_count; ++i) - { - b2ContactVelocityConstraint* vc = m_velocityConstraints + i; - - int32 indexA = vc->indexA; - int32 indexB = vc->indexB; - float32 mA = vc->invMassA; - float32 iA = vc->invIA; - float32 mB = vc->invMassB; - float32 iB = vc->invIB; - int32 pointCount = vc->pointCount; - - b2Vec2 vA = m_velocities[indexA].v; - float32 wA = m_velocities[indexA].w; - b2Vec2 vB = m_velocities[indexB].v; - float32 wB = m_velocities[indexB].w; - - b2Vec2 normal = vc->normal; - b2Vec2 tangent = b2Cross(normal, 1.0f); - float32 friction = vc->friction; - - b2Assert(pointCount == 1 || pointCount == 2); - - // Solve tangent constraints first because non-penetration is more important - // than friction. - for (int32 j = 0; j < pointCount; ++j) - { - b2VelocityConstraintPoint* vcp = vc->points + j; - - // Relative velocity at contact - b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA); - - // Compute tangent force - float32 vt = b2Dot(dv, tangent) - vc->tangentSpeed; - float32 lambda = vcp->tangentMass * (-vt); - - // b2Clamp the accumulated force - float32 maxFriction = friction * vcp->normalImpulse; - float32 newImpulse = b2Clamp(vcp->tangentImpulse + lambda, -maxFriction, maxFriction); - lambda = newImpulse - vcp->tangentImpulse; - vcp->tangentImpulse = newImpulse; - - // Apply contact impulse - b2Vec2 P = lambda * tangent; - - vA -= mA * P; - wA -= iA * b2Cross(vcp->rA, P); - - vB += mB * P; - wB += iB * b2Cross(vcp->rB, P); - } - - // Solve normal constraints - if (pointCount == 1 || g_blockSolve == false) - { - for (int32 j = 0; j < pointCount; ++j) - { - b2VelocityConstraintPoint* vcp = vc->points + j; - - // Relative velocity at contact - b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA); - - // Compute normal impulse - float32 vn = b2Dot(dv, normal); - float32 lambda = -vcp->normalMass * (vn - vcp->velocityBias); - - // b2Clamp the accumulated impulse - float32 newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f); - lambda = newImpulse - vcp->normalImpulse; - vcp->normalImpulse = newImpulse; - - // Apply contact impulse - b2Vec2 P = lambda * normal; - vA -= mA * P; - wA -= iA * b2Cross(vcp->rA, P); - - vB += mB * P; - wB += iB * b2Cross(vcp->rB, P); - } - } - else - { - // Block solver developed in collaboration with Dirk Gregorius (back in 01/07 on Box2D_Lite). - // Build the mini LCP for this contact patch - // - // vn = A * x + b, vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2 - // - // A = J * W * JT and J = ( -n, -r1 x n, n, r2 x n ) - // b = vn0 - velocityBias - // - // The system is solved using the "Total enumeration method" (s. Murty). The complementary constraint vn_i * x_i - // implies that we must have in any solution either vn_i = 0 or x_i = 0. So for the 2D contact problem the cases - // vn1 = 0 and vn2 = 0, x1 = 0 and x2 = 0, x1 = 0 and vn2 = 0, x2 = 0 and vn1 = 0 need to be tested. The first valid - // solution that satisfies the problem is chosen. - // - // In order to account of the accumulated impulse 'a' (because of the iterative nature of the solver which only requires - // that the accumulated impulse is clamped and not the incremental impulse) we change the impulse variable (x_i). - // - // Substitute: - // - // x = a + d - // - // a := old total impulse - // x := new total impulse - // d := incremental impulse - // - // For the current iteration we extend the formula for the incremental impulse - // to compute the new total impulse: - // - // vn = A * d + b - // = A * (x - a) + b - // = A * x + b - A * a - // = A * x + b' - // b' = b - A * a; - - b2VelocityConstraintPoint* cp1 = vc->points + 0; - b2VelocityConstraintPoint* cp2 = vc->points + 1; - - b2Vec2 a(cp1->normalImpulse, cp2->normalImpulse); - b2Assert(a.x >= 0.0f && a.y >= 0.0f); - - // Relative velocity at contact - b2Vec2 dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); - b2Vec2 dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); - - // Compute normal velocity - float32 vn1 = b2Dot(dv1, normal); - float32 vn2 = b2Dot(dv2, normal); - - b2Vec2 b; - b.x = vn1 - cp1->velocityBias; - b.y = vn2 - cp2->velocityBias; - - // Compute b' - b -= b2Mul(vc->K, a); - - const float32 k_errorTol = 1e-3f; - B2_NOT_USED(k_errorTol); - - for (;;) - { - // - // Case 1: vn = 0 - // - // 0 = A * x + b' - // - // Solve for x: - // - // x = - inv(A) * b' - // - b2Vec2 x = - b2Mul(vc->normalMass, b); - - if (x.x >= 0.0f && x.y >= 0.0f) - { - // Get the incremental impulse - b2Vec2 d = x - a; - - // Apply incremental impulse - b2Vec2 P1 = d.x * normal; - b2Vec2 P2 = d.y * normal; - vA -= mA * (P1 + P2); - wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); - - vB += mB * (P1 + P2); - wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); - - // Accumulate - cp1->normalImpulse = x.x; - cp2->normalImpulse = x.y; - -#if B2_DEBUG_SOLVER == 1 - // Postconditions - dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); - dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); - - // Compute normal velocity - vn1 = b2Dot(dv1, normal); - vn2 = b2Dot(dv2, normal); - - b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol); - b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol); -#endif - break; - } - - // - // Case 2: vn1 = 0 and x2 = 0 - // - // 0 = a11 * x1 + a12 * 0 + b1' - // vn2 = a21 * x1 + a22 * 0 + b2' - // - x.x = - cp1->normalMass * b.x; - x.y = 0.0f; - vn1 = 0.0f; - vn2 = vc->K.ex.y * x.x + b.y; - if (x.x >= 0.0f && vn2 >= 0.0f) - { - // Get the incremental impulse - b2Vec2 d = x - a; - - // Apply incremental impulse - b2Vec2 P1 = d.x * normal; - b2Vec2 P2 = d.y * normal; - vA -= mA * (P1 + P2); - wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); - - vB += mB * (P1 + P2); - wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); - - // Accumulate - cp1->normalImpulse = x.x; - cp2->normalImpulse = x.y; - -#if B2_DEBUG_SOLVER == 1 - // Postconditions - dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); - - // Compute normal velocity - vn1 = b2Dot(dv1, normal); - - b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol); -#endif - break; - } - - - // - // Case 3: vn2 = 0 and x1 = 0 - // - // vn1 = a11 * 0 + a12 * x2 + b1' - // 0 = a21 * 0 + a22 * x2 + b2' - // - x.x = 0.0f; - x.y = - cp2->normalMass * b.y; - vn1 = vc->K.ey.x * x.y + b.x; - vn2 = 0.0f; - - if (x.y >= 0.0f && vn1 >= 0.0f) - { - // Resubstitute for the incremental impulse - b2Vec2 d = x - a; - - // Apply incremental impulse - b2Vec2 P1 = d.x * normal; - b2Vec2 P2 = d.y * normal; - vA -= mA * (P1 + P2); - wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); - - vB += mB * (P1 + P2); - wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); - - // Accumulate - cp1->normalImpulse = x.x; - cp2->normalImpulse = x.y; - -#if B2_DEBUG_SOLVER == 1 - // Postconditions - dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); - - // Compute normal velocity - vn2 = b2Dot(dv2, normal); - - b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol); -#endif - break; - } - - // - // Case 4: x1 = 0 and x2 = 0 - // - // vn1 = b1 - // vn2 = b2; - x.x = 0.0f; - x.y = 0.0f; - vn1 = b.x; - vn2 = b.y; - - if (vn1 >= 0.0f && vn2 >= 0.0f ) - { - // Resubstitute for the incremental impulse - b2Vec2 d = x - a; - - // Apply incremental impulse - b2Vec2 P1 = d.x * normal; - b2Vec2 P2 = d.y * normal; - vA -= mA * (P1 + P2); - wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); - - vB += mB * (P1 + P2); - wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); - - // Accumulate - cp1->normalImpulse = x.x; - cp2->normalImpulse = x.y; - - break; - } - - // No solution, give up. This is hit sometimes, but it doesn't seem to matter. - break; - } - } - - m_velocities[indexA].v = vA; - m_velocities[indexA].w = wA; - m_velocities[indexB].v = vB; - m_velocities[indexB].w = wB; - } -} - -void b2ContactSolver::StoreImpulses() -{ - for (int32 i = 0; i < m_count; ++i) - { - b2ContactVelocityConstraint* vc = m_velocityConstraints + i; - b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold(); - - for (int32 j = 0; j < vc->pointCount; ++j) - { - manifold->points[j].normalImpulse = vc->points[j].normalImpulse; - manifold->points[j].tangentImpulse = vc->points[j].tangentImpulse; - } - } -} - -struct b2PositionSolverManifold -{ - void Initialize(b2ContactPositionConstraint* pc, const b2Transform& xfA, const b2Transform& xfB, int32 index) - { - b2Assert(pc->pointCount > 0); - - switch (pc->type) - { - case b2Manifold::e_circles: - { - b2Vec2 pointA = b2Mul(xfA, pc->localPoint); - b2Vec2 pointB = b2Mul(xfB, pc->localPoints[0]); - normal = pointB - pointA; - normal.Normalize(); - point = 0.5f * (pointA + pointB); - separation = b2Dot(pointB - pointA, normal) - pc->radiusA - pc->radiusB; - } - break; - - case b2Manifold::e_faceA: - { - normal = b2Mul(xfA.q, pc->localNormal); - b2Vec2 planePoint = b2Mul(xfA, pc->localPoint); - - b2Vec2 clipPoint = b2Mul(xfB, pc->localPoints[index]); - separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB; - point = clipPoint; - } - break; - - case b2Manifold::e_faceB: - { - normal = b2Mul(xfB.q, pc->localNormal); - b2Vec2 planePoint = b2Mul(xfB, pc->localPoint); - - b2Vec2 clipPoint = b2Mul(xfA, pc->localPoints[index]); - separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB; - point = clipPoint; - - // Ensure normal points from A to B - normal = -normal; - } - break; - } - } - - b2Vec2 normal; - b2Vec2 point; - float32 separation; -}; - -// Sequential solver. -bool b2ContactSolver::SolvePositionConstraints() -{ - float32 minSeparation = 0.0f; - - for (int32 i = 0; i < m_count; ++i) - { - b2ContactPositionConstraint* pc = m_positionConstraints + i; - - int32 indexA = pc->indexA; - int32 indexB = pc->indexB; - b2Vec2 localCenterA = pc->localCenterA; - float32 mA = pc->invMassA; - float32 iA = pc->invIA; - b2Vec2 localCenterB = pc->localCenterB; - float32 mB = pc->invMassB; - float32 iB = pc->invIB; - int32 pointCount = pc->pointCount; - - b2Vec2 cA = m_positions[indexA].c; - float32 aA = m_positions[indexA].a; - - b2Vec2 cB = m_positions[indexB].c; - float32 aB = m_positions[indexB].a; - - // Solve normal constraints - for (int32 j = 0; j < pointCount; ++j) - { - b2Transform xfA, xfB; - xfA.q.Set(aA); - xfB.q.Set(aB); - xfA.p = cA - b2Mul(xfA.q, localCenterA); - xfB.p = cB - b2Mul(xfB.q, localCenterB); - - b2PositionSolverManifold psm; - psm.Initialize(pc, xfA, xfB, j); - b2Vec2 normal = psm.normal; - - b2Vec2 point = psm.point; - float32 separation = psm.separation; - - b2Vec2 rA = point - cA; - b2Vec2 rB = point - cB; - - // Track max constraint error. - minSeparation = b2Min(minSeparation, separation); - - // Prevent large corrections and allow slop. - float32 C = b2Clamp(b2_baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f); - - // Compute the effective mass. - float32 rnA = b2Cross(rA, normal); - float32 rnB = b2Cross(rB, normal); - float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; - - // Compute normal impulse - float32 impulse = K > 0.0f ? - C / K : 0.0f; - - b2Vec2 P = impulse * normal; - - cA -= mA * P; - aA -= iA * b2Cross(rA, P); - - cB += mB * P; - aB += iB * b2Cross(rB, P); - } - - m_positions[indexA].c = cA; - m_positions[indexA].a = aA; - - m_positions[indexB].c = cB; - m_positions[indexB].a = aB; - } - - // We can't expect minSpeparation >= -b2_linearSlop because we don't - // push the separation above -b2_linearSlop. - return minSeparation >= -3.0f * b2_linearSlop; -} - -// Sequential position solver for position constraints. -bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB) -{ - float32 minSeparation = 0.0f; - - for (int32 i = 0; i < m_count; ++i) - { - b2ContactPositionConstraint* pc = m_positionConstraints + i; - - int32 indexA = pc->indexA; - int32 indexB = pc->indexB; - b2Vec2 localCenterA = pc->localCenterA; - b2Vec2 localCenterB = pc->localCenterB; - int32 pointCount = pc->pointCount; - - float32 mA = 0.0f; - float32 iA = 0.0f; - if (indexA == toiIndexA || indexA == toiIndexB) - { - mA = pc->invMassA; - iA = pc->invIA; - } - - float32 mB = 0.0f; - float32 iB = 0.; - if (indexB == toiIndexA || indexB == toiIndexB) - { - mB = pc->invMassB; - iB = pc->invIB; - } - - b2Vec2 cA = m_positions[indexA].c; - float32 aA = m_positions[indexA].a; - - b2Vec2 cB = m_positions[indexB].c; - float32 aB = m_positions[indexB].a; - - // Solve normal constraints - for (int32 j = 0; j < pointCount; ++j) - { - b2Transform xfA, xfB; - xfA.q.Set(aA); - xfB.q.Set(aB); - xfA.p = cA - b2Mul(xfA.q, localCenterA); - xfB.p = cB - b2Mul(xfB.q, localCenterB); - - b2PositionSolverManifold psm; - psm.Initialize(pc, xfA, xfB, j); - b2Vec2 normal = psm.normal; - - b2Vec2 point = psm.point; - float32 separation = psm.separation; - - b2Vec2 rA = point - cA; - b2Vec2 rB = point - cB; - - // Track max constraint error. - minSeparation = b2Min(minSeparation, separation); - - // Prevent large corrections and allow slop. - float32 C = b2Clamp(b2_toiBaugarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f); - - // Compute the effective mass. - float32 rnA = b2Cross(rA, normal); - float32 rnB = b2Cross(rB, normal); - float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; - - // Compute normal impulse - float32 impulse = K > 0.0f ? - C / K : 0.0f; - - b2Vec2 P = impulse * normal; - - cA -= mA * P; - aA -= iA * b2Cross(rA, P); - - cB += mB * P; - aB += iB * b2Cross(rB, P); - } - - m_positions[indexA].c = cA; - m_positions[indexA].a = aA; - - m_positions[indexB].c = cB; - m_positions[indexB].a = aB; - } - - // We can't expect minSpeparation >= -b2_linearSlop because we don't - // push the separation above -b2_linearSlop. - return minSeparation >= -1.5f * b2_linearSlop; -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ContactSolver.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ContactSolver.h deleted file mode 100644 index ed98df5..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2ContactSolver.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CONTACT_SOLVER_H -#define B2_CONTACT_SOLVER_H - -#include "Box2D/Common/b2Math.h" -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -class b2Contact; -class b2Body; -class b2StackAllocator; -struct b2ContactPositionConstraint; - -struct b2VelocityConstraintPoint -{ - b2Vec2 rA; - b2Vec2 rB; - float32 normalImpulse; - float32 tangentImpulse; - float32 normalMass; - float32 tangentMass; - float32 velocityBias; -}; - -struct b2ContactVelocityConstraint -{ - b2VelocityConstraintPoint points[b2_maxManifoldPoints]; - b2Vec2 normal; - b2Mat22 normalMass; - b2Mat22 K; - int32 indexA; - int32 indexB; - float32 invMassA, invMassB; - float32 invIA, invIB; - float32 friction; - float32 restitution; - float32 tangentSpeed; - int32 pointCount; - int32 contactIndex; -}; - -struct b2ContactSolverDef -{ - b2TimeStep step; - b2Contact** contacts; - int32 count; - b2Position* positions; - b2Velocity* velocities; - b2StackAllocator* allocator; -}; - -class b2ContactSolver -{ -public: - b2ContactSolver(b2ContactSolverDef* def); - ~b2ContactSolver(); - - void InitializeVelocityConstraints(); - - void WarmStart(); - void SolveVelocityConstraints(); - void StoreImpulses(); - - bool SolvePositionConstraints(); - bool SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB); - - b2TimeStep m_step; - b2Position* m_positions; - b2Velocity* m_velocities; - b2StackAllocator* m_allocator; - b2ContactPositionConstraint* m_positionConstraints; - b2ContactVelocityConstraint* m_velocityConstraints; - b2Contact** m_contacts; - int m_count; -}; - -#endif - diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp deleted file mode 100644 index 8d5933e..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Dynamics/b2Fixture.h" - -#include <new> - -b2Contact* b2EdgeAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2EdgeAndCircleContact)); - return new (mem) b2EdgeAndCircleContact(fixtureA, fixtureB); -} - -void b2EdgeAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2EdgeAndCircleContact*)contact)->~b2EdgeAndCircleContact(); - allocator->Free(contact, sizeof(b2EdgeAndCircleContact)); -} - -b2EdgeAndCircleContact::b2EdgeAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) -: b2Contact(fixtureA, 0, fixtureB, 0) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_edge); - b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); -} - -void b2EdgeAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2CollideEdgeAndCircle( manifold, - (b2EdgeShape*)m_fixtureA->GetShape(), xfA, - (b2CircleShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h deleted file mode 100644 index e241985..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_EDGE_AND_CIRCLE_CONTACT_H -#define B2_EDGE_AND_CIRCLE_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2EdgeAndCircleContact : public b2Contact -{ -public: - static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2EdgeAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); - ~b2EdgeAndCircleContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp deleted file mode 100644 index 6fab3f7..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Dynamics/b2Fixture.h" - -#include <new> - -b2Contact* b2EdgeAndPolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2EdgeAndPolygonContact)); - return new (mem) b2EdgeAndPolygonContact(fixtureA, fixtureB); -} - -void b2EdgeAndPolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2EdgeAndPolygonContact*)contact)->~b2EdgeAndPolygonContact(); - allocator->Free(contact, sizeof(b2EdgeAndPolygonContact)); -} - -b2EdgeAndPolygonContact::b2EdgeAndPolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB) -: b2Contact(fixtureA, 0, fixtureB, 0) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_edge); - b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon); -} - -void b2EdgeAndPolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2CollideEdgeAndPolygon( manifold, - (b2EdgeShape*)m_fixtureA->GetShape(), xfA, - (b2PolygonShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h deleted file mode 100644 index ad92aac..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_EDGE_AND_POLYGON_CONTACT_H -#define B2_EDGE_AND_POLYGON_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2EdgeAndPolygonContact : public b2Contact -{ -public: - static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2EdgeAndPolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB); - ~b2EdgeAndPolygonContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp deleted file mode 100644 index d3c3b94..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Dynamics/b2Fixture.h" - -#include <new> - -b2Contact* b2PolygonAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2PolygonAndCircleContact)); - return new (mem) b2PolygonAndCircleContact(fixtureA, fixtureB); -} - -void b2PolygonAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2PolygonAndCircleContact*)contact)->~b2PolygonAndCircleContact(); - allocator->Free(contact, sizeof(b2PolygonAndCircleContact)); -} - -b2PolygonAndCircleContact::b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) -: b2Contact(fixtureA, 0, fixtureB, 0) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon); - b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); -} - -void b2PolygonAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2CollidePolygonAndCircle( manifold, - (b2PolygonShape*)m_fixtureA->GetShape(), xfA, - (b2CircleShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h deleted file mode 100644 index fc3573c..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_POLYGON_AND_CIRCLE_CONTACT_H -#define B2_POLYGON_AND_CIRCLE_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2PolygonAndCircleContact : public b2Contact -{ -public: - static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); - ~b2PolygonAndCircleContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonContact.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonContact.cpp deleted file mode 100644 index a9a6cdc..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Contacts/b2PolygonContact.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Collision/b2TimeOfImpact.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2WorldCallbacks.h" - -#include <new> - -b2Contact* b2PolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) -{ - void* mem = allocator->Allocate(sizeof(b2PolygonContact)); - return new (mem) b2PolygonContact(fixtureA, fixtureB); -} - -void b2PolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) -{ - ((b2PolygonContact*)contact)->~b2PolygonContact(); - allocator->Free(contact, sizeof(b2PolygonContact)); -} - -b2PolygonContact::b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB) - : b2Contact(fixtureA, 0, fixtureB, 0) -{ - b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon); - b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon); -} - -void b2PolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) -{ - b2CollidePolygons( manifold, - (b2PolygonShape*)m_fixtureA->GetShape(), xfA, - (b2PolygonShape*)m_fixtureB->GetShape(), xfB); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonContact.h b/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonContact.h deleted file mode 100644 index 4755b4b..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Contacts/b2PolygonContact.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_POLYGON_CONTACT_H -#define B2_POLYGON_CONTACT_H - -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -class b2BlockAllocator; - -class b2PolygonContact : public b2Contact -{ -public: - static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, - b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); - static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - - b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB); - ~b2PolygonContact() {} - - void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2DistanceJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2DistanceJoint.cpp deleted file mode 100644 index 126133c..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2DistanceJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// 1-D constrained system -// m (v2 - v1) = lambda -// v2 + (beta/h) * x1 + gamma * lambda = 0, gamma has units of inverse mass. -// x2 = x1 + h * v2 - -// 1-D mass-damper-spring system -// m (v2 - v1) + h * d * v2 + h * k * - -// C = norm(p2 - p1) - L -// u = (p2 - p1) / norm(p2 - p1) -// Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1)) -// J = [-u -cross(r1, u) u cross(r2, u)] -// K = J * invM * JT -// = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2 - -void b2DistanceJointDef::Initialize(b2Body* b1, b2Body* b2, - const b2Vec2& anchor1, const b2Vec2& anchor2) -{ - bodyA = b1; - bodyB = b2; - localAnchorA = bodyA->GetLocalPoint(anchor1); - localAnchorB = bodyB->GetLocalPoint(anchor2); - b2Vec2 d = anchor2 - anchor1; - length = d.Length(); -} - -b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - m_length = def->length; - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; - m_impulse = 0.0f; - m_gamma = 0.0f; - m_bias = 0.0f; -} - -void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - m_u = cB + m_rB - cA - m_rA; - - // Handle singularity. - float32 length = m_u.Length(); - if (length > b2_linearSlop) - { - m_u *= 1.0f / length; - } - else - { - m_u.Set(0.0f, 0.0f); - } - - float32 crAu = b2Cross(m_rA, m_u); - float32 crBu = b2Cross(m_rB, m_u); - float32 invMass = m_invMassA + m_invIA * crAu * crAu + m_invMassB + m_invIB * crBu * crBu; - - // Compute the effective mass matrix. - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - - if (m_frequencyHz > 0.0f) - { - float32 C = length - m_length; - - // Frequency - float32 omega = 2.0f * b2_pi * m_frequencyHz; - - // Damping coefficient - float32 d = 2.0f * m_mass * m_dampingRatio * omega; - - // Spring stiffness - float32 k = m_mass * omega * omega; - - // magic formulas - float32 h = data.step.dt; - m_gamma = h * (d + h * k); - m_gamma = m_gamma != 0.0f ? 1.0f / m_gamma : 0.0f; - m_bias = C * h * k * m_gamma; - - invMass += m_gamma; - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - } - else - { - m_gamma = 0.0f; - m_bias = 0.0f; - } - - if (data.step.warmStarting) - { - // Scale the impulse to support a variable time step. - m_impulse *= data.step.dtRatio; - - b2Vec2 P = m_impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - } - else - { - m_impulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - // Cdot = dot(u, v + cross(w, r)) - b2Vec2 vpA = vA + b2Cross(wA, m_rA); - b2Vec2 vpB = vB + b2Cross(wB, m_rB); - float32 Cdot = b2Dot(m_u, vpB - vpA); - - float32 impulse = -m_mass * (Cdot + m_bias + m_gamma * m_impulse); - m_impulse += impulse; - - b2Vec2 P = impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2DistanceJoint::SolvePositionConstraints(const b2SolverData& data) -{ - if (m_frequencyHz > 0.0f) - { - // There is no position correction for soft distance constraints. - return true; - } - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 u = cB + rB - cA - rA; - - float32 length = u.Normalize(); - float32 C = length - m_length; - C = b2Clamp(C, -b2_maxLinearCorrection, b2_maxLinearCorrection); - - float32 impulse = -m_mass * C; - b2Vec2 P = impulse * u; - - cA -= m_invMassA * P; - aA -= m_invIA * b2Cross(rA, P); - cB += m_invMassB * P; - aB += m_invIB * b2Cross(rB, P); - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return b2Abs(C) < b2_linearSlop; -} - -b2Vec2 b2DistanceJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2DistanceJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2DistanceJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 F = (inv_dt * m_impulse) * m_u; - return F; -} - -float32 b2DistanceJoint::GetReactionTorque(float32 inv_dt) const -{ - B2_NOT_USED(inv_dt); - return 0.0f; -} - -void b2DistanceJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2DistanceJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.length = %.15lef;\n", m_length); - b2Log(" jd.frequencyHz = %.15lef;\n", m_frequencyHz); - b2Log(" jd.dampingRatio = %.15lef;\n", m_dampingRatio); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2DistanceJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2DistanceJoint.h deleted file mode 100644 index ba59210..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2DistanceJoint.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_DISTANCE_JOINT_H -#define B2_DISTANCE_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Distance joint definition. This requires defining an -/// anchor point on both bodies and the non-zero length of the -/// distance joint. The definition uses local anchor points -/// so that the initial configuration can violate the constraint -/// slightly. This helps when saving and loading a game. -/// @warning Do not use a zero or short length. -struct b2DistanceJointDef : public b2JointDef -{ - b2DistanceJointDef() - { - type = e_distanceJoint; - localAnchorA.Set(0.0f, 0.0f); - localAnchorB.Set(0.0f, 0.0f); - length = 1.0f; - frequencyHz = 0.0f; - dampingRatio = 0.0f; - } - - /// Initialize the bodies, anchors, and length using the world - /// anchors. - void Initialize(b2Body* bodyA, b2Body* bodyB, - const b2Vec2& anchorA, const b2Vec2& anchorB); - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The natural length between the anchor points. - float32 length; - - /// The mass-spring-damper frequency in Hertz. A value of 0 - /// disables softness. - float32 frequencyHz; - - /// The damping ratio. 0 = no damping, 1 = critical damping. - float32 dampingRatio; -}; - -/// A distance joint constrains two points on two bodies -/// to remain at a fixed distance from each other. You can view -/// this as a massless, rigid rod. -class b2DistanceJoint : public b2Joint -{ -public: - - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - /// Get the reaction force given the inverse time step. - /// Unit is N. - b2Vec2 GetReactionForce(float32 inv_dt) const override; - - /// Get the reaction torque given the inverse time step. - /// Unit is N*m. This is always zero for a distance joint. - float32 GetReactionTorque(float32 inv_dt) const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// Set/get the natural length. - /// Manipulating the length can lead to non-physical behavior when the frequency is zero. - void SetLength(float32 length); - float32 GetLength() const; - - /// Set/get frequency in Hz. - void SetFrequency(float32 hz); - float32 GetFrequency() const; - - /// Set/get damping ratio. - void SetDampingRatio(float32 ratio); - float32 GetDampingRatio() const; - - /// Dump joint to dmLog - void Dump() override; - -protected: - - friend class b2Joint; - b2DistanceJoint(const b2DistanceJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - float32 m_frequencyHz; - float32 m_dampingRatio; - float32 m_bias; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - float32 m_gamma; - float32 m_impulse; - float32 m_length; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_u; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - float32 m_mass; -}; - -inline void b2DistanceJoint::SetLength(float32 length) -{ - m_length = length; -} - -inline float32 b2DistanceJoint::GetLength() const -{ - return m_length; -} - -inline void b2DistanceJoint::SetFrequency(float32 hz) -{ - m_frequencyHz = hz; -} - -inline float32 b2DistanceJoint::GetFrequency() const -{ - return m_frequencyHz; -} - -inline void b2DistanceJoint::SetDampingRatio(float32 ratio) -{ - m_dampingRatio = ratio; -} - -inline float32 b2DistanceJoint::GetDampingRatio() const -{ - return m_dampingRatio; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2FrictionJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2FrictionJoint.cpp deleted file mode 100644 index cb122eb..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2FrictionJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Point-to-point constraint -// Cdot = v2 - v1 -// = v2 + cross(w2, r2) - v1 - cross(w1, r1) -// J = [-I -r1_skew I r2_skew ] -// Identity used: -// w k % (rx i + ry j) = w * (-ry i + rx j) - -// Angle constraint -// Cdot = w2 - w1 -// J = [0 0 -1 0 0 1] -// K = invI1 + invI2 - -void b2FrictionJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor) -{ - bodyA = bA; - bodyB = bB; - localAnchorA = bodyA->GetLocalPoint(anchor); - localAnchorB = bodyB->GetLocalPoint(anchor); -} - -b2FrictionJoint::b2FrictionJoint(const b2FrictionJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - - m_linearImpulse.SetZero(); - m_angularImpulse = 0.0f; - - m_maxForce = def->maxForce; - m_maxTorque = def->maxTorque; -} - -void b2FrictionJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - // Compute the effective mass matrix. - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - // J = [-I -r1_skew I r2_skew] - // [ 0 -1 0 1] - // r_skew = [-ry; rx] - - // Matlab - // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] - // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] - // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - b2Mat22 K; - K.ex.x = mA + mB + iA * m_rA.y * m_rA.y + iB * m_rB.y * m_rB.y; - K.ex.y = -iA * m_rA.x * m_rA.y - iB * m_rB.x * m_rB.y; - K.ey.x = K.ex.y; - K.ey.y = mA + mB + iA * m_rA.x * m_rA.x + iB * m_rB.x * m_rB.x; - - m_linearMass = K.GetInverse(); - - m_angularMass = iA + iB; - if (m_angularMass > 0.0f) - { - m_angularMass = 1.0f / m_angularMass; - } - - if (data.step.warmStarting) - { - // Scale impulses to support a variable time step. - m_linearImpulse *= data.step.dtRatio; - m_angularImpulse *= data.step.dtRatio; - - b2Vec2 P(m_linearImpulse.x, m_linearImpulse.y); - vA -= mA * P; - wA -= iA * (b2Cross(m_rA, P) + m_angularImpulse); - vB += mB * P; - wB += iB * (b2Cross(m_rB, P) + m_angularImpulse); - } - else - { - m_linearImpulse.SetZero(); - m_angularImpulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2FrictionJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - float32 h = data.step.dt; - - // Solve angular friction - { - float32 Cdot = wB - wA; - float32 impulse = -m_angularMass * Cdot; - - float32 oldImpulse = m_angularImpulse; - float32 maxImpulse = h * m_maxTorque; - m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse); - impulse = m_angularImpulse - oldImpulse; - - wA -= iA * impulse; - wB += iB * impulse; - } - - // Solve linear friction - { - b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); - - b2Vec2 impulse = -b2Mul(m_linearMass, Cdot); - b2Vec2 oldImpulse = m_linearImpulse; - m_linearImpulse += impulse; - - float32 maxImpulse = h * m_maxForce; - - if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) - { - m_linearImpulse.Normalize(); - m_linearImpulse *= maxImpulse; - } - - impulse = m_linearImpulse - oldImpulse; - - vA -= mA * impulse; - wA -= iA * b2Cross(m_rA, impulse); - - vB += mB * impulse; - wB += iB * b2Cross(m_rB, impulse); - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2FrictionJoint::SolvePositionConstraints(const b2SolverData& data) -{ - B2_NOT_USED(data); - - return true; -} - -b2Vec2 b2FrictionJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2FrictionJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2FrictionJoint::GetReactionForce(float32 inv_dt) const -{ - return inv_dt * m_linearImpulse; -} - -float32 b2FrictionJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * m_angularImpulse; -} - -void b2FrictionJoint::SetMaxForce(float32 force) -{ - b2Assert(b2IsValid(force) && force >= 0.0f); - m_maxForce = force; -} - -float32 b2FrictionJoint::GetMaxForce() const -{ - return m_maxForce; -} - -void b2FrictionJoint::SetMaxTorque(float32 torque) -{ - b2Assert(b2IsValid(torque) && torque >= 0.0f); - m_maxTorque = torque; -} - -float32 b2FrictionJoint::GetMaxTorque() const -{ - return m_maxTorque; -} - -void b2FrictionJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2FrictionJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.maxForce = %.15lef;\n", m_maxForce); - b2Log(" jd.maxTorque = %.15lef;\n", m_maxTorque); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2FrictionJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2FrictionJoint.h deleted file mode 100644 index d964f84..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2FrictionJoint.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_FRICTION_JOINT_H -#define B2_FRICTION_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Friction joint definition. -struct b2FrictionJointDef : public b2JointDef -{ - b2FrictionJointDef() - { - type = e_frictionJoint; - localAnchorA.SetZero(); - localAnchorB.SetZero(); - maxForce = 0.0f; - maxTorque = 0.0f; - } - - /// Initialize the bodies, anchors, axis, and reference angle using the world - /// anchor and world axis. - void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The maximum friction force in N. - float32 maxForce; - - /// The maximum friction torque in N-m. - float32 maxTorque; -}; - -/// Friction joint. This is used for top-down friction. -/// It provides 2D translational friction and angular friction. -class b2FrictionJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// Set the maximum friction force in N. - void SetMaxForce(float32 force); - - /// Get the maximum friction force in N. - float32 GetMaxForce() const; - - /// Set the maximum friction torque in N*m. - void SetMaxTorque(float32 torque); - - /// Get the maximum friction torque in N*m. - float32 GetMaxTorque() const; - - /// Dump joint to dmLog - void Dump() override; - -protected: - - friend class b2Joint; - - b2FrictionJoint(const b2FrictionJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - - // Solver shared - b2Vec2 m_linearImpulse; - float32 m_angularImpulse; - float32 m_maxForce; - float32 m_maxTorque; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - b2Mat22 m_linearMass; - float32 m_angularMass; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2GearJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2GearJoint.cpp deleted file mode 100644 index 1ce575b..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2GearJoint.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* -* Copyright (c) 2007-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2GearJoint.h" -#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" -#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Gear Joint: -// C0 = (coordinate1 + ratio * coordinate2)_initial -// C = (coordinate1 + ratio * coordinate2) - C0 = 0 -// J = [J1 ratio * J2] -// K = J * invM * JT -// = J1 * invM1 * J1T + ratio * ratio * J2 * invM2 * J2T -// -// Revolute: -// coordinate = rotation -// Cdot = angularVelocity -// J = [0 0 1] -// K = J * invM * JT = invI -// -// Prismatic: -// coordinate = dot(p - pg, ug) -// Cdot = dot(v + cross(w, r), ug) -// J = [ug cross(r, ug)] -// K = J * invM * JT = invMass + invI * cross(r, ug)^2 - -b2GearJoint::b2GearJoint(const b2GearJointDef* def) -: b2Joint(def) -{ - m_joint1 = def->joint1; - m_joint2 = def->joint2; - - m_typeA = m_joint1->GetType(); - m_typeB = m_joint2->GetType(); - - b2Assert(m_typeA == e_revoluteJoint || m_typeA == e_prismaticJoint); - b2Assert(m_typeB == e_revoluteJoint || m_typeB == e_prismaticJoint); - - float32 coordinateA, coordinateB; - - // TODO_ERIN there might be some problem with the joint edges in b2Joint. - - m_bodyC = m_joint1->GetBodyA(); - m_bodyA = m_joint1->GetBodyB(); - - // Get geometry of joint1 - b2Transform xfA = m_bodyA->m_xf; - float32 aA = m_bodyA->m_sweep.a; - b2Transform xfC = m_bodyC->m_xf; - float32 aC = m_bodyC->m_sweep.a; - - if (m_typeA == e_revoluteJoint) - { - b2RevoluteJoint* revolute = (b2RevoluteJoint*)def->joint1; - m_localAnchorC = revolute->m_localAnchorA; - m_localAnchorA = revolute->m_localAnchorB; - m_referenceAngleA = revolute->m_referenceAngle; - m_localAxisC.SetZero(); - - coordinateA = aA - aC - m_referenceAngleA; - } - else - { - b2PrismaticJoint* prismatic = (b2PrismaticJoint*)def->joint1; - m_localAnchorC = prismatic->m_localAnchorA; - m_localAnchorA = prismatic->m_localAnchorB; - m_referenceAngleA = prismatic->m_referenceAngle; - m_localAxisC = prismatic->m_localXAxisA; - - b2Vec2 pC = m_localAnchorC; - b2Vec2 pA = b2MulT(xfC.q, b2Mul(xfA.q, m_localAnchorA) + (xfA.p - xfC.p)); - coordinateA = b2Dot(pA - pC, m_localAxisC); - } - - m_bodyD = m_joint2->GetBodyA(); - m_bodyB = m_joint2->GetBodyB(); - - // Get geometry of joint2 - b2Transform xfB = m_bodyB->m_xf; - float32 aB = m_bodyB->m_sweep.a; - b2Transform xfD = m_bodyD->m_xf; - float32 aD = m_bodyD->m_sweep.a; - - if (m_typeB == e_revoluteJoint) - { - b2RevoluteJoint* revolute = (b2RevoluteJoint*)def->joint2; - m_localAnchorD = revolute->m_localAnchorA; - m_localAnchorB = revolute->m_localAnchorB; - m_referenceAngleB = revolute->m_referenceAngle; - m_localAxisD.SetZero(); - - coordinateB = aB - aD - m_referenceAngleB; - } - else - { - b2PrismaticJoint* prismatic = (b2PrismaticJoint*)def->joint2; - m_localAnchorD = prismatic->m_localAnchorA; - m_localAnchorB = prismatic->m_localAnchorB; - m_referenceAngleB = prismatic->m_referenceAngle; - m_localAxisD = prismatic->m_localXAxisA; - - b2Vec2 pD = m_localAnchorD; - b2Vec2 pB = b2MulT(xfD.q, b2Mul(xfB.q, m_localAnchorB) + (xfB.p - xfD.p)); - coordinateB = b2Dot(pB - pD, m_localAxisD); - } - - m_ratio = def->ratio; - - m_constant = coordinateA + m_ratio * coordinateB; - - m_impulse = 0.0f; -} - -void b2GearJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_indexC = m_bodyC->m_islandIndex; - m_indexD = m_bodyD->m_islandIndex; - m_lcA = m_bodyA->m_sweep.localCenter; - m_lcB = m_bodyB->m_sweep.localCenter; - m_lcC = m_bodyC->m_sweep.localCenter; - m_lcD = m_bodyD->m_sweep.localCenter; - m_mA = m_bodyA->m_invMass; - m_mB = m_bodyB->m_invMass; - m_mC = m_bodyC->m_invMass; - m_mD = m_bodyD->m_invMass; - m_iA = m_bodyA->m_invI; - m_iB = m_bodyB->m_invI; - m_iC = m_bodyC->m_invI; - m_iD = m_bodyD->m_invI; - - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - float32 aC = data.positions[m_indexC].a; - b2Vec2 vC = data.velocities[m_indexC].v; - float32 wC = data.velocities[m_indexC].w; - - float32 aD = data.positions[m_indexD].a; - b2Vec2 vD = data.velocities[m_indexD].v; - float32 wD = data.velocities[m_indexD].w; - - b2Rot qA(aA), qB(aB), qC(aC), qD(aD); - - m_mass = 0.0f; - - if (m_typeA == e_revoluteJoint) - { - m_JvAC.SetZero(); - m_JwA = 1.0f; - m_JwC = 1.0f; - m_mass += m_iA + m_iC; - } - else - { - b2Vec2 u = b2Mul(qC, m_localAxisC); - b2Vec2 rC = b2Mul(qC, m_localAnchorC - m_lcC); - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_lcA); - m_JvAC = u; - m_JwC = b2Cross(rC, u); - m_JwA = b2Cross(rA, u); - m_mass += m_mC + m_mA + m_iC * m_JwC * m_JwC + m_iA * m_JwA * m_JwA; - } - - if (m_typeB == e_revoluteJoint) - { - m_JvBD.SetZero(); - m_JwB = m_ratio; - m_JwD = m_ratio; - m_mass += m_ratio * m_ratio * (m_iB + m_iD); - } - else - { - b2Vec2 u = b2Mul(qD, m_localAxisD); - b2Vec2 rD = b2Mul(qD, m_localAnchorD - m_lcD); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_lcB); - m_JvBD = m_ratio * u; - m_JwD = m_ratio * b2Cross(rD, u); - m_JwB = m_ratio * b2Cross(rB, u); - m_mass += m_ratio * m_ratio * (m_mD + m_mB) + m_iD * m_JwD * m_JwD + m_iB * m_JwB * m_JwB; - } - - // Compute effective mass. - m_mass = m_mass > 0.0f ? 1.0f / m_mass : 0.0f; - - if (data.step.warmStarting) - { - vA += (m_mA * m_impulse) * m_JvAC; - wA += m_iA * m_impulse * m_JwA; - vB += (m_mB * m_impulse) * m_JvBD; - wB += m_iB * m_impulse * m_JwB; - vC -= (m_mC * m_impulse) * m_JvAC; - wC -= m_iC * m_impulse * m_JwC; - vD -= (m_mD * m_impulse) * m_JvBD; - wD -= m_iD * m_impulse * m_JwD; - } - else - { - m_impulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; - data.velocities[m_indexC].v = vC; - data.velocities[m_indexC].w = wC; - data.velocities[m_indexD].v = vD; - data.velocities[m_indexD].w = wD; -} - -void b2GearJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - b2Vec2 vC = data.velocities[m_indexC].v; - float32 wC = data.velocities[m_indexC].w; - b2Vec2 vD = data.velocities[m_indexD].v; - float32 wD = data.velocities[m_indexD].w; - - float32 Cdot = b2Dot(m_JvAC, vA - vC) + b2Dot(m_JvBD, vB - vD); - Cdot += (m_JwA * wA - m_JwC * wC) + (m_JwB * wB - m_JwD * wD); - - float32 impulse = -m_mass * Cdot; - m_impulse += impulse; - - vA += (m_mA * impulse) * m_JvAC; - wA += m_iA * impulse * m_JwA; - vB += (m_mB * impulse) * m_JvBD; - wB += m_iB * impulse * m_JwB; - vC -= (m_mC * impulse) * m_JvAC; - wC -= m_iC * impulse * m_JwC; - vD -= (m_mD * impulse) * m_JvBD; - wD -= m_iD * impulse * m_JwD; - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; - data.velocities[m_indexC].v = vC; - data.velocities[m_indexC].w = wC; - data.velocities[m_indexD].v = vD; - data.velocities[m_indexD].w = wD; -} - -bool b2GearJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 cC = data.positions[m_indexC].c; - float32 aC = data.positions[m_indexC].a; - b2Vec2 cD = data.positions[m_indexD].c; - float32 aD = data.positions[m_indexD].a; - - b2Rot qA(aA), qB(aB), qC(aC), qD(aD); - - float32 linearError = 0.0f; - - float32 coordinateA, coordinateB; - - b2Vec2 JvAC, JvBD; - float32 JwA, JwB, JwC, JwD; - float32 mass = 0.0f; - - if (m_typeA == e_revoluteJoint) - { - JvAC.SetZero(); - JwA = 1.0f; - JwC = 1.0f; - mass += m_iA + m_iC; - - coordinateA = aA - aC - m_referenceAngleA; - } - else - { - b2Vec2 u = b2Mul(qC, m_localAxisC); - b2Vec2 rC = b2Mul(qC, m_localAnchorC - m_lcC); - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_lcA); - JvAC = u; - JwC = b2Cross(rC, u); - JwA = b2Cross(rA, u); - mass += m_mC + m_mA + m_iC * JwC * JwC + m_iA * JwA * JwA; - - b2Vec2 pC = m_localAnchorC - m_lcC; - b2Vec2 pA = b2MulT(qC, rA + (cA - cC)); - coordinateA = b2Dot(pA - pC, m_localAxisC); - } - - if (m_typeB == e_revoluteJoint) - { - JvBD.SetZero(); - JwB = m_ratio; - JwD = m_ratio; - mass += m_ratio * m_ratio * (m_iB + m_iD); - - coordinateB = aB - aD - m_referenceAngleB; - } - else - { - b2Vec2 u = b2Mul(qD, m_localAxisD); - b2Vec2 rD = b2Mul(qD, m_localAnchorD - m_lcD); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_lcB); - JvBD = m_ratio * u; - JwD = m_ratio * b2Cross(rD, u); - JwB = m_ratio * b2Cross(rB, u); - mass += m_ratio * m_ratio * (m_mD + m_mB) + m_iD * JwD * JwD + m_iB * JwB * JwB; - - b2Vec2 pD = m_localAnchorD - m_lcD; - b2Vec2 pB = b2MulT(qD, rB + (cB - cD)); - coordinateB = b2Dot(pB - pD, m_localAxisD); - } - - float32 C = (coordinateA + m_ratio * coordinateB) - m_constant; - - float32 impulse = 0.0f; - if (mass > 0.0f) - { - impulse = -C / mass; - } - - cA += m_mA * impulse * JvAC; - aA += m_iA * impulse * JwA; - cB += m_mB * impulse * JvBD; - aB += m_iB * impulse * JwB; - cC -= m_mC * impulse * JvAC; - aC -= m_iC * impulse * JwC; - cD -= m_mD * impulse * JvBD; - aD -= m_iD * impulse * JwD; - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - data.positions[m_indexC].c = cC; - data.positions[m_indexC].a = aC; - data.positions[m_indexD].c = cD; - data.positions[m_indexD].a = aD; - - // TODO_ERIN not implemented - return linearError < b2_linearSlop; -} - -b2Vec2 b2GearJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2GearJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2GearJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 P = m_impulse * m_JvAC; - return inv_dt * P; -} - -float32 b2GearJoint::GetReactionTorque(float32 inv_dt) const -{ - float32 L = m_impulse * m_JwA; - return inv_dt * L; -} - -void b2GearJoint::SetRatio(float32 ratio) -{ - b2Assert(b2IsValid(ratio)); - m_ratio = ratio; -} - -float32 b2GearJoint::GetRatio() const -{ - return m_ratio; -} - -void b2GearJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - int32 index1 = m_joint1->m_index; - int32 index2 = m_joint2->m_index; - - b2Log(" b2GearJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.joint1 = joints[%d];\n", index1); - b2Log(" jd.joint2 = joints[%d];\n", index2); - b2Log(" jd.ratio = %.15lef;\n", m_ratio); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2GearJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2GearJoint.h deleted file mode 100644 index 53f7e58..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2GearJoint.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_GEAR_JOINT_H -#define B2_GEAR_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Gear joint definition. This definition requires two existing -/// revolute or prismatic joints (any combination will work). -struct b2GearJointDef : public b2JointDef -{ - b2GearJointDef() - { - type = e_gearJoint; - joint1 = nullptr; - joint2 = nullptr; - ratio = 1.0f; - } - - /// The first revolute/prismatic joint attached to the gear joint. - b2Joint* joint1; - - /// The second revolute/prismatic joint attached to the gear joint. - b2Joint* joint2; - - /// The gear ratio. - /// @see b2GearJoint for explanation. - float32 ratio; -}; - -/// A gear joint is used to connect two joints together. Either joint -/// can be a revolute or prismatic joint. You specify a gear ratio -/// to bind the motions together: -/// coordinate1 + ratio * coordinate2 = constant -/// The ratio can be negative or positive. If one joint is a revolute joint -/// and the other joint is a prismatic joint, then the ratio will have units -/// of length or units of 1/length. -/// @warning You have to manually destroy the gear joint if joint1 or joint2 -/// is destroyed. -class b2GearJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// Get the first joint. - b2Joint* GetJoint1() { return m_joint1; } - - /// Get the second joint. - b2Joint* GetJoint2() { return m_joint2; } - - /// Set/Get the gear ratio. - void SetRatio(float32 ratio); - float32 GetRatio() const; - - /// Dump joint to dmLog - void Dump() override; - -protected: - - friend class b2Joint; - b2GearJoint(const b2GearJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - b2Joint* m_joint1; - b2Joint* m_joint2; - - b2JointType m_typeA; - b2JointType m_typeB; - - // Body A is connected to body C - // Body B is connected to body D - b2Body* m_bodyC; - b2Body* m_bodyD; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - b2Vec2 m_localAnchorC; - b2Vec2 m_localAnchorD; - - b2Vec2 m_localAxisC; - b2Vec2 m_localAxisD; - - float32 m_referenceAngleA; - float32 m_referenceAngleB; - - float32 m_constant; - float32 m_ratio; - - float32 m_impulse; - - // Solver temp - int32 m_indexA, m_indexB, m_indexC, m_indexD; - b2Vec2 m_lcA, m_lcB, m_lcC, m_lcD; - float32 m_mA, m_mB, m_mC, m_mD; - float32 m_iA, m_iB, m_iC, m_iD; - b2Vec2 m_JvAC, m_JvBD; - float32 m_JwA, m_JwB, m_JwC, m_JwD; - float32 m_mass; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2Joint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2Joint.cpp deleted file mode 100644 index 8103b01..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2Joint.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2Joint.h" -#include "Box2D/Dynamics/Joints/b2DistanceJoint.h" -#include "Box2D/Dynamics/Joints/b2WheelJoint.h" -#include "Box2D/Dynamics/Joints/b2MouseJoint.h" -#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" -#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" -#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" -#include "Box2D/Dynamics/Joints/b2GearJoint.h" -#include "Box2D/Dynamics/Joints/b2WeldJoint.h" -#include "Box2D/Dynamics/Joints/b2FrictionJoint.h" -#include "Box2D/Dynamics/Joints/b2RopeJoint.h" -#include "Box2D/Dynamics/Joints/b2MotorJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2World.h" -#include "Box2D/Common/b2BlockAllocator.h" - -#include <new> - -b2Joint* b2Joint::Create(const b2JointDef* def, b2BlockAllocator* allocator) -{ - b2Joint* joint = nullptr; - - switch (def->type) - { - case e_distanceJoint: - { - void* mem = allocator->Allocate(sizeof(b2DistanceJoint)); - joint = new (mem) b2DistanceJoint(static_cast<const b2DistanceJointDef*>(def)); - } - break; - - case e_mouseJoint: - { - void* mem = allocator->Allocate(sizeof(b2MouseJoint)); - joint = new (mem) b2MouseJoint(static_cast<const b2MouseJointDef*>(def)); - } - break; - - case e_prismaticJoint: - { - void* mem = allocator->Allocate(sizeof(b2PrismaticJoint)); - joint = new (mem) b2PrismaticJoint(static_cast<const b2PrismaticJointDef*>(def)); - } - break; - - case e_revoluteJoint: - { - void* mem = allocator->Allocate(sizeof(b2RevoluteJoint)); - joint = new (mem) b2RevoluteJoint(static_cast<const b2RevoluteJointDef*>(def)); - } - break; - - case e_pulleyJoint: - { - void* mem = allocator->Allocate(sizeof(b2PulleyJoint)); - joint = new (mem) b2PulleyJoint(static_cast<const b2PulleyJointDef*>(def)); - } - break; - - case e_gearJoint: - { - void* mem = allocator->Allocate(sizeof(b2GearJoint)); - joint = new (mem) b2GearJoint(static_cast<const b2GearJointDef*>(def)); - } - break; - - case e_wheelJoint: - { - void* mem = allocator->Allocate(sizeof(b2WheelJoint)); - joint = new (mem) b2WheelJoint(static_cast<const b2WheelJointDef*>(def)); - } - break; - - case e_weldJoint: - { - void* mem = allocator->Allocate(sizeof(b2WeldJoint)); - joint = new (mem) b2WeldJoint(static_cast<const b2WeldJointDef*>(def)); - } - break; - - case e_frictionJoint: - { - void* mem = allocator->Allocate(sizeof(b2FrictionJoint)); - joint = new (mem) b2FrictionJoint(static_cast<const b2FrictionJointDef*>(def)); - } - break; - - case e_ropeJoint: - { - void* mem = allocator->Allocate(sizeof(b2RopeJoint)); - joint = new (mem) b2RopeJoint(static_cast<const b2RopeJointDef*>(def)); - } - break; - - case e_motorJoint: - { - void* mem = allocator->Allocate(sizeof(b2MotorJoint)); - joint = new (mem) b2MotorJoint(static_cast<const b2MotorJointDef*>(def)); - } - break; - - default: - b2Assert(false); - break; - } - - return joint; -} - -void b2Joint::Destroy(b2Joint* joint, b2BlockAllocator* allocator) -{ - joint->~b2Joint(); - switch (joint->m_type) - { - case e_distanceJoint: - allocator->Free(joint, sizeof(b2DistanceJoint)); - break; - - case e_mouseJoint: - allocator->Free(joint, sizeof(b2MouseJoint)); - break; - - case e_prismaticJoint: - allocator->Free(joint, sizeof(b2PrismaticJoint)); - break; - - case e_revoluteJoint: - allocator->Free(joint, sizeof(b2RevoluteJoint)); - break; - - case e_pulleyJoint: - allocator->Free(joint, sizeof(b2PulleyJoint)); - break; - - case e_gearJoint: - allocator->Free(joint, sizeof(b2GearJoint)); - break; - - case e_wheelJoint: - allocator->Free(joint, sizeof(b2WheelJoint)); - break; - - case e_weldJoint: - allocator->Free(joint, sizeof(b2WeldJoint)); - break; - - case e_frictionJoint: - allocator->Free(joint, sizeof(b2FrictionJoint)); - break; - - case e_ropeJoint: - allocator->Free(joint, sizeof(b2RopeJoint)); - break; - - case e_motorJoint: - allocator->Free(joint, sizeof(b2MotorJoint)); - break; - - default: - b2Assert(false); - break; - } -} - -b2Joint::b2Joint(const b2JointDef* def) -{ - b2Assert(def->bodyA != def->bodyB); - - m_type = def->type; - m_prev = nullptr; - m_next = nullptr; - m_bodyA = def->bodyA; - m_bodyB = def->bodyB; - m_index = 0; - m_collideConnected = def->collideConnected; - m_islandFlag = false; - m_userData = def->userData; - - m_edgeA.joint = nullptr; - m_edgeA.other = nullptr; - m_edgeA.prev = nullptr; - m_edgeA.next = nullptr; - - m_edgeB.joint = nullptr; - m_edgeB.other = nullptr; - m_edgeB.prev = nullptr; - m_edgeB.next = nullptr; -} - -bool b2Joint::IsActive() const -{ - return m_bodyA->IsActive() && m_bodyB->IsActive(); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2Joint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2Joint.h deleted file mode 100644 index 2ab5616..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2Joint.h +++ /dev/null @@ -1,226 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_JOINT_H -#define B2_JOINT_H - -#include "Box2D/Common/b2Math.h" - -class b2Body; -class b2Joint; -struct b2SolverData; -class b2BlockAllocator; - -enum b2JointType -{ - e_unknownJoint, - e_revoluteJoint, - e_prismaticJoint, - e_distanceJoint, - e_pulleyJoint, - e_mouseJoint, - e_gearJoint, - e_wheelJoint, - e_weldJoint, - e_frictionJoint, - e_ropeJoint, - e_motorJoint -}; - -enum b2LimitState -{ - e_inactiveLimit, - e_atLowerLimit, - e_atUpperLimit, - e_equalLimits -}; - -struct b2Jacobian -{ - b2Vec2 linear; - float32 angularA; - float32 angularB; -}; - -/// A joint edge is used to connect bodies and joints together -/// in a joint graph where each body is a node and each joint -/// is an edge. A joint edge belongs to a doubly linked list -/// maintained in each attached body. Each joint has two joint -/// nodes, one for each attached body. -struct b2JointEdge -{ - b2Body* other; ///< provides quick access to the other body attached. - b2Joint* joint; ///< the joint - b2JointEdge* prev; ///< the previous joint edge in the body's joint list - b2JointEdge* next; ///< the next joint edge in the body's joint list -}; - -/// Joint definitions are used to construct joints. -struct b2JointDef -{ - b2JointDef() - { - type = e_unknownJoint; - userData = nullptr; - bodyA = nullptr; - bodyB = nullptr; - collideConnected = false; - } - - /// The joint type is set automatically for concrete joint types. - b2JointType type; - - /// Use this to attach application specific data to your joints. - void* userData; - - /// The first attached body. - b2Body* bodyA; - - /// The second attached body. - b2Body* bodyB; - - /// Set this flag to true if the attached bodies should collide. - bool collideConnected; -}; - -/// The base joint class. Joints are used to constraint two bodies together in -/// various fashions. Some joints also feature limits and motors. -class b2Joint -{ -public: - - /// Get the type of the concrete joint. - b2JointType GetType() const; - - /// Get the first body attached to this joint. - b2Body* GetBodyA(); - - /// Get the second body attached to this joint. - b2Body* GetBodyB(); - - /// Get the anchor point on bodyA in world coordinates. - virtual b2Vec2 GetAnchorA() const = 0; - - /// Get the anchor point on bodyB in world coordinates. - virtual b2Vec2 GetAnchorB() const = 0; - - /// Get the reaction force on bodyB at the joint anchor in Newtons. - virtual b2Vec2 GetReactionForce(float32 inv_dt) const = 0; - - /// Get the reaction torque on bodyB in N*m. - virtual float32 GetReactionTorque(float32 inv_dt) const = 0; - - /// Get the next joint the world joint list. - b2Joint* GetNext(); - const b2Joint* GetNext() const; - - /// Get the user data pointer. - void* GetUserData() const; - - /// Set the user data pointer. - void SetUserData(void* data); - - /// Short-cut function to determine if either body is inactive. - bool IsActive() const; - - /// Get collide connected. - /// Note: modifying the collide connect flag won't work correctly because - /// the flag is only checked when fixture AABBs begin to overlap. - bool GetCollideConnected() const; - - /// Dump this joint to the log file. - virtual void Dump() { b2Log("// Dump is not supported for this joint type.\n"); } - - /// Shift the origin for any points stored in world coordinates. - virtual void ShiftOrigin(const b2Vec2& newOrigin) { B2_NOT_USED(newOrigin); } - -protected: - friend class b2World; - friend class b2Body; - friend class b2Island; - friend class b2GearJoint; - - static b2Joint* Create(const b2JointDef* def, b2BlockAllocator* allocator); - static void Destroy(b2Joint* joint, b2BlockAllocator* allocator); - - b2Joint(const b2JointDef* def); - virtual ~b2Joint() {} - - virtual void InitVelocityConstraints(const b2SolverData& data) = 0; - virtual void SolveVelocityConstraints(const b2SolverData& data) = 0; - - // This returns true if the position errors are within tolerance. - virtual bool SolvePositionConstraints(const b2SolverData& data) = 0; - - b2JointType m_type; - b2Joint* m_prev; - b2Joint* m_next; - b2JointEdge m_edgeA; - b2JointEdge m_edgeB; - b2Body* m_bodyA; - b2Body* m_bodyB; - - int32 m_index; - - bool m_islandFlag; - bool m_collideConnected; - - void* m_userData; -}; - -inline b2JointType b2Joint::GetType() const -{ - return m_type; -} - -inline b2Body* b2Joint::GetBodyA() -{ - return m_bodyA; -} - -inline b2Body* b2Joint::GetBodyB() -{ - return m_bodyB; -} - -inline b2Joint* b2Joint::GetNext() -{ - return m_next; -} - -inline const b2Joint* b2Joint::GetNext() const -{ - return m_next; -} - -inline void* b2Joint::GetUserData() const -{ - return m_userData; -} - -inline void b2Joint::SetUserData(void* data) -{ - m_userData = data; -} - -inline bool b2Joint::GetCollideConnected() const -{ - return m_collideConnected; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MotorJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MotorJoint.cpp deleted file mode 100644 index 7906845..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MotorJoint.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* -* Copyright (c) 2006-2012 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2MotorJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Point-to-point constraint -// Cdot = v2 - v1 -// = v2 + cross(w2, r2) - v1 - cross(w1, r1) -// J = [-I -r1_skew I r2_skew ] -// Identity used: -// w k % (rx i + ry j) = w * (-ry i + rx j) -// -// r1 = offset - c1 -// r2 = -c2 - -// Angle constraint -// Cdot = w2 - w1 -// J = [0 0 -1 0 0 1] -// K = invI1 + invI2 - -void b2MotorJointDef::Initialize(b2Body* bA, b2Body* bB) -{ - bodyA = bA; - bodyB = bB; - b2Vec2 xB = bodyB->GetPosition(); - linearOffset = bodyA->GetLocalPoint(xB); - - float32 angleA = bodyA->GetAngle(); - float32 angleB = bodyB->GetAngle(); - angularOffset = angleB - angleA; -} - -b2MotorJoint::b2MotorJoint(const b2MotorJointDef* def) -: b2Joint(def) -{ - m_linearOffset = def->linearOffset; - m_angularOffset = def->angularOffset; - - m_linearImpulse.SetZero(); - m_angularImpulse = 0.0f; - - m_maxForce = def->maxForce; - m_maxTorque = def->maxTorque; - m_correctionFactor = def->correctionFactor; -} - -void b2MotorJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - // Compute the effective mass matrix. - m_rA = b2Mul(qA, m_linearOffset - m_localCenterA); - m_rB = b2Mul(qB, -m_localCenterB); - - // J = [-I -r1_skew I r2_skew] - // r_skew = [-ry; rx] - - // Matlab - // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] - // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] - // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] - - - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - // Upper 2 by 2 of K for point to point - b2Mat22 K; - K.ex.x = mA + mB + iA * m_rA.y * m_rA.y + iB * m_rB.y * m_rB.y; - K.ex.y = -iA * m_rA.x * m_rA.y - iB * m_rB.x * m_rB.y; - K.ey.x = K.ex.y; - K.ey.y = mA + mB + iA * m_rA.x * m_rA.x + iB * m_rB.x * m_rB.x; - - m_linearMass = K.GetInverse(); - - m_angularMass = iA + iB; - if (m_angularMass > 0.0f) - { - m_angularMass = 1.0f / m_angularMass; - } - - m_linearError = cB + m_rB - cA - m_rA; - m_angularError = aB - aA - m_angularOffset; - - if (data.step.warmStarting) - { - // Scale impulses to support a variable time step. - m_linearImpulse *= data.step.dtRatio; - m_angularImpulse *= data.step.dtRatio; - - b2Vec2 P(m_linearImpulse.x, m_linearImpulse.y); - vA -= mA * P; - wA -= iA * (b2Cross(m_rA, P) + m_angularImpulse); - vB += mB * P; - wB += iB * (b2Cross(m_rB, P) + m_angularImpulse); - } - else - { - m_linearImpulse.SetZero(); - m_angularImpulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2MotorJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - float32 h = data.step.dt; - float32 inv_h = data.step.inv_dt; - - // Solve angular friction - { - float32 Cdot = wB - wA + inv_h * m_correctionFactor * m_angularError; - float32 impulse = -m_angularMass * Cdot; - - float32 oldImpulse = m_angularImpulse; - float32 maxImpulse = h * m_maxTorque; - m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse); - impulse = m_angularImpulse - oldImpulse; - - wA -= iA * impulse; - wB += iB * impulse; - } - - // Solve linear friction - { - b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA) + inv_h * m_correctionFactor * m_linearError; - - b2Vec2 impulse = -b2Mul(m_linearMass, Cdot); - b2Vec2 oldImpulse = m_linearImpulse; - m_linearImpulse += impulse; - - float32 maxImpulse = h * m_maxForce; - - if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) - { - m_linearImpulse.Normalize(); - m_linearImpulse *= maxImpulse; - } - - impulse = m_linearImpulse - oldImpulse; - - vA -= mA * impulse; - wA -= iA * b2Cross(m_rA, impulse); - - vB += mB * impulse; - wB += iB * b2Cross(m_rB, impulse); - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2MotorJoint::SolvePositionConstraints(const b2SolverData& data) -{ - B2_NOT_USED(data); - - return true; -} - -b2Vec2 b2MotorJoint::GetAnchorA() const -{ - return m_bodyA->GetPosition(); -} - -b2Vec2 b2MotorJoint::GetAnchorB() const -{ - return m_bodyB->GetPosition(); -} - -b2Vec2 b2MotorJoint::GetReactionForce(float32 inv_dt) const -{ - return inv_dt * m_linearImpulse; -} - -float32 b2MotorJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * m_angularImpulse; -} - -void b2MotorJoint::SetMaxForce(float32 force) -{ - b2Assert(b2IsValid(force) && force >= 0.0f); - m_maxForce = force; -} - -float32 b2MotorJoint::GetMaxForce() const -{ - return m_maxForce; -} - -void b2MotorJoint::SetMaxTorque(float32 torque) -{ - b2Assert(b2IsValid(torque) && torque >= 0.0f); - m_maxTorque = torque; -} - -float32 b2MotorJoint::GetMaxTorque() const -{ - return m_maxTorque; -} - -void b2MotorJoint::SetCorrectionFactor(float32 factor) -{ - b2Assert(b2IsValid(factor) && 0.0f <= factor && factor <= 1.0f); - m_correctionFactor = factor; -} - -float32 b2MotorJoint::GetCorrectionFactor() const -{ - return m_correctionFactor; -} - -void b2MotorJoint::SetLinearOffset(const b2Vec2& linearOffset) -{ - if (linearOffset.x != m_linearOffset.x || linearOffset.y != m_linearOffset.y) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_linearOffset = linearOffset; - } -} - -const b2Vec2& b2MotorJoint::GetLinearOffset() const -{ - return m_linearOffset; -} - -void b2MotorJoint::SetAngularOffset(float32 angularOffset) -{ - if (angularOffset != m_angularOffset) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_angularOffset = angularOffset; - } -} - -float32 b2MotorJoint::GetAngularOffset() const -{ - return m_angularOffset; -} - -void b2MotorJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2MotorJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.linearOffset.Set(%.15lef, %.15lef);\n", m_linearOffset.x, m_linearOffset.y); - b2Log(" jd.angularOffset = %.15lef;\n", m_angularOffset); - b2Log(" jd.maxForce = %.15lef;\n", m_maxForce); - b2Log(" jd.maxTorque = %.15lef;\n", m_maxTorque); - b2Log(" jd.correctionFactor = %.15lef;\n", m_correctionFactor); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MotorJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MotorJoint.h deleted file mode 100644 index f384f41..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MotorJoint.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -* Copyright (c) 2006-2012 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_MOTOR_JOINT_H -#define B2_MOTOR_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Motor joint definition. -struct b2MotorJointDef : public b2JointDef -{ - b2MotorJointDef() - { - type = e_motorJoint; - linearOffset.SetZero(); - angularOffset = 0.0f; - maxForce = 1.0f; - maxTorque = 1.0f; - correctionFactor = 0.3f; - } - - /// Initialize the bodies and offsets using the current transforms. - void Initialize(b2Body* bodyA, b2Body* bodyB); - - /// Position of bodyB minus the position of bodyA, in bodyA's frame, in meters. - b2Vec2 linearOffset; - - /// The bodyB angle minus bodyA angle in radians. - float32 angularOffset; - - /// The maximum motor force in N. - float32 maxForce; - - /// The maximum motor torque in N-m. - float32 maxTorque; - - /// Position correction factor in the range [0,1]. - float32 correctionFactor; -}; - -/// A motor joint is used to control the relative motion -/// between two bodies. A typical usage is to control the movement -/// of a dynamic body with respect to the ground. -class b2MotorJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// Set/get the target linear offset, in frame A, in meters. - void SetLinearOffset(const b2Vec2& linearOffset); - const b2Vec2& GetLinearOffset() const; - - /// Set/get the target angular offset, in radians. - void SetAngularOffset(float32 angularOffset); - float32 GetAngularOffset() const; - - /// Set the maximum friction force in N. - void SetMaxForce(float32 force); - - /// Get the maximum friction force in N. - float32 GetMaxForce() const; - - /// Set the maximum friction torque in N*m. - void SetMaxTorque(float32 torque); - - /// Get the maximum friction torque in N*m. - float32 GetMaxTorque() const; - - /// Set the position correction factor in the range [0,1]. - void SetCorrectionFactor(float32 factor); - - /// Get the position correction factor in the range [0,1]. - float32 GetCorrectionFactor() const; - - /// Dump to b2Log - void Dump() override; - -protected: - - friend class b2Joint; - - b2MotorJoint(const b2MotorJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - // Solver shared - b2Vec2 m_linearOffset; - float32 m_angularOffset; - b2Vec2 m_linearImpulse; - float32 m_angularImpulse; - float32 m_maxForce; - float32 m_maxTorque; - float32 m_correctionFactor; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - b2Vec2 m_linearError; - float32 m_angularError; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - b2Mat22 m_linearMass; - float32 m_angularMass; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MouseJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MouseJoint.cpp deleted file mode 100644 index 637e4cd..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MouseJoint.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2MouseJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// p = attached point, m = mouse point -// C = p - m -// Cdot = v -// = v + cross(w, r) -// J = [I r_skew] -// Identity used: -// w k % (rx i + ry j) = w * (-ry i + rx j) - -b2MouseJoint::b2MouseJoint(const b2MouseJointDef* def) -: b2Joint(def) -{ - b2Assert(def->target.IsValid()); - b2Assert(b2IsValid(def->maxForce) && def->maxForce >= 0.0f); - b2Assert(b2IsValid(def->frequencyHz) && def->frequencyHz >= 0.0f); - b2Assert(b2IsValid(def->dampingRatio) && def->dampingRatio >= 0.0f); - - m_targetA = def->target; - m_localAnchorB = b2MulT(m_bodyB->GetTransform(), m_targetA); - - m_maxForce = def->maxForce; - m_impulse.SetZero(); - - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; - - m_beta = 0.0f; - m_gamma = 0.0f; -} - -void b2MouseJoint::SetTarget(const b2Vec2& target) -{ - if (target != m_targetA) - { - m_bodyB->SetAwake(true); - m_targetA = target; - } -} - -const b2Vec2& b2MouseJoint::GetTarget() const -{ - return m_targetA; -} - -void b2MouseJoint::SetMaxForce(float32 force) -{ - m_maxForce = force; -} - -float32 b2MouseJoint::GetMaxForce() const -{ - return m_maxForce; -} - -void b2MouseJoint::SetFrequency(float32 hz) -{ - m_frequencyHz = hz; -} - -float32 b2MouseJoint::GetFrequency() const -{ - return m_frequencyHz; -} - -void b2MouseJoint::SetDampingRatio(float32 ratio) -{ - m_dampingRatio = ratio; -} - -float32 b2MouseJoint::GetDampingRatio() const -{ - return m_dampingRatio; -} - -void b2MouseJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexB = m_bodyB->m_islandIndex; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassB = m_bodyB->m_invMass; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qB(aB); - - float32 mass = m_bodyB->GetMass(); - - // Frequency - float32 omega = 2.0f * b2_pi * m_frequencyHz; - - // Damping coefficient - float32 d = 2.0f * mass * m_dampingRatio * omega; - - // Spring stiffness - float32 k = mass * (omega * omega); - - // magic formulas - // gamma has units of inverse mass. - // beta has units of inverse time. - float32 h = data.step.dt; - b2Assert(d + h * k > b2_epsilon); - m_gamma = h * (d + h * k); - if (m_gamma != 0.0f) - { - m_gamma = 1.0f / m_gamma; - } - m_beta = h * k * m_gamma; - - // Compute the effective mass matrix. - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - // K = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)] - // = [1/m1+1/m2 0 ] + invI1 * [r1.y*r1.y -r1.x*r1.y] + invI2 * [r1.y*r1.y -r1.x*r1.y] - // [ 0 1/m1+1/m2] [-r1.x*r1.y r1.x*r1.x] [-r1.x*r1.y r1.x*r1.x] - b2Mat22 K; - K.ex.x = m_invMassB + m_invIB * m_rB.y * m_rB.y + m_gamma; - K.ex.y = -m_invIB * m_rB.x * m_rB.y; - K.ey.x = K.ex.y; - K.ey.y = m_invMassB + m_invIB * m_rB.x * m_rB.x + m_gamma; - - m_mass = K.GetInverse(); - - m_C = cB + m_rB - m_targetA; - m_C *= m_beta; - - // Cheat with some damping - wB *= 0.98f; - - if (data.step.warmStarting) - { - m_impulse *= data.step.dtRatio; - vB += m_invMassB * m_impulse; - wB += m_invIB * b2Cross(m_rB, m_impulse); - } - else - { - m_impulse.SetZero(); - } - - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2MouseJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - // Cdot = v + cross(w, r) - b2Vec2 Cdot = vB + b2Cross(wB, m_rB); - b2Vec2 impulse = b2Mul(m_mass, -(Cdot + m_C + m_gamma * m_impulse)); - - b2Vec2 oldImpulse = m_impulse; - m_impulse += impulse; - float32 maxImpulse = data.step.dt * m_maxForce; - if (m_impulse.LengthSquared() > maxImpulse * maxImpulse) - { - m_impulse *= maxImpulse / m_impulse.Length(); - } - impulse = m_impulse - oldImpulse; - - vB += m_invMassB * impulse; - wB += m_invIB * b2Cross(m_rB, impulse); - - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2MouseJoint::SolvePositionConstraints(const b2SolverData& data) -{ - B2_NOT_USED(data); - return true; -} - -b2Vec2 b2MouseJoint::GetAnchorA() const -{ - return m_targetA; -} - -b2Vec2 b2MouseJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2MouseJoint::GetReactionForce(float32 inv_dt) const -{ - return inv_dt * m_impulse; -} - -float32 b2MouseJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * 0.0f; -} - -void b2MouseJoint::ShiftOrigin(const b2Vec2& newOrigin) -{ - m_targetA -= newOrigin; -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MouseJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MouseJoint.h deleted file mode 100644 index 7441978..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2MouseJoint.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_MOUSE_JOINT_H -#define B2_MOUSE_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Mouse joint definition. This requires a world target point, -/// tuning parameters, and the time step. -struct b2MouseJointDef : public b2JointDef -{ - b2MouseJointDef() - { - type = e_mouseJoint; - target.Set(0.0f, 0.0f); - maxForce = 0.0f; - frequencyHz = 5.0f; - dampingRatio = 0.7f; - } - - /// The initial world target point. This is assumed - /// to coincide with the body anchor initially. - b2Vec2 target; - - /// The maximum constraint force that can be exerted - /// to move the candidate body. Usually you will express - /// as some multiple of the weight (multiplier * mass * gravity). - float32 maxForce; - - /// The response speed. - float32 frequencyHz; - - /// The damping ratio. 0 = no damping, 1 = critical damping. - float32 dampingRatio; -}; - -/// A mouse joint is used to make a point on a body track a -/// specified world point. This a soft constraint with a maximum -/// force. This allows the constraint to stretch and without -/// applying huge forces. -/// NOTE: this joint is not documented in the manual because it was -/// developed to be used in the testbed. If you want to learn how to -/// use the mouse joint, look at the testbed. -class b2MouseJoint : public b2Joint -{ -public: - - /// Implements b2Joint. - b2Vec2 GetAnchorA() const override; - - /// Implements b2Joint. - b2Vec2 GetAnchorB() const override; - - /// Implements b2Joint. - b2Vec2 GetReactionForce(float32 inv_dt) const override; - - /// Implements b2Joint. - float32 GetReactionTorque(float32 inv_dt) const override; - - /// Use this to update the target point. - void SetTarget(const b2Vec2& target); - const b2Vec2& GetTarget() const; - - /// Set/get the maximum force in Newtons. - void SetMaxForce(float32 force); - float32 GetMaxForce() const; - - /// Set/get the frequency in Hertz. - void SetFrequency(float32 hz); - float32 GetFrequency() const; - - /// Set/get the damping ratio (dimensionless). - void SetDampingRatio(float32 ratio); - float32 GetDampingRatio() const; - - /// The mouse joint does not support dumping. - void Dump() override { b2Log("Mouse joint dumping is not supported.\n"); } - - /// Implement b2Joint::ShiftOrigin - void ShiftOrigin(const b2Vec2& newOrigin) override; - -protected: - friend class b2Joint; - - b2MouseJoint(const b2MouseJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - b2Vec2 m_localAnchorB; - b2Vec2 m_targetA; - float32 m_frequencyHz; - float32 m_dampingRatio; - float32 m_beta; - - // Solver shared - b2Vec2 m_impulse; - float32 m_maxForce; - float32 m_gamma; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_rB; - b2Vec2 m_localCenterB; - float32 m_invMassB; - float32 m_invIB; - b2Mat22 m_mass; - b2Vec2 m_C; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp deleted file mode 100644 index 5da19b6..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +++ /dev/null @@ -1,642 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Linear constraint (point-to-line) -// d = p2 - p1 = x2 + r2 - x1 - r1 -// C = dot(perp, d) -// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1)) -// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2) -// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)] -// -// Angular constraint -// C = a2 - a1 + a_initial -// Cdot = w2 - w1 -// J = [0 0 -1 0 0 1] -// -// K = J * invM * JT -// -// J = [-a -s1 a s2] -// [0 -1 0 1] -// a = perp -// s1 = cross(d + r1, a) = cross(p2 - x1, a) -// s2 = cross(r2, a) = cross(p2 - x2, a) - - -// Motor/Limit linear constraint -// C = dot(ax1, d) -// Cdot = = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2) -// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)] - -// Block Solver -// We develop a block solver that includes the joint limit. This makes the limit stiff (inelastic) even -// when the mass has poor distribution (leading to large torques about the joint anchor points). -// -// The Jacobian has 3 rows: -// J = [-uT -s1 uT s2] // linear -// [0 -1 0 1] // angular -// [-vT -a1 vT a2] // limit -// -// u = perp -// v = axis -// s1 = cross(d + r1, u), s2 = cross(r2, u) -// a1 = cross(d + r1, v), a2 = cross(r2, v) - -// M * (v2 - v1) = JT * df -// J * v2 = bias -// -// v2 = v1 + invM * JT * df -// J * (v1 + invM * JT * df) = bias -// K * df = bias - J * v1 = -Cdot -// K = J * invM * JT -// Cdot = J * v1 - bias -// -// Now solve for f2. -// df = f2 - f1 -// K * (f2 - f1) = -Cdot -// f2 = invK * (-Cdot) + f1 -// -// Clamp accumulated limit impulse. -// lower: f2(3) = max(f2(3), 0) -// upper: f2(3) = min(f2(3), 0) -// -// Solve for correct f2(1:2) -// K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:3) * f1 -// = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:2) * f1(1:2) + K(1:2,3) * f1(3) -// K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3)) + K(1:2,1:2) * f1(1:2) -// f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) + f1(1:2) -// -// Now compute impulse to be applied: -// df = f2 - f1 - -void b2PrismaticJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor, const b2Vec2& axis) -{ - bodyA = bA; - bodyB = bB; - localAnchorA = bodyA->GetLocalPoint(anchor); - localAnchorB = bodyB->GetLocalPoint(anchor); - localAxisA = bodyA->GetLocalVector(axis); - referenceAngle = bodyB->GetAngle() - bodyA->GetAngle(); -} - -b2PrismaticJoint::b2PrismaticJoint(const b2PrismaticJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - m_localXAxisA = def->localAxisA; - m_localXAxisA.Normalize(); - m_localYAxisA = b2Cross(1.0f, m_localXAxisA); - m_referenceAngle = def->referenceAngle; - - m_impulse.SetZero(); - m_motorMass = 0.0f; - m_motorImpulse = 0.0f; - - m_lowerTranslation = def->lowerTranslation; - m_upperTranslation = def->upperTranslation; - m_maxMotorForce = def->maxMotorForce; - m_motorSpeed = def->motorSpeed; - m_enableLimit = def->enableLimit; - m_enableMotor = def->enableMotor; - m_limitState = e_inactiveLimit; - - m_axis.SetZero(); - m_perp.SetZero(); -} - -void b2PrismaticJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - // Compute the effective masses. - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 d = (cB - cA) + rB - rA; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - // Compute motor Jacobian and effective mass. - { - m_axis = b2Mul(qA, m_localXAxisA); - m_a1 = b2Cross(d + rA, m_axis); - m_a2 = b2Cross(rB, m_axis); - - m_motorMass = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2; - if (m_motorMass > 0.0f) - { - m_motorMass = 1.0f / m_motorMass; - } - } - - // Prismatic constraint. - { - m_perp = b2Mul(qA, m_localYAxisA); - - m_s1 = b2Cross(d + rA, m_perp); - m_s2 = b2Cross(rB, m_perp); - - float32 k11 = mA + mB + iA * m_s1 * m_s1 + iB * m_s2 * m_s2; - float32 k12 = iA * m_s1 + iB * m_s2; - float32 k13 = iA * m_s1 * m_a1 + iB * m_s2 * m_a2; - float32 k22 = iA + iB; - if (k22 == 0.0f) - { - // For bodies with fixed rotation. - k22 = 1.0f; - } - float32 k23 = iA * m_a1 + iB * m_a2; - float32 k33 = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2; - - m_K.ex.Set(k11, k12, k13); - m_K.ey.Set(k12, k22, k23); - m_K.ez.Set(k13, k23, k33); - } - - // Compute motor and limit terms. - if (m_enableLimit) - { - float32 jointTranslation = b2Dot(m_axis, d); - if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) - { - m_limitState = e_equalLimits; - } - else if (jointTranslation <= m_lowerTranslation) - { - if (m_limitState != e_atLowerLimit) - { - m_limitState = e_atLowerLimit; - m_impulse.z = 0.0f; - } - } - else if (jointTranslation >= m_upperTranslation) - { - if (m_limitState != e_atUpperLimit) - { - m_limitState = e_atUpperLimit; - m_impulse.z = 0.0f; - } - } - else - { - m_limitState = e_inactiveLimit; - m_impulse.z = 0.0f; - } - } - else - { - m_limitState = e_inactiveLimit; - m_impulse.z = 0.0f; - } - - if (m_enableMotor == false) - { - m_motorImpulse = 0.0f; - } - - if (data.step.warmStarting) - { - // Account for variable time step. - m_impulse *= data.step.dtRatio; - m_motorImpulse *= data.step.dtRatio; - - b2Vec2 P = m_impulse.x * m_perp + (m_motorImpulse + m_impulse.z) * m_axis; - float32 LA = m_impulse.x * m_s1 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a1; - float32 LB = m_impulse.x * m_s2 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a2; - - vA -= mA * P; - wA -= iA * LA; - - vB += mB * P; - wB += iB * LB; - } - else - { - m_impulse.SetZero(); - m_motorImpulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2PrismaticJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - // Solve linear motor constraint. - if (m_enableMotor && m_limitState != e_equalLimits) - { - float32 Cdot = b2Dot(m_axis, vB - vA) + m_a2 * wB - m_a1 * wA; - float32 impulse = m_motorMass * (m_motorSpeed - Cdot); - float32 oldImpulse = m_motorImpulse; - float32 maxImpulse = data.step.dt * m_maxMotorForce; - m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); - impulse = m_motorImpulse - oldImpulse; - - b2Vec2 P = impulse * m_axis; - float32 LA = impulse * m_a1; - float32 LB = impulse * m_a2; - - vA -= mA * P; - wA -= iA * LA; - - vB += mB * P; - wB += iB * LB; - } - - b2Vec2 Cdot1; - Cdot1.x = b2Dot(m_perp, vB - vA) + m_s2 * wB - m_s1 * wA; - Cdot1.y = wB - wA; - - if (m_enableLimit && m_limitState != e_inactiveLimit) - { - // Solve prismatic and limit constraint in block form. - float32 Cdot2; - Cdot2 = b2Dot(m_axis, vB - vA) + m_a2 * wB - m_a1 * wA; - b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); - - b2Vec3 f1 = m_impulse; - b2Vec3 df = m_K.Solve33(-Cdot); - m_impulse += df; - - if (m_limitState == e_atLowerLimit) - { - m_impulse.z = b2Max(m_impulse.z, 0.0f); - } - else if (m_limitState == e_atUpperLimit) - { - m_impulse.z = b2Min(m_impulse.z, 0.0f); - } - - // f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) + f1(1:2) - b2Vec2 b = -Cdot1 - (m_impulse.z - f1.z) * b2Vec2(m_K.ez.x, m_K.ez.y); - b2Vec2 f2r = m_K.Solve22(b) + b2Vec2(f1.x, f1.y); - m_impulse.x = f2r.x; - m_impulse.y = f2r.y; - - df = m_impulse - f1; - - b2Vec2 P = df.x * m_perp + df.z * m_axis; - float32 LA = df.x * m_s1 + df.y + df.z * m_a1; - float32 LB = df.x * m_s2 + df.y + df.z * m_a2; - - vA -= mA * P; - wA -= iA * LA; - - vB += mB * P; - wB += iB * LB; - } - else - { - // Limit is inactive, just solve the prismatic constraint in block form. - b2Vec2 df = m_K.Solve22(-Cdot1); - m_impulse.x += df.x; - m_impulse.y += df.y; - - b2Vec2 P = df.x * m_perp; - float32 LA = df.x * m_s1 + df.y; - float32 LB = df.x * m_s2 + df.y; - - vA -= mA * P; - wA -= iA * LA; - - vB += mB * P; - wB += iB * LB; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -// A velocity based solver computes reaction forces(impulses) using the velocity constraint solver.Under this context, -// the position solver is not there to resolve forces.It is only there to cope with integration error. -// -// Therefore, the pseudo impulses in the position solver do not have any physical meaning.Thus it is okay if they suck. -// -// We could take the active state from the velocity solver.However, the joint might push past the limit when the velocity -// solver indicates the limit is inactive. -bool b2PrismaticJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - // Compute fresh Jacobians - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 d = cB + rB - cA - rA; - - b2Vec2 axis = b2Mul(qA, m_localXAxisA); - float32 a1 = b2Cross(d + rA, axis); - float32 a2 = b2Cross(rB, axis); - b2Vec2 perp = b2Mul(qA, m_localYAxisA); - - float32 s1 = b2Cross(d + rA, perp); - float32 s2 = b2Cross(rB, perp); - - b2Vec3 impulse; - b2Vec2 C1; - C1.x = b2Dot(perp, d); - C1.y = aB - aA - m_referenceAngle; - - float32 linearError = b2Abs(C1.x); - float32 angularError = b2Abs(C1.y); - - bool active = false; - float32 C2 = 0.0f; - if (m_enableLimit) - { - float32 translation = b2Dot(axis, d); - if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) - { - // Prevent large angular corrections - C2 = b2Clamp(translation, -b2_maxLinearCorrection, b2_maxLinearCorrection); - linearError = b2Max(linearError, b2Abs(translation)); - active = true; - } - else if (translation <= m_lowerTranslation) - { - // Prevent large linear corrections and allow some slop. - C2 = b2Clamp(translation - m_lowerTranslation + b2_linearSlop, -b2_maxLinearCorrection, 0.0f); - linearError = b2Max(linearError, m_lowerTranslation - translation); - active = true; - } - else if (translation >= m_upperTranslation) - { - // Prevent large linear corrections and allow some slop. - C2 = b2Clamp(translation - m_upperTranslation - b2_linearSlop, 0.0f, b2_maxLinearCorrection); - linearError = b2Max(linearError, translation - m_upperTranslation); - active = true; - } - } - - if (active) - { - float32 k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; - float32 k12 = iA * s1 + iB * s2; - float32 k13 = iA * s1 * a1 + iB * s2 * a2; - float32 k22 = iA + iB; - if (k22 == 0.0f) - { - // For fixed rotation - k22 = 1.0f; - } - float32 k23 = iA * a1 + iB * a2; - float32 k33 = mA + mB + iA * a1 * a1 + iB * a2 * a2; - - b2Mat33 K; - K.ex.Set(k11, k12, k13); - K.ey.Set(k12, k22, k23); - K.ez.Set(k13, k23, k33); - - b2Vec3 C; - C.x = C1.x; - C.y = C1.y; - C.z = C2; - - impulse = K.Solve33(-C); - } - else - { - float32 k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; - float32 k12 = iA * s1 + iB * s2; - float32 k22 = iA + iB; - if (k22 == 0.0f) - { - k22 = 1.0f; - } - - b2Mat22 K; - K.ex.Set(k11, k12); - K.ey.Set(k12, k22); - - b2Vec2 impulse1 = K.Solve(-C1); - impulse.x = impulse1.x; - impulse.y = impulse1.y; - impulse.z = 0.0f; - } - - b2Vec2 P = impulse.x * perp + impulse.z * axis; - float32 LA = impulse.x * s1 + impulse.y + impulse.z * a1; - float32 LB = impulse.x * s2 + impulse.y + impulse.z * a2; - - cA -= mA * P; - aA -= iA * LA; - cB += mB * P; - aB += iB * LB; - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return linearError <= b2_linearSlop && angularError <= b2_angularSlop; -} - -b2Vec2 b2PrismaticJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2PrismaticJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2PrismaticJoint::GetReactionForce(float32 inv_dt) const -{ - return inv_dt * (m_impulse.x * m_perp + (m_motorImpulse + m_impulse.z) * m_axis); -} - -float32 b2PrismaticJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * m_impulse.y; -} - -float32 b2PrismaticJoint::GetJointTranslation() const -{ - b2Vec2 pA = m_bodyA->GetWorldPoint(m_localAnchorA); - b2Vec2 pB = m_bodyB->GetWorldPoint(m_localAnchorB); - b2Vec2 d = pB - pA; - b2Vec2 axis = m_bodyA->GetWorldVector(m_localXAxisA); - - float32 translation = b2Dot(d, axis); - return translation; -} - -float32 b2PrismaticJoint::GetJointSpeed() const -{ - b2Body* bA = m_bodyA; - b2Body* bB = m_bodyB; - - b2Vec2 rA = b2Mul(bA->m_xf.q, m_localAnchorA - bA->m_sweep.localCenter); - b2Vec2 rB = b2Mul(bB->m_xf.q, m_localAnchorB - bB->m_sweep.localCenter); - b2Vec2 p1 = bA->m_sweep.c + rA; - b2Vec2 p2 = bB->m_sweep.c + rB; - b2Vec2 d = p2 - p1; - b2Vec2 axis = b2Mul(bA->m_xf.q, m_localXAxisA); - - b2Vec2 vA = bA->m_linearVelocity; - b2Vec2 vB = bB->m_linearVelocity; - float32 wA = bA->m_angularVelocity; - float32 wB = bB->m_angularVelocity; - - float32 speed = b2Dot(d, b2Cross(wA, axis)) + b2Dot(axis, vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA)); - return speed; -} - -bool b2PrismaticJoint::IsLimitEnabled() const -{ - return m_enableLimit; -} - -void b2PrismaticJoint::EnableLimit(bool flag) -{ - if (flag != m_enableLimit) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableLimit = flag; - m_impulse.z = 0.0f; - } -} - -float32 b2PrismaticJoint::GetLowerLimit() const -{ - return m_lowerTranslation; -} - -float32 b2PrismaticJoint::GetUpperLimit() const -{ - return m_upperTranslation; -} - -void b2PrismaticJoint::SetLimits(float32 lower, float32 upper) -{ - b2Assert(lower <= upper); - if (lower != m_lowerTranslation || upper != m_upperTranslation) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_lowerTranslation = lower; - m_upperTranslation = upper; - m_impulse.z = 0.0f; - } -} - -bool b2PrismaticJoint::IsMotorEnabled() const -{ - return m_enableMotor; -} - -void b2PrismaticJoint::EnableMotor(bool flag) -{ - if (flag != m_enableMotor) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableMotor = flag; - } -} - -void b2PrismaticJoint::SetMotorSpeed(float32 speed) -{ - if (speed != m_motorSpeed) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_motorSpeed = speed; - } -} - -void b2PrismaticJoint::SetMaxMotorForce(float32 force) -{ - if (force != m_maxMotorForce) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_maxMotorForce = force; - } -} - -float32 b2PrismaticJoint::GetMotorForce(float32 inv_dt) const -{ - return inv_dt * m_motorImpulse; -} - -void b2PrismaticJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2PrismaticJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.localAxisA.Set(%.15lef, %.15lef);\n", m_localXAxisA.x, m_localXAxisA.y); - b2Log(" jd.referenceAngle = %.15lef;\n", m_referenceAngle); - b2Log(" jd.enableLimit = bool(%d);\n", m_enableLimit); - b2Log(" jd.lowerTranslation = %.15lef;\n", m_lowerTranslation); - b2Log(" jd.upperTranslation = %.15lef;\n", m_upperTranslation); - b2Log(" jd.enableMotor = bool(%d);\n", m_enableMotor); - b2Log(" jd.motorSpeed = %.15lef;\n", m_motorSpeed); - b2Log(" jd.maxMotorForce = %.15lef;\n", m_maxMotorForce); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PrismaticJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PrismaticJoint.h deleted file mode 100644 index 131dffd..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PrismaticJoint.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_PRISMATIC_JOINT_H -#define B2_PRISMATIC_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Prismatic joint definition. This requires defining a line of -/// motion using an axis and an anchor point. The definition uses local -/// anchor points and a local axis so that the initial configuration -/// can violate the constraint slightly. The joint translation is zero -/// when the local anchor points coincide in world space. Using local -/// anchors and a local axis helps when saving and loading a game. -struct b2PrismaticJointDef : public b2JointDef -{ - b2PrismaticJointDef() - { - type = e_prismaticJoint; - localAnchorA.SetZero(); - localAnchorB.SetZero(); - localAxisA.Set(1.0f, 0.0f); - referenceAngle = 0.0f; - enableLimit = false; - lowerTranslation = 0.0f; - upperTranslation = 0.0f; - enableMotor = false; - maxMotorForce = 0.0f; - motorSpeed = 0.0f; - } - - /// Initialize the bodies, anchors, axis, and reference angle using the world - /// anchor and unit world axis. - void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis); - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The local translation unit axis in bodyA. - b2Vec2 localAxisA; - - /// The constrained angle between the bodies: bodyB_angle - bodyA_angle. - float32 referenceAngle; - - /// Enable/disable the joint limit. - bool enableLimit; - - /// The lower translation limit, usually in meters. - float32 lowerTranslation; - - /// The upper translation limit, usually in meters. - float32 upperTranslation; - - /// Enable/disable the joint motor. - bool enableMotor; - - /// The maximum motor torque, usually in N-m. - float32 maxMotorForce; - - /// The desired motor speed in radians per second. - float32 motorSpeed; -}; - -/// A prismatic joint. This joint provides one degree of freedom: translation -/// along an axis fixed in bodyA. Relative rotation is prevented. You can -/// use a joint limit to restrict the range of motion and a joint motor to -/// drive the motion or to model joint friction. -class b2PrismaticJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// The local joint axis relative to bodyA. - const b2Vec2& GetLocalAxisA() const { return m_localXAxisA; } - - /// Get the reference angle. - float32 GetReferenceAngle() const { return m_referenceAngle; } - - /// Get the current joint translation, usually in meters. - float32 GetJointTranslation() const; - - /// Get the current joint translation speed, usually in meters per second. - float32 GetJointSpeed() const; - - /// Is the joint limit enabled? - bool IsLimitEnabled() const; - - /// Enable/disable the joint limit. - void EnableLimit(bool flag); - - /// Get the lower joint limit, usually in meters. - float32 GetLowerLimit() const; - - /// Get the upper joint limit, usually in meters. - float32 GetUpperLimit() const; - - /// Set the joint limits, usually in meters. - void SetLimits(float32 lower, float32 upper); - - /// Is the joint motor enabled? - bool IsMotorEnabled() const; - - /// Enable/disable the joint motor. - void EnableMotor(bool flag); - - /// Set the motor speed, usually in meters per second. - void SetMotorSpeed(float32 speed); - - /// Get the motor speed, usually in meters per second. - float32 GetMotorSpeed() const; - - /// Set the maximum motor force, usually in N. - void SetMaxMotorForce(float32 force); - float32 GetMaxMotorForce() const { return m_maxMotorForce; } - - /// Get the current motor force given the inverse time step, usually in N. - float32 GetMotorForce(float32 inv_dt) const; - - /// Dump to b2Log - void Dump() override; - -protected: - friend class b2Joint; - friend class b2GearJoint; - b2PrismaticJoint(const b2PrismaticJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - b2Vec2 m_localXAxisA; - b2Vec2 m_localYAxisA; - float32 m_referenceAngle; - b2Vec3 m_impulse; - float32 m_motorImpulse; - float32 m_lowerTranslation; - float32 m_upperTranslation; - float32 m_maxMotorForce; - float32 m_motorSpeed; - bool m_enableLimit; - bool m_enableMotor; - b2LimitState m_limitState; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - b2Vec2 m_axis, m_perp; - float32 m_s1, m_s2; - float32 m_a1, m_a2; - b2Mat33 m_K; - float32 m_motorMass; -}; - -inline float32 b2PrismaticJoint::GetMotorSpeed() const -{ - return m_motorSpeed; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PulleyJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PulleyJoint.cpp deleted file mode 100644 index 1525f41..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* -* Copyright (c) 2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Pulley: -// length1 = norm(p1 - s1) -// length2 = norm(p2 - s2) -// C0 = (length1 + ratio * length2)_initial -// C = C0 - (length1 + ratio * length2) -// u1 = (p1 - s1) / norm(p1 - s1) -// u2 = (p2 - s2) / norm(p2 - s2) -// Cdot = -dot(u1, v1 + cross(w1, r1)) - ratio * dot(u2, v2 + cross(w2, r2)) -// J = -[u1 cross(r1, u1) ratio * u2 ratio * cross(r2, u2)] -// K = J * invM * JT -// = invMass1 + invI1 * cross(r1, u1)^2 + ratio^2 * (invMass2 + invI2 * cross(r2, u2)^2) - -void b2PulleyJointDef::Initialize(b2Body* bA, b2Body* bB, - const b2Vec2& groundA, const b2Vec2& groundB, - const b2Vec2& anchorA, const b2Vec2& anchorB, - float32 r) -{ - bodyA = bA; - bodyB = bB; - groundAnchorA = groundA; - groundAnchorB = groundB; - localAnchorA = bodyA->GetLocalPoint(anchorA); - localAnchorB = bodyB->GetLocalPoint(anchorB); - b2Vec2 dA = anchorA - groundA; - lengthA = dA.Length(); - b2Vec2 dB = anchorB - groundB; - lengthB = dB.Length(); - ratio = r; - b2Assert(ratio > b2_epsilon); -} - -b2PulleyJoint::b2PulleyJoint(const b2PulleyJointDef* def) -: b2Joint(def) -{ - m_groundAnchorA = def->groundAnchorA; - m_groundAnchorB = def->groundAnchorB; - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - - m_lengthA = def->lengthA; - m_lengthB = def->lengthB; - - b2Assert(def->ratio != 0.0f); - m_ratio = def->ratio; - - m_constant = def->lengthA + m_ratio * def->lengthB; - - m_impulse = 0.0f; -} - -void b2PulleyJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - // Get the pulley axes. - m_uA = cA + m_rA - m_groundAnchorA; - m_uB = cB + m_rB - m_groundAnchorB; - - float32 lengthA = m_uA.Length(); - float32 lengthB = m_uB.Length(); - - if (lengthA > 10.0f * b2_linearSlop) - { - m_uA *= 1.0f / lengthA; - } - else - { - m_uA.SetZero(); - } - - if (lengthB > 10.0f * b2_linearSlop) - { - m_uB *= 1.0f / lengthB; - } - else - { - m_uB.SetZero(); - } - - // Compute effective mass. - float32 ruA = b2Cross(m_rA, m_uA); - float32 ruB = b2Cross(m_rB, m_uB); - - float32 mA = m_invMassA + m_invIA * ruA * ruA; - float32 mB = m_invMassB + m_invIB * ruB * ruB; - - m_mass = mA + m_ratio * m_ratio * mB; - - if (m_mass > 0.0f) - { - m_mass = 1.0f / m_mass; - } - - if (data.step.warmStarting) - { - // Scale impulses to support variable time steps. - m_impulse *= data.step.dtRatio; - - // Warm starting. - b2Vec2 PA = -(m_impulse) * m_uA; - b2Vec2 PB = (-m_ratio * m_impulse) * m_uB; - - vA += m_invMassA * PA; - wA += m_invIA * b2Cross(m_rA, PA); - vB += m_invMassB * PB; - wB += m_invIB * b2Cross(m_rB, PB); - } - else - { - m_impulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2PulleyJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Vec2 vpA = vA + b2Cross(wA, m_rA); - b2Vec2 vpB = vB + b2Cross(wB, m_rB); - - float32 Cdot = -b2Dot(m_uA, vpA) - m_ratio * b2Dot(m_uB, vpB); - float32 impulse = -m_mass * Cdot; - m_impulse += impulse; - - b2Vec2 PA = -impulse * m_uA; - b2Vec2 PB = -m_ratio * impulse * m_uB; - vA += m_invMassA * PA; - wA += m_invIA * b2Cross(m_rA, PA); - vB += m_invMassB * PB; - wB += m_invIB * b2Cross(m_rB, PB); - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2PulleyJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - // Get the pulley axes. - b2Vec2 uA = cA + rA - m_groundAnchorA; - b2Vec2 uB = cB + rB - m_groundAnchorB; - - float32 lengthA = uA.Length(); - float32 lengthB = uB.Length(); - - if (lengthA > 10.0f * b2_linearSlop) - { - uA *= 1.0f / lengthA; - } - else - { - uA.SetZero(); - } - - if (lengthB > 10.0f * b2_linearSlop) - { - uB *= 1.0f / lengthB; - } - else - { - uB.SetZero(); - } - - // Compute effective mass. - float32 ruA = b2Cross(rA, uA); - float32 ruB = b2Cross(rB, uB); - - float32 mA = m_invMassA + m_invIA * ruA * ruA; - float32 mB = m_invMassB + m_invIB * ruB * ruB; - - float32 mass = mA + m_ratio * m_ratio * mB; - - if (mass > 0.0f) - { - mass = 1.0f / mass; - } - - float32 C = m_constant - lengthA - m_ratio * lengthB; - float32 linearError = b2Abs(C); - - float32 impulse = -mass * C; - - b2Vec2 PA = -impulse * uA; - b2Vec2 PB = -m_ratio * impulse * uB; - - cA += m_invMassA * PA; - aA += m_invIA * b2Cross(rA, PA); - cB += m_invMassB * PB; - aB += m_invIB * b2Cross(rB, PB); - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return linearError < b2_linearSlop; -} - -b2Vec2 b2PulleyJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2PulleyJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2PulleyJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 P = m_impulse * m_uB; - return inv_dt * P; -} - -float32 b2PulleyJoint::GetReactionTorque(float32 inv_dt) const -{ - B2_NOT_USED(inv_dt); - return 0.0f; -} - -b2Vec2 b2PulleyJoint::GetGroundAnchorA() const -{ - return m_groundAnchorA; -} - -b2Vec2 b2PulleyJoint::GetGroundAnchorB() const -{ - return m_groundAnchorB; -} - -float32 b2PulleyJoint::GetLengthA() const -{ - return m_lengthA; -} - -float32 b2PulleyJoint::GetLengthB() const -{ - return m_lengthB; -} - -float32 b2PulleyJoint::GetRatio() const -{ - return m_ratio; -} - -float32 b2PulleyJoint::GetCurrentLengthA() const -{ - b2Vec2 p = m_bodyA->GetWorldPoint(m_localAnchorA); - b2Vec2 s = m_groundAnchorA; - b2Vec2 d = p - s; - return d.Length(); -} - -float32 b2PulleyJoint::GetCurrentLengthB() const -{ - b2Vec2 p = m_bodyB->GetWorldPoint(m_localAnchorB); - b2Vec2 s = m_groundAnchorB; - b2Vec2 d = p - s; - return d.Length(); -} - -void b2PulleyJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2PulleyJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.groundAnchorA.Set(%.15lef, %.15lef);\n", m_groundAnchorA.x, m_groundAnchorA.y); - b2Log(" jd.groundAnchorB.Set(%.15lef, %.15lef);\n", m_groundAnchorB.x, m_groundAnchorB.y); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.lengthA = %.15lef;\n", m_lengthA); - b2Log(" jd.lengthB = %.15lef;\n", m_lengthB); - b2Log(" jd.ratio = %.15lef;\n", m_ratio); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} - -void b2PulleyJoint::ShiftOrigin(const b2Vec2& newOrigin) -{ - m_groundAnchorA -= newOrigin; - m_groundAnchorB -= newOrigin; -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PulleyJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PulleyJoint.h deleted file mode 100644 index 71c759b..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2PulleyJoint.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_PULLEY_JOINT_H -#define B2_PULLEY_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -const float32 b2_minPulleyLength = 2.0f; - -/// Pulley joint definition. This requires two ground anchors, -/// two dynamic body anchor points, and a pulley ratio. -struct b2PulleyJointDef : public b2JointDef -{ - b2PulleyJointDef() - { - type = e_pulleyJoint; - groundAnchorA.Set(-1.0f, 1.0f); - groundAnchorB.Set(1.0f, 1.0f); - localAnchorA.Set(-1.0f, 0.0f); - localAnchorB.Set(1.0f, 0.0f); - lengthA = 0.0f; - lengthB = 0.0f; - ratio = 1.0f; - collideConnected = true; - } - - /// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors. - void Initialize(b2Body* bodyA, b2Body* bodyB, - const b2Vec2& groundAnchorA, const b2Vec2& groundAnchorB, - const b2Vec2& anchorA, const b2Vec2& anchorB, - float32 ratio); - - /// The first ground anchor in world coordinates. This point never moves. - b2Vec2 groundAnchorA; - - /// The second ground anchor in world coordinates. This point never moves. - b2Vec2 groundAnchorB; - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The a reference length for the segment attached to bodyA. - float32 lengthA; - - /// The a reference length for the segment attached to bodyB. - float32 lengthB; - - /// The pulley ratio, used to simulate a block-and-tackle. - float32 ratio; -}; - -/// The pulley joint is connected to two bodies and two fixed ground points. -/// The pulley supports a ratio such that: -/// length1 + ratio * length2 <= constant -/// Yes, the force transmitted is scaled by the ratio. -/// Warning: the pulley joint can get a bit squirrelly by itself. They often -/// work better when combined with prismatic joints. You should also cover the -/// the anchor points with static shapes to prevent one side from going to -/// zero length. -class b2PulleyJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// Get the first ground anchor. - b2Vec2 GetGroundAnchorA() const; - - /// Get the second ground anchor. - b2Vec2 GetGroundAnchorB() const; - - /// Get the current length of the segment attached to bodyA. - float32 GetLengthA() const; - - /// Get the current length of the segment attached to bodyB. - float32 GetLengthB() const; - - /// Get the pulley ratio. - float32 GetRatio() const; - - /// Get the current length of the segment attached to bodyA. - float32 GetCurrentLengthA() const; - - /// Get the current length of the segment attached to bodyB. - float32 GetCurrentLengthB() const; - - /// Dump joint to dmLog - void Dump() override; - - /// Implement b2Joint::ShiftOrigin - void ShiftOrigin(const b2Vec2& newOrigin) override; - -protected: - - friend class b2Joint; - b2PulleyJoint(const b2PulleyJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - b2Vec2 m_groundAnchorA; - b2Vec2 m_groundAnchorB; - float32 m_lengthA; - float32 m_lengthB; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - float32 m_constant; - float32 m_ratio; - float32 m_impulse; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_uA; - b2Vec2 m_uB; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - float32 m_mass; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp deleted file mode 100644 index b3f7ee5..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Point-to-point constraint -// C = p2 - p1 -// Cdot = v2 - v1 -// = v2 + cross(w2, r2) - v1 - cross(w1, r1) -// J = [-I -r1_skew I r2_skew ] -// Identity used: -// w k % (rx i + ry j) = w * (-ry i + rx j) - -// Motor constraint -// Cdot = w2 - w1 -// J = [0 0 -1 0 0 1] -// K = invI1 + invI2 - -void b2RevoluteJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor) -{ - bodyA = bA; - bodyB = bB; - localAnchorA = bodyA->GetLocalPoint(anchor); - localAnchorB = bodyB->GetLocalPoint(anchor); - referenceAngle = bodyB->GetAngle() - bodyA->GetAngle(); -} - -b2RevoluteJoint::b2RevoluteJoint(const b2RevoluteJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - m_referenceAngle = def->referenceAngle; - - m_impulse.SetZero(); - m_motorImpulse = 0.0f; - - m_lowerAngle = def->lowerAngle; - m_upperAngle = def->upperAngle; - m_maxMotorTorque = def->maxMotorTorque; - m_motorSpeed = def->motorSpeed; - m_enableLimit = def->enableLimit; - m_enableMotor = def->enableMotor; - m_limitState = e_inactiveLimit; -} - -void b2RevoluteJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - // J = [-I -r1_skew I r2_skew] - // [ 0 -1 0 1] - // r_skew = [-ry; rx] - - // Matlab - // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] - // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] - // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - bool fixedRotation = (iA + iB == 0.0f); - - m_mass.ex.x = mA + mB + m_rA.y * m_rA.y * iA + m_rB.y * m_rB.y * iB; - m_mass.ey.x = -m_rA.y * m_rA.x * iA - m_rB.y * m_rB.x * iB; - m_mass.ez.x = -m_rA.y * iA - m_rB.y * iB; - m_mass.ex.y = m_mass.ey.x; - m_mass.ey.y = mA + mB + m_rA.x * m_rA.x * iA + m_rB.x * m_rB.x * iB; - m_mass.ez.y = m_rA.x * iA + m_rB.x * iB; - m_mass.ex.z = m_mass.ez.x; - m_mass.ey.z = m_mass.ez.y; - m_mass.ez.z = iA + iB; - - m_motorMass = iA + iB; - if (m_motorMass > 0.0f) - { - m_motorMass = 1.0f / m_motorMass; - } - - if (m_enableMotor == false || fixedRotation) - { - m_motorImpulse = 0.0f; - } - - if (m_enableLimit && fixedRotation == false) - { - float32 jointAngle = aB - aA - m_referenceAngle; - if (b2Abs(m_upperAngle - m_lowerAngle) < 2.0f * b2_angularSlop) - { - m_limitState = e_equalLimits; - } - else if (jointAngle <= m_lowerAngle) - { - if (m_limitState != e_atLowerLimit) - { - m_impulse.z = 0.0f; - } - m_limitState = e_atLowerLimit; - } - else if (jointAngle >= m_upperAngle) - { - if (m_limitState != e_atUpperLimit) - { - m_impulse.z = 0.0f; - } - m_limitState = e_atUpperLimit; - } - else - { - m_limitState = e_inactiveLimit; - m_impulse.z = 0.0f; - } - } - else - { - m_limitState = e_inactiveLimit; - } - - if (data.step.warmStarting) - { - // Scale impulses to support a variable time step. - m_impulse *= data.step.dtRatio; - m_motorImpulse *= data.step.dtRatio; - - b2Vec2 P(m_impulse.x, m_impulse.y); - - vA -= mA * P; - wA -= iA * (b2Cross(m_rA, P) + m_motorImpulse + m_impulse.z); - - vB += mB * P; - wB += iB * (b2Cross(m_rB, P) + m_motorImpulse + m_impulse.z); - } - else - { - m_impulse.SetZero(); - m_motorImpulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2RevoluteJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - bool fixedRotation = (iA + iB == 0.0f); - - // Solve motor constraint. - if (m_enableMotor && m_limitState != e_equalLimits && fixedRotation == false) - { - float32 Cdot = wB - wA - m_motorSpeed; - float32 impulse = -m_motorMass * Cdot; - float32 oldImpulse = m_motorImpulse; - float32 maxImpulse = data.step.dt * m_maxMotorTorque; - m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); - impulse = m_motorImpulse - oldImpulse; - - wA -= iA * impulse; - wB += iB * impulse; - } - - // Solve limit constraint. - if (m_enableLimit && m_limitState != e_inactiveLimit && fixedRotation == false) - { - b2Vec2 Cdot1 = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); - float32 Cdot2 = wB - wA; - b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); - - b2Vec3 impulse = -m_mass.Solve33(Cdot); - - if (m_limitState == e_equalLimits) - { - m_impulse += impulse; - } - else if (m_limitState == e_atLowerLimit) - { - float32 newImpulse = m_impulse.z + impulse.z; - if (newImpulse < 0.0f) - { - b2Vec2 rhs = -Cdot1 + m_impulse.z * b2Vec2(m_mass.ez.x, m_mass.ez.y); - b2Vec2 reduced = m_mass.Solve22(rhs); - impulse.x = reduced.x; - impulse.y = reduced.y; - impulse.z = -m_impulse.z; - m_impulse.x += reduced.x; - m_impulse.y += reduced.y; - m_impulse.z = 0.0f; - } - else - { - m_impulse += impulse; - } - } - else if (m_limitState == e_atUpperLimit) - { - float32 newImpulse = m_impulse.z + impulse.z; - if (newImpulse > 0.0f) - { - b2Vec2 rhs = -Cdot1 + m_impulse.z * b2Vec2(m_mass.ez.x, m_mass.ez.y); - b2Vec2 reduced = m_mass.Solve22(rhs); - impulse.x = reduced.x; - impulse.y = reduced.y; - impulse.z = -m_impulse.z; - m_impulse.x += reduced.x; - m_impulse.y += reduced.y; - m_impulse.z = 0.0f; - } - else - { - m_impulse += impulse; - } - } - - b2Vec2 P(impulse.x, impulse.y); - - vA -= mA * P; - wA -= iA * (b2Cross(m_rA, P) + impulse.z); - - vB += mB * P; - wB += iB * (b2Cross(m_rB, P) + impulse.z); - } - else - { - // Solve point-to-point constraint - b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); - b2Vec2 impulse = m_mass.Solve22(-Cdot); - - m_impulse.x += impulse.x; - m_impulse.y += impulse.y; - - vA -= mA * impulse; - wA -= iA * b2Cross(m_rA, impulse); - - vB += mB * impulse; - wB += iB * b2Cross(m_rB, impulse); - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2RevoluteJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - float32 angularError = 0.0f; - float32 positionError = 0.0f; - - bool fixedRotation = (m_invIA + m_invIB == 0.0f); - - // Solve angular limit constraint. - if (m_enableLimit && m_limitState != e_inactiveLimit && fixedRotation == false) - { - float32 angle = aB - aA - m_referenceAngle; - float32 limitImpulse = 0.0f; - - if (m_limitState == e_equalLimits) - { - // Prevent large angular corrections - float32 C = b2Clamp(angle - m_lowerAngle, -b2_maxAngularCorrection, b2_maxAngularCorrection); - limitImpulse = -m_motorMass * C; - angularError = b2Abs(C); - } - else if (m_limitState == e_atLowerLimit) - { - float32 C = angle - m_lowerAngle; - angularError = -C; - - // Prevent large angular corrections and allow some slop. - C = b2Clamp(C + b2_angularSlop, -b2_maxAngularCorrection, 0.0f); - limitImpulse = -m_motorMass * C; - } - else if (m_limitState == e_atUpperLimit) - { - float32 C = angle - m_upperAngle; - angularError = C; - - // Prevent large angular corrections and allow some slop. - C = b2Clamp(C - b2_angularSlop, 0.0f, b2_maxAngularCorrection); - limitImpulse = -m_motorMass * C; - } - - aA -= m_invIA * limitImpulse; - aB += m_invIB * limitImpulse; - } - - // Solve point-to-point constraint. - { - qA.Set(aA); - qB.Set(aB); - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - b2Vec2 C = cB + rB - cA - rA; - positionError = C.Length(); - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - b2Mat22 K; - K.ex.x = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y; - K.ex.y = -iA * rA.x * rA.y - iB * rB.x * rB.y; - K.ey.x = K.ex.y; - K.ey.y = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x; - - b2Vec2 impulse = -K.Solve(C); - - cA -= mA * impulse; - aA -= iA * b2Cross(rA, impulse); - - cB += mB * impulse; - aB += iB * b2Cross(rB, impulse); - } - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return positionError <= b2_linearSlop && angularError <= b2_angularSlop; -} - -b2Vec2 b2RevoluteJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2RevoluteJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2RevoluteJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 P(m_impulse.x, m_impulse.y); - return inv_dt * P; -} - -float32 b2RevoluteJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * m_impulse.z; -} - -float32 b2RevoluteJoint::GetJointAngle() const -{ - b2Body* bA = m_bodyA; - b2Body* bB = m_bodyB; - return bB->m_sweep.a - bA->m_sweep.a - m_referenceAngle; -} - -float32 b2RevoluteJoint::GetJointSpeed() const -{ - b2Body* bA = m_bodyA; - b2Body* bB = m_bodyB; - return bB->m_angularVelocity - bA->m_angularVelocity; -} - -bool b2RevoluteJoint::IsMotorEnabled() const -{ - return m_enableMotor; -} - -void b2RevoluteJoint::EnableMotor(bool flag) -{ - if (flag != m_enableMotor) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableMotor = flag; - } -} - -float32 b2RevoluteJoint::GetMotorTorque(float32 inv_dt) const -{ - return inv_dt * m_motorImpulse; -} - -void b2RevoluteJoint::SetMotorSpeed(float32 speed) -{ - if (speed != m_motorSpeed) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_motorSpeed = speed; - } -} - -void b2RevoluteJoint::SetMaxMotorTorque(float32 torque) -{ - if (torque != m_maxMotorTorque) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_maxMotorTorque = torque; - } -} - -bool b2RevoluteJoint::IsLimitEnabled() const -{ - return m_enableLimit; -} - -void b2RevoluteJoint::EnableLimit(bool flag) -{ - if (flag != m_enableLimit) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableLimit = flag; - m_impulse.z = 0.0f; - } -} - -float32 b2RevoluteJoint::GetLowerLimit() const -{ - return m_lowerAngle; -} - -float32 b2RevoluteJoint::GetUpperLimit() const -{ - return m_upperAngle; -} - -void b2RevoluteJoint::SetLimits(float32 lower, float32 upper) -{ - b2Assert(lower <= upper); - - if (lower != m_lowerAngle || upper != m_upperAngle) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_impulse.z = 0.0f; - m_lowerAngle = lower; - m_upperAngle = upper; - } -} - -void b2RevoluteJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2RevoluteJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.referenceAngle = %.15lef;\n", m_referenceAngle); - b2Log(" jd.enableLimit = bool(%d);\n", m_enableLimit); - b2Log(" jd.lowerAngle = %.15lef;\n", m_lowerAngle); - b2Log(" jd.upperAngle = %.15lef;\n", m_upperAngle); - b2Log(" jd.enableMotor = bool(%d);\n", m_enableMotor); - b2Log(" jd.motorSpeed = %.15lef;\n", m_motorSpeed); - b2Log(" jd.maxMotorTorque = %.15lef;\n", m_maxMotorTorque); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RevoluteJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RevoluteJoint.h deleted file mode 100644 index 06b1455..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RevoluteJoint.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_REVOLUTE_JOINT_H -#define B2_REVOLUTE_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Revolute joint definition. This requires defining an -/// anchor point where the bodies are joined. The definition -/// uses local anchor points so that the initial configuration -/// can violate the constraint slightly. You also need to -/// specify the initial relative angle for joint limits. This -/// helps when saving and loading a game. -/// The local anchor points are measured from the body's origin -/// rather than the center of mass because: -/// 1. you might not know where the center of mass will be. -/// 2. if you add/remove shapes from a body and recompute the mass, -/// the joints will be broken. -struct b2RevoluteJointDef : public b2JointDef -{ - b2RevoluteJointDef() - { - type = e_revoluteJoint; - localAnchorA.Set(0.0f, 0.0f); - localAnchorB.Set(0.0f, 0.0f); - referenceAngle = 0.0f; - lowerAngle = 0.0f; - upperAngle = 0.0f; - maxMotorTorque = 0.0f; - motorSpeed = 0.0f; - enableLimit = false; - enableMotor = false; - } - - /// Initialize the bodies, anchors, and reference angle using a world - /// anchor point. - void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The bodyB angle minus bodyA angle in the reference state (radians). - float32 referenceAngle; - - /// A flag to enable joint limits. - bool enableLimit; - - /// The lower angle for the joint limit (radians). - float32 lowerAngle; - - /// The upper angle for the joint limit (radians). - float32 upperAngle; - - /// A flag to enable the joint motor. - bool enableMotor; - - /// The desired motor speed. Usually in radians per second. - float32 motorSpeed; - - /// The maximum motor torque used to achieve the desired motor speed. - /// Usually in N-m. - float32 maxMotorTorque; -}; - -/// A revolute joint constrains two bodies to share a common point while they -/// are free to rotate about the point. The relative rotation about the shared -/// point is the joint angle. You can limit the relative rotation with -/// a joint limit that specifies a lower and upper angle. You can use a motor -/// to drive the relative rotation about the shared point. A maximum motor torque -/// is provided so that infinite forces are not generated. -class b2RevoluteJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// Get the reference angle. - float32 GetReferenceAngle() const { return m_referenceAngle; } - - /// Get the current joint angle in radians. - float32 GetJointAngle() const; - - /// Get the current joint angle speed in radians per second. - float32 GetJointSpeed() const; - - /// Is the joint limit enabled? - bool IsLimitEnabled() const; - - /// Enable/disable the joint limit. - void EnableLimit(bool flag); - - /// Get the lower joint limit in radians. - float32 GetLowerLimit() const; - - /// Get the upper joint limit in radians. - float32 GetUpperLimit() const; - - /// Set the joint limits in radians. - void SetLimits(float32 lower, float32 upper); - - /// Is the joint motor enabled? - bool IsMotorEnabled() const; - - /// Enable/disable the joint motor. - void EnableMotor(bool flag); - - /// Set the motor speed in radians per second. - void SetMotorSpeed(float32 speed); - - /// Get the motor speed in radians per second. - float32 GetMotorSpeed() const; - - /// Set the maximum motor torque, usually in N-m. - void SetMaxMotorTorque(float32 torque); - float32 GetMaxMotorTorque() const { return m_maxMotorTorque; } - - /// Get the reaction force given the inverse time step. - /// Unit is N. - b2Vec2 GetReactionForce(float32 inv_dt) const override; - - /// Get the reaction torque due to the joint limit given the inverse time step. - /// Unit is N*m. - float32 GetReactionTorque(float32 inv_dt) const override; - - /// Get the current motor torque given the inverse time step. - /// Unit is N*m. - float32 GetMotorTorque(float32 inv_dt) const; - - /// Dump to b2Log. - void Dump() override; - -protected: - - friend class b2Joint; - friend class b2GearJoint; - - b2RevoluteJoint(const b2RevoluteJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - b2Vec3 m_impulse; - float32 m_motorImpulse; - - bool m_enableMotor; - float32 m_maxMotorTorque; - float32 m_motorSpeed; - - bool m_enableLimit; - float32 m_referenceAngle; - float32 m_lowerAngle; - float32 m_upperAngle; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - b2Mat33 m_mass; // effective mass for point-to-point constraint. - float32 m_motorMass; // effective mass for motor/limit angular constraint. - b2LimitState m_limitState; -}; - -inline float32 b2RevoluteJoint::GetMotorSpeed() const -{ - return m_motorSpeed; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RopeJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RopeJoint.cpp deleted file mode 100644 index 86d27e7..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RopeJoint.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* -* Copyright (c) 2007-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2RopeJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - - -// Limit: -// C = norm(pB - pA) - L -// u = (pB - pA) / norm(pB - pA) -// Cdot = dot(u, vB + cross(wB, rB) - vA - cross(wA, rA)) -// J = [-u -cross(rA, u) u cross(rB, u)] -// K = J * invM * JT -// = invMassA + invIA * cross(rA, u)^2 + invMassB + invIB * cross(rB, u)^2 - -b2RopeJoint::b2RopeJoint(const b2RopeJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - - m_maxLength = def->maxLength; - - m_mass = 0.0f; - m_impulse = 0.0f; - m_state = e_inactiveLimit; - m_length = 0.0f; -} - -void b2RopeJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - m_u = cB + m_rB - cA - m_rA; - - m_length = m_u.Length(); - - float32 C = m_length - m_maxLength; - if (C > 0.0f) - { - m_state = e_atUpperLimit; - } - else - { - m_state = e_inactiveLimit; - } - - if (m_length > b2_linearSlop) - { - m_u *= 1.0f / m_length; - } - else - { - m_u.SetZero(); - m_mass = 0.0f; - m_impulse = 0.0f; - return; - } - - // Compute effective mass. - float32 crA = b2Cross(m_rA, m_u); - float32 crB = b2Cross(m_rB, m_u); - float32 invMass = m_invMassA + m_invIA * crA * crA + m_invMassB + m_invIB * crB * crB; - - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - - if (data.step.warmStarting) - { - // Scale the impulse to support a variable time step. - m_impulse *= data.step.dtRatio; - - b2Vec2 P = m_impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - } - else - { - m_impulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2RopeJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - // Cdot = dot(u, v + cross(w, r)) - b2Vec2 vpA = vA + b2Cross(wA, m_rA); - b2Vec2 vpB = vB + b2Cross(wB, m_rB); - float32 C = m_length - m_maxLength; - float32 Cdot = b2Dot(m_u, vpB - vpA); - - // Predictive constraint. - if (C < 0.0f) - { - Cdot += data.step.inv_dt * C; - } - - float32 impulse = -m_mass * Cdot; - float32 oldImpulse = m_impulse; - m_impulse = b2Min(0.0f, m_impulse + impulse); - impulse = m_impulse - oldImpulse; - - b2Vec2 P = impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2RopeJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 u = cB + rB - cA - rA; - - float32 length = u.Normalize(); - float32 C = length - m_maxLength; - - C = b2Clamp(C, 0.0f, b2_maxLinearCorrection); - - float32 impulse = -m_mass * C; - b2Vec2 P = impulse * u; - - cA -= m_invMassA * P; - aA -= m_invIA * b2Cross(rA, P); - cB += m_invMassB * P; - aB += m_invIB * b2Cross(rB, P); - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return length - m_maxLength < b2_linearSlop; -} - -b2Vec2 b2RopeJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2RopeJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2RopeJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 F = (inv_dt * m_impulse) * m_u; - return F; -} - -float32 b2RopeJoint::GetReactionTorque(float32 inv_dt) const -{ - B2_NOT_USED(inv_dt); - return 0.0f; -} - -float32 b2RopeJoint::GetMaxLength() const -{ - return m_maxLength; -} - -b2LimitState b2RopeJoint::GetLimitState() const -{ - return m_state; -} - -void b2RopeJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2RopeJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.maxLength = %.15lef;\n", m_maxLength); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RopeJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RopeJoint.h deleted file mode 100644 index ef5d6f7..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2RopeJoint.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_ROPE_JOINT_H -#define B2_ROPE_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Rope joint definition. This requires two body anchor points and -/// a maximum lengths. -/// Note: by default the connected objects will not collide. -/// see collideConnected in b2JointDef. -struct b2RopeJointDef : public b2JointDef -{ - b2RopeJointDef() - { - type = e_ropeJoint; - localAnchorA.Set(-1.0f, 0.0f); - localAnchorB.Set(1.0f, 0.0f); - maxLength = 0.0f; - } - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The maximum length of the rope. - /// Warning: this must be larger than b2_linearSlop or - /// the joint will have no effect. - float32 maxLength; -}; - -/// A rope joint enforces a maximum distance between two points -/// on two bodies. It has no other effect. -/// Warning: if you attempt to change the maximum length during -/// the simulation you will get some non-physical behavior. -/// A model that would allow you to dynamically modify the length -/// would have some sponginess, so I chose not to implement it -/// that way. See b2DistanceJoint if you want to dynamically -/// control length. -class b2RopeJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// Set/Get the maximum length of the rope. - void SetMaxLength(float32 length) { m_maxLength = length; } - float32 GetMaxLength() const; - - b2LimitState GetLimitState() const; - - /// Dump joint to dmLog - void Dump() override; - -protected: - - friend class b2Joint; - b2RopeJoint(const b2RopeJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - float32 m_maxLength; - float32 m_length; - float32 m_impulse; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_u; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - float32 m_mass; - b2LimitState m_state; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WeldJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WeldJoint.cpp deleted file mode 100644 index b10cee8..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WeldJoint.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2WeldJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Point-to-point constraint -// C = p2 - p1 -// Cdot = v2 - v1 -// = v2 + cross(w2, r2) - v1 - cross(w1, r1) -// J = [-I -r1_skew I r2_skew ] -// Identity used: -// w k % (rx i + ry j) = w * (-ry i + rx j) - -// Angle constraint -// C = angle2 - angle1 - referenceAngle -// Cdot = w2 - w1 -// J = [0 0 -1 0 0 1] -// K = invI1 + invI2 - -void b2WeldJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor) -{ - bodyA = bA; - bodyB = bB; - localAnchorA = bodyA->GetLocalPoint(anchor); - localAnchorB = bodyB->GetLocalPoint(anchor); - referenceAngle = bodyB->GetAngle() - bodyA->GetAngle(); -} - -b2WeldJoint::b2WeldJoint(const b2WeldJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - m_referenceAngle = def->referenceAngle; - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; - - m_impulse.SetZero(); -} - -void b2WeldJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - // J = [-I -r1_skew I r2_skew] - // [ 0 -1 0 1] - // r_skew = [-ry; rx] - - // Matlab - // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] - // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] - // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - b2Mat33 K; - K.ex.x = mA + mB + m_rA.y * m_rA.y * iA + m_rB.y * m_rB.y * iB; - K.ey.x = -m_rA.y * m_rA.x * iA - m_rB.y * m_rB.x * iB; - K.ez.x = -m_rA.y * iA - m_rB.y * iB; - K.ex.y = K.ey.x; - K.ey.y = mA + mB + m_rA.x * m_rA.x * iA + m_rB.x * m_rB.x * iB; - K.ez.y = m_rA.x * iA + m_rB.x * iB; - K.ex.z = K.ez.x; - K.ey.z = K.ez.y; - K.ez.z = iA + iB; - - if (m_frequencyHz > 0.0f) - { - K.GetInverse22(&m_mass); - - float32 invM = iA + iB; - float32 m = invM > 0.0f ? 1.0f / invM : 0.0f; - - float32 C = aB - aA - m_referenceAngle; - - // Frequency - float32 omega = 2.0f * b2_pi * m_frequencyHz; - - // Damping coefficient - float32 d = 2.0f * m * m_dampingRatio * omega; - - // Spring stiffness - float32 k = m * omega * omega; - - // magic formulas - float32 h = data.step.dt; - m_gamma = h * (d + h * k); - m_gamma = m_gamma != 0.0f ? 1.0f / m_gamma : 0.0f; - m_bias = C * h * k * m_gamma; - - invM += m_gamma; - m_mass.ez.z = invM != 0.0f ? 1.0f / invM : 0.0f; - } - else if (K.ez.z == 0.0f) - { - K.GetInverse22(&m_mass); - m_gamma = 0.0f; - m_bias = 0.0f; - } - else - { - K.GetSymInverse33(&m_mass); - m_gamma = 0.0f; - m_bias = 0.0f; - } - - if (data.step.warmStarting) - { - // Scale impulses to support a variable time step. - m_impulse *= data.step.dtRatio; - - b2Vec2 P(m_impulse.x, m_impulse.y); - - vA -= mA * P; - wA -= iA * (b2Cross(m_rA, P) + m_impulse.z); - - vB += mB * P; - wB += iB * (b2Cross(m_rB, P) + m_impulse.z); - } - else - { - m_impulse.SetZero(); - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2WeldJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - if (m_frequencyHz > 0.0f) - { - float32 Cdot2 = wB - wA; - - float32 impulse2 = -m_mass.ez.z * (Cdot2 + m_bias + m_gamma * m_impulse.z); - m_impulse.z += impulse2; - - wA -= iA * impulse2; - wB += iB * impulse2; - - b2Vec2 Cdot1 = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); - - b2Vec2 impulse1 = -b2Mul22(m_mass, Cdot1); - m_impulse.x += impulse1.x; - m_impulse.y += impulse1.y; - - b2Vec2 P = impulse1; - - vA -= mA * P; - wA -= iA * b2Cross(m_rA, P); - - vB += mB * P; - wB += iB * b2Cross(m_rB, P); - } - else - { - b2Vec2 Cdot1 = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); - float32 Cdot2 = wB - wA; - b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); - - b2Vec3 impulse = -b2Mul(m_mass, Cdot); - m_impulse += impulse; - - b2Vec2 P(impulse.x, impulse.y); - - vA -= mA * P; - wA -= iA * (b2Cross(m_rA, P) + impulse.z); - - vB += mB * P; - wB += iB * (b2Cross(m_rB, P) + impulse.z); - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2WeldJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - - float32 positionError, angularError; - - b2Mat33 K; - K.ex.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB; - K.ey.x = -rA.y * rA.x * iA - rB.y * rB.x * iB; - K.ez.x = -rA.y * iA - rB.y * iB; - K.ex.y = K.ey.x; - K.ey.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB; - K.ez.y = rA.x * iA + rB.x * iB; - K.ex.z = K.ez.x; - K.ey.z = K.ez.y; - K.ez.z = iA + iB; - - if (m_frequencyHz > 0.0f) - { - b2Vec2 C1 = cB + rB - cA - rA; - - positionError = C1.Length(); - angularError = 0.0f; - - b2Vec2 P = -K.Solve22(C1); - - cA -= mA * P; - aA -= iA * b2Cross(rA, P); - - cB += mB * P; - aB += iB * b2Cross(rB, P); - } - else - { - b2Vec2 C1 = cB + rB - cA - rA; - float32 C2 = aB - aA - m_referenceAngle; - - positionError = C1.Length(); - angularError = b2Abs(C2); - - b2Vec3 C(C1.x, C1.y, C2); - - b2Vec3 impulse; - if (K.ez.z > 0.0f) - { - impulse = -K.Solve33(C); - } - else - { - b2Vec2 impulse2 = -K.Solve22(C1); - impulse.Set(impulse2.x, impulse2.y, 0.0f); - } - - b2Vec2 P(impulse.x, impulse.y); - - cA -= mA * P; - aA -= iA * (b2Cross(rA, P) + impulse.z); - - cB += mB * P; - aB += iB * (b2Cross(rB, P) + impulse.z); - } - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return positionError <= b2_linearSlop && angularError <= b2_angularSlop; -} - -b2Vec2 b2WeldJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2WeldJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2WeldJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 P(m_impulse.x, m_impulse.y); - return inv_dt * P; -} - -float32 b2WeldJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * m_impulse.z; -} - -void b2WeldJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2WeldJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.referenceAngle = %.15lef;\n", m_referenceAngle); - b2Log(" jd.frequencyHz = %.15lef;\n", m_frequencyHz); - b2Log(" jd.dampingRatio = %.15lef;\n", m_dampingRatio); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WeldJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WeldJoint.h deleted file mode 100644 index 81ba235..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WeldJoint.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_WELD_JOINT_H -#define B2_WELD_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Weld joint definition. You need to specify local anchor points -/// where they are attached and the relative body angle. The position -/// of the anchor points is important for computing the reaction torque. -struct b2WeldJointDef : public b2JointDef -{ - b2WeldJointDef() - { - type = e_weldJoint; - localAnchorA.Set(0.0f, 0.0f); - localAnchorB.Set(0.0f, 0.0f); - referenceAngle = 0.0f; - frequencyHz = 0.0f; - dampingRatio = 0.0f; - } - - /// Initialize the bodies, anchors, and reference angle using a world - /// anchor point. - void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The bodyB angle minus bodyA angle in the reference state (radians). - float32 referenceAngle; - - /// The mass-spring-damper frequency in Hertz. Rotation only. - /// Disable softness with a value of 0. - float32 frequencyHz; - - /// The damping ratio. 0 = no damping, 1 = critical damping. - float32 dampingRatio; -}; - -/// A weld joint essentially glues two bodies together. A weld joint may -/// distort somewhat because the island constraint solver is approximate. -class b2WeldJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// Get the reference angle. - float32 GetReferenceAngle() const { return m_referenceAngle; } - - /// Set/get frequency in Hz. - void SetFrequency(float32 hz) { m_frequencyHz = hz; } - float32 GetFrequency() const { return m_frequencyHz; } - - /// Set/get damping ratio. - void SetDampingRatio(float32 ratio) { m_dampingRatio = ratio; } - float32 GetDampingRatio() const { return m_dampingRatio; } - - /// Dump to b2Log - void Dump() override; - -protected: - - friend class b2Joint; - - b2WeldJoint(const b2WeldJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - float32 m_frequencyHz; - float32 m_dampingRatio; - float32 m_bias; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - float32 m_referenceAngle; - float32 m_gamma; - b2Vec3 m_impulse; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_rA; - b2Vec2 m_rB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - b2Mat33 m_mass; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WheelJoint.cpp b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WheelJoint.cpp deleted file mode 100644 index a95311e..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WheelJoint.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/Joints/b2WheelJoint.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -// Linear constraint (point-to-line) -// d = pB - pA = xB + rB - xA - rA -// C = dot(ay, d) -// Cdot = dot(d, cross(wA, ay)) + dot(ay, vB + cross(wB, rB) - vA - cross(wA, rA)) -// = -dot(ay, vA) - dot(cross(d + rA, ay), wA) + dot(ay, vB) + dot(cross(rB, ay), vB) -// J = [-ay, -cross(d + rA, ay), ay, cross(rB, ay)] - -// Spring linear constraint -// C = dot(ax, d) -// Cdot = = -dot(ax, vA) - dot(cross(d + rA, ax), wA) + dot(ax, vB) + dot(cross(rB, ax), vB) -// J = [-ax -cross(d+rA, ax) ax cross(rB, ax)] - -// Motor rotational constraint -// Cdot = wB - wA -// J = [0 0 -1 0 0 1] - -void b2WheelJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor, const b2Vec2& axis) -{ - bodyA = bA; - bodyB = bB; - localAnchorA = bodyA->GetLocalPoint(anchor); - localAnchorB = bodyB->GetLocalPoint(anchor); - localAxisA = bodyA->GetLocalVector(axis); -} - -b2WheelJoint::b2WheelJoint(const b2WheelJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - m_localXAxisA = def->localAxisA; - m_localYAxisA = b2Cross(1.0f, m_localXAxisA); - - m_mass = 0.0f; - m_impulse = 0.0f; - m_motorMass = 0.0f; - m_motorImpulse = 0.0f; - m_springMass = 0.0f; - m_springImpulse = 0.0f; - - m_maxMotorTorque = def->maxMotorTorque; - m_motorSpeed = def->motorSpeed; - m_enableMotor = def->enableMotor; - - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; - - m_bias = 0.0f; - m_gamma = 0.0f; - - m_ax.SetZero(); - m_ay.SetZero(); -} - -void b2WheelJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - // Compute the effective masses. - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 d = cB + rB - cA - rA; - - // Point to line constraint - { - m_ay = b2Mul(qA, m_localYAxisA); - m_sAy = b2Cross(d + rA, m_ay); - m_sBy = b2Cross(rB, m_ay); - - m_mass = mA + mB + iA * m_sAy * m_sAy + iB * m_sBy * m_sBy; - - if (m_mass > 0.0f) - { - m_mass = 1.0f / m_mass; - } - } - - // Spring constraint - m_springMass = 0.0f; - m_bias = 0.0f; - m_gamma = 0.0f; - if (m_frequencyHz > 0.0f) - { - m_ax = b2Mul(qA, m_localXAxisA); - m_sAx = b2Cross(d + rA, m_ax); - m_sBx = b2Cross(rB, m_ax); - - float32 invMass = mA + mB + iA * m_sAx * m_sAx + iB * m_sBx * m_sBx; - - if (invMass > 0.0f) - { - m_springMass = 1.0f / invMass; - - float32 C = b2Dot(d, m_ax); - - // Frequency - float32 omega = 2.0f * b2_pi * m_frequencyHz; - - // Damping coefficient - float32 damp = 2.0f * m_springMass * m_dampingRatio * omega; - - // Spring stiffness - float32 k = m_springMass * omega * omega; - - // magic formulas - float32 h = data.step.dt; - m_gamma = h * (damp + h * k); - if (m_gamma > 0.0f) - { - m_gamma = 1.0f / m_gamma; - } - - m_bias = C * h * k * m_gamma; - - m_springMass = invMass + m_gamma; - if (m_springMass > 0.0f) - { - m_springMass = 1.0f / m_springMass; - } - } - } - else - { - m_springImpulse = 0.0f; - } - - // Rotational motor - if (m_enableMotor) - { - m_motorMass = iA + iB; - if (m_motorMass > 0.0f) - { - m_motorMass = 1.0f / m_motorMass; - } - } - else - { - m_motorMass = 0.0f; - m_motorImpulse = 0.0f; - } - - if (data.step.warmStarting) - { - // Account for variable time step. - m_impulse *= data.step.dtRatio; - m_springImpulse *= data.step.dtRatio; - m_motorImpulse *= data.step.dtRatio; - - b2Vec2 P = m_impulse * m_ay + m_springImpulse * m_ax; - float32 LA = m_impulse * m_sAy + m_springImpulse * m_sAx + m_motorImpulse; - float32 LB = m_impulse * m_sBy + m_springImpulse * m_sBx + m_motorImpulse; - - vA -= m_invMassA * P; - wA -= m_invIA * LA; - - vB += m_invMassB * P; - wB += m_invIB * LB; - } - else - { - m_impulse = 0.0f; - m_springImpulse = 0.0f; - m_motorImpulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2WheelJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; - - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - // Solve spring constraint - { - float32 Cdot = b2Dot(m_ax, vB - vA) + m_sBx * wB - m_sAx * wA; - float32 impulse = -m_springMass * (Cdot + m_bias + m_gamma * m_springImpulse); - m_springImpulse += impulse; - - b2Vec2 P = impulse * m_ax; - float32 LA = impulse * m_sAx; - float32 LB = impulse * m_sBx; - - vA -= mA * P; - wA -= iA * LA; - - vB += mB * P; - wB += iB * LB; - } - - // Solve rotational motor constraint - { - float32 Cdot = wB - wA - m_motorSpeed; - float32 impulse = -m_motorMass * Cdot; - - float32 oldImpulse = m_motorImpulse; - float32 maxImpulse = data.step.dt * m_maxMotorTorque; - m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); - impulse = m_motorImpulse - oldImpulse; - - wA -= iA * impulse; - wB += iB * impulse; - } - - // Solve point to line constraint - { - float32 Cdot = b2Dot(m_ay, vB - vA) + m_sBy * wB - m_sAy * wA; - float32 impulse = -m_mass * Cdot; - m_impulse += impulse; - - b2Vec2 P = impulse * m_ay; - float32 LA = impulse * m_sAy; - float32 LB = impulse * m_sBy; - - vA -= mA * P; - wA -= iA * LA; - - vB += mB * P; - wB += iB * LB; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2WheelJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 d = (cB - cA) + rB - rA; - - b2Vec2 ay = b2Mul(qA, m_localYAxisA); - - float32 sAy = b2Cross(d + rA, ay); - float32 sBy = b2Cross(rB, ay); - - float32 C = b2Dot(d, ay); - - float32 k = m_invMassA + m_invMassB + m_invIA * m_sAy * m_sAy + m_invIB * m_sBy * m_sBy; - - float32 impulse; - if (k != 0.0f) - { - impulse = - C / k; - } - else - { - impulse = 0.0f; - } - - b2Vec2 P = impulse * ay; - float32 LA = impulse * sAy; - float32 LB = impulse * sBy; - - cA -= m_invMassA * P; - aA -= m_invIA * LA; - cB += m_invMassB * P; - aB += m_invIB * LB; - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return b2Abs(C) <= b2_linearSlop; -} - -b2Vec2 b2WheelJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2WheelJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2WheelJoint::GetReactionForce(float32 inv_dt) const -{ - return inv_dt * (m_impulse * m_ay + m_springImpulse * m_ax); -} - -float32 b2WheelJoint::GetReactionTorque(float32 inv_dt) const -{ - return inv_dt * m_motorImpulse; -} - -float32 b2WheelJoint::GetJointTranslation() const -{ - b2Body* bA = m_bodyA; - b2Body* bB = m_bodyB; - - b2Vec2 pA = bA->GetWorldPoint(m_localAnchorA); - b2Vec2 pB = bB->GetWorldPoint(m_localAnchorB); - b2Vec2 d = pB - pA; - b2Vec2 axis = bA->GetWorldVector(m_localXAxisA); - - float32 translation = b2Dot(d, axis); - return translation; -} - -float32 b2WheelJoint::GetJointLinearSpeed() const -{ - b2Body* bA = m_bodyA; - b2Body* bB = m_bodyB; - - b2Vec2 rA = b2Mul(bA->m_xf.q, m_localAnchorA - bA->m_sweep.localCenter); - b2Vec2 rB = b2Mul(bB->m_xf.q, m_localAnchorB - bB->m_sweep.localCenter); - b2Vec2 p1 = bA->m_sweep.c + rA; - b2Vec2 p2 = bB->m_sweep.c + rB; - b2Vec2 d = p2 - p1; - b2Vec2 axis = b2Mul(bA->m_xf.q, m_localXAxisA); - - b2Vec2 vA = bA->m_linearVelocity; - b2Vec2 vB = bB->m_linearVelocity; - float32 wA = bA->m_angularVelocity; - float32 wB = bB->m_angularVelocity; - - float32 speed = b2Dot(d, b2Cross(wA, axis)) + b2Dot(axis, vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA)); - return speed; -} - -float32 b2WheelJoint::GetJointAngle() const -{ - b2Body* bA = m_bodyA; - b2Body* bB = m_bodyB; - return bB->m_sweep.a - bA->m_sweep.a; -} - -float32 b2WheelJoint::GetJointAngularSpeed() const -{ - float32 wA = m_bodyA->m_angularVelocity; - float32 wB = m_bodyB->m_angularVelocity; - return wB - wA; -} - -bool b2WheelJoint::IsMotorEnabled() const -{ - return m_enableMotor; -} - -void b2WheelJoint::EnableMotor(bool flag) -{ - if (flag != m_enableMotor) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableMotor = flag; - } -} - -void b2WheelJoint::SetMotorSpeed(float32 speed) -{ - if (speed != m_motorSpeed) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_motorSpeed = speed; - } -} - -void b2WheelJoint::SetMaxMotorTorque(float32 torque) -{ - if (torque != m_maxMotorTorque) - { - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_maxMotorTorque = torque; - } -} - -float32 b2WheelJoint::GetMotorTorque(float32 inv_dt) const -{ - return inv_dt * m_motorImpulse; -} - -void b2WheelJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2WheelJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.localAxisA.Set(%.15lef, %.15lef);\n", m_localXAxisA.x, m_localXAxisA.y); - b2Log(" jd.enableMotor = bool(%d);\n", m_enableMotor); - b2Log(" jd.motorSpeed = %.15lef;\n", m_motorSpeed); - b2Log(" jd.maxMotorTorque = %.15lef;\n", m_maxMotorTorque); - b2Log(" jd.frequencyHz = %.15lef;\n", m_frequencyHz); - b2Log(" jd.dampingRatio = %.15lef;\n", m_dampingRatio); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WheelJoint.h b/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WheelJoint.h deleted file mode 100644 index be7ad66..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/Joints/b2WheelJoint.h +++ /dev/null @@ -1,216 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_WHEEL_JOINT_H -#define B2_WHEEL_JOINT_H - -#include "Box2D/Dynamics/Joints/b2Joint.h" - -/// Wheel joint definition. This requires defining a line of -/// motion using an axis and an anchor point. The definition uses local -/// anchor points and a local axis so that the initial configuration -/// can violate the constraint slightly. The joint translation is zero -/// when the local anchor points coincide in world space. Using local -/// anchors and a local axis helps when saving and loading a game. -struct b2WheelJointDef : public b2JointDef -{ - b2WheelJointDef() - { - type = e_wheelJoint; - localAnchorA.SetZero(); - localAnchorB.SetZero(); - localAxisA.Set(1.0f, 0.0f); - enableMotor = false; - maxMotorTorque = 0.0f; - motorSpeed = 0.0f; - frequencyHz = 2.0f; - dampingRatio = 0.7f; - } - - /// Initialize the bodies, anchors, axis, and reference angle using the world - /// anchor and world axis. - void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis); - - /// The local anchor point relative to bodyA's origin. - b2Vec2 localAnchorA; - - /// The local anchor point relative to bodyB's origin. - b2Vec2 localAnchorB; - - /// The local translation axis in bodyA. - b2Vec2 localAxisA; - - /// Enable/disable the joint motor. - bool enableMotor; - - /// The maximum motor torque, usually in N-m. - float32 maxMotorTorque; - - /// The desired motor speed in radians per second. - float32 motorSpeed; - - /// Suspension frequency, zero indicates no suspension - float32 frequencyHz; - - /// Suspension damping ratio, one indicates critical damping - float32 dampingRatio; -}; - -/// A wheel joint. This joint provides two degrees of freedom: translation -/// along an axis fixed in bodyA and rotation in the plane. In other words, it is a point to -/// line constraint with a rotational motor and a linear spring/damper. -/// This joint is designed for vehicle suspensions. -class b2WheelJoint : public b2Joint -{ -public: - b2Vec2 GetAnchorA() const override; - b2Vec2 GetAnchorB() const override; - - b2Vec2 GetReactionForce(float32 inv_dt) const override; - float32 GetReactionTorque(float32 inv_dt) const override; - - /// The local anchor point relative to bodyA's origin. - const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } - - /// The local anchor point relative to bodyB's origin. - const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } - - /// The local joint axis relative to bodyA. - const b2Vec2& GetLocalAxisA() const { return m_localXAxisA; } - - /// Get the current joint translation, usually in meters. - float32 GetJointTranslation() const; - - /// Get the current joint linear speed, usually in meters per second. - float32 GetJointLinearSpeed() const; - - /// Get the current joint angle in radians. - float32 GetJointAngle() const; - - /// Get the current joint angular speed in radians per second. - float32 GetJointAngularSpeed() const; - - /// Is the joint motor enabled? - bool IsMotorEnabled() const; - - /// Enable/disable the joint motor. - void EnableMotor(bool flag); - - /// Set the motor speed, usually in radians per second. - void SetMotorSpeed(float32 speed); - - /// Get the motor speed, usually in radians per second. - float32 GetMotorSpeed() const; - - /// Set/Get the maximum motor force, usually in N-m. - void SetMaxMotorTorque(float32 torque); - float32 GetMaxMotorTorque() const; - - /// Get the current motor torque given the inverse time step, usually in N-m. - float32 GetMotorTorque(float32 inv_dt) const; - - /// Set/Get the spring frequency in hertz. Setting the frequency to zero disables the spring. - void SetSpringFrequencyHz(float32 hz); - float32 GetSpringFrequencyHz() const; - - /// Set/Get the spring damping ratio - void SetSpringDampingRatio(float32 ratio); - float32 GetSpringDampingRatio() const; - - /// Dump to b2Log - void Dump() override; - -protected: - - friend class b2Joint; - b2WheelJoint(const b2WheelJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data) override; - void SolveVelocityConstraints(const b2SolverData& data) override; - bool SolvePositionConstraints(const b2SolverData& data) override; - - float32 m_frequencyHz; - float32 m_dampingRatio; - - // Solver shared - b2Vec2 m_localAnchorA; - b2Vec2 m_localAnchorB; - b2Vec2 m_localXAxisA; - b2Vec2 m_localYAxisA; - - float32 m_impulse; - float32 m_motorImpulse; - float32 m_springImpulse; - - float32 m_maxMotorTorque; - float32 m_motorSpeed; - bool m_enableMotor; - - // Solver temp - int32 m_indexA; - int32 m_indexB; - b2Vec2 m_localCenterA; - b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - - b2Vec2 m_ax, m_ay; - float32 m_sAx, m_sBx; - float32 m_sAy, m_sBy; - - float32 m_mass; - float32 m_motorMass; - float32 m_springMass; - - float32 m_bias; - float32 m_gamma; -}; - -inline float32 b2WheelJoint::GetMotorSpeed() const -{ - return m_motorSpeed; -} - -inline float32 b2WheelJoint::GetMaxMotorTorque() const -{ - return m_maxMotorTorque; -} - -inline void b2WheelJoint::SetSpringFrequencyHz(float32 hz) -{ - m_frequencyHz = hz; -} - -inline float32 b2WheelJoint::GetSpringFrequencyHz() const -{ - return m_frequencyHz; -} - -inline void b2WheelJoint::SetSpringDampingRatio(float32 ratio) -{ - m_dampingRatio = ratio; -} - -inline float32 b2WheelJoint::GetSpringDampingRatio() const -{ - return m_dampingRatio; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2Body.cpp b/src/libjin/3rdparty/Box2D/Dynamics/b2Body.cpp deleted file mode 100644 index 54154b8..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2Body.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2World.h" -#include "Box2D/Dynamics/Contacts/b2Contact.h" -#include "Box2D/Dynamics/Joints/b2Joint.h" - -b2Body::b2Body(const b2BodyDef* bd, b2World* world) -{ - b2Assert(bd->position.IsValid()); - b2Assert(bd->linearVelocity.IsValid()); - b2Assert(b2IsValid(bd->angle)); - b2Assert(b2IsValid(bd->angularVelocity)); - b2Assert(b2IsValid(bd->angularDamping) && bd->angularDamping >= 0.0f); - b2Assert(b2IsValid(bd->linearDamping) && bd->linearDamping >= 0.0f); - - m_flags = 0; - - if (bd->bullet) - { - m_flags |= e_bulletFlag; - } - if (bd->fixedRotation) - { - m_flags |= e_fixedRotationFlag; - } - if (bd->allowSleep) - { - m_flags |= e_autoSleepFlag; - } - if (bd->awake) - { - m_flags |= e_awakeFlag; - } - if (bd->active) - { - m_flags |= e_activeFlag; - } - - m_world = world; - - m_xf.p = bd->position; - m_xf.q.Set(bd->angle); - - m_sweep.localCenter.SetZero(); - m_sweep.c0 = m_xf.p; - m_sweep.c = m_xf.p; - m_sweep.a0 = bd->angle; - m_sweep.a = bd->angle; - m_sweep.alpha0 = 0.0f; - - m_jointList = nullptr; - m_contactList = nullptr; - m_prev = nullptr; - m_next = nullptr; - - m_linearVelocity = bd->linearVelocity; - m_angularVelocity = bd->angularVelocity; - - m_linearDamping = bd->linearDamping; - m_angularDamping = bd->angularDamping; - m_gravityScale = bd->gravityScale; - - m_force.SetZero(); - m_torque = 0.0f; - - m_sleepTime = 0.0f; - - m_type = bd->type; - - if (m_type == b2_dynamicBody) - { - m_mass = 1.0f; - m_invMass = 1.0f; - } - else - { - m_mass = 0.0f; - m_invMass = 0.0f; - } - - m_I = 0.0f; - m_invI = 0.0f; - - m_userData = bd->userData; - - m_fixtureList = nullptr; - m_fixtureCount = 0; -} - -b2Body::~b2Body() -{ - // shapes and joints are destroyed in b2World::Destroy -} - -void b2Body::SetType(b2BodyType type) -{ - b2Assert(m_world->IsLocked() == false); - if (m_world->IsLocked() == true) - { - return; - } - - if (m_type == type) - { - return; - } - - m_type = type; - - ResetMassData(); - - if (m_type == b2_staticBody) - { - m_linearVelocity.SetZero(); - m_angularVelocity = 0.0f; - m_sweep.a0 = m_sweep.a; - m_sweep.c0 = m_sweep.c; - SynchronizeFixtures(); - } - - SetAwake(true); - - m_force.SetZero(); - m_torque = 0.0f; - - // Delete the attached contacts. - b2ContactEdge* ce = m_contactList; - while (ce) - { - b2ContactEdge* ce0 = ce; - ce = ce->next; - m_world->m_contactManager.Destroy(ce0->contact); - } - m_contactList = nullptr; - - // Touch the proxies so that new contacts will be created (when appropriate) - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - int32 proxyCount = f->m_proxyCount; - for (int32 i = 0; i < proxyCount; ++i) - { - broadPhase->TouchProxy(f->m_proxies[i].proxyId); - } - } -} - -b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def) -{ - b2Assert(m_world->IsLocked() == false); - if (m_world->IsLocked() == true) - { - return nullptr; - } - - b2BlockAllocator* allocator = &m_world->m_blockAllocator; - - void* memory = allocator->Allocate(sizeof(b2Fixture)); - b2Fixture* fixture = new (memory) b2Fixture; - fixture->Create(allocator, this, def); - - if (m_flags & e_activeFlag) - { - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - fixture->CreateProxies(broadPhase, m_xf); - } - - fixture->m_next = m_fixtureList; - m_fixtureList = fixture; - ++m_fixtureCount; - - fixture->m_body = this; - - // Adjust mass properties if needed. - if (fixture->m_density > 0.0f) - { - ResetMassData(); - } - - // Let the world know we have a new fixture. This will cause new contacts - // to be created at the beginning of the next time step. - m_world->m_flags |= b2World::e_newFixture; - - return fixture; -} - -b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density) -{ - b2FixtureDef def; - def.shape = shape; - def.density = density; - - return CreateFixture(&def); -} - -void b2Body::DestroyFixture(b2Fixture* fixture) -{ - if (fixture == NULL) - { - return; - } - - b2Assert(m_world->IsLocked() == false); - if (m_world->IsLocked() == true) - { - return; - } - - b2Assert(fixture->m_body == this); - - // Remove the fixture from this body's singly linked list. - b2Assert(m_fixtureCount > 0); - b2Fixture** node = &m_fixtureList; - bool found = false; - while (*node != nullptr) - { - if (*node == fixture) - { - *node = fixture->m_next; - found = true; - break; - } - - node = &(*node)->m_next; - } - - // You tried to remove a shape that is not attached to this body. - b2Assert(found); - - // Destroy any contacts associated with the fixture. - b2ContactEdge* edge = m_contactList; - while (edge) - { - b2Contact* c = edge->contact; - edge = edge->next; - - b2Fixture* fixtureA = c->GetFixtureA(); - b2Fixture* fixtureB = c->GetFixtureB(); - - if (fixture == fixtureA || fixture == fixtureB) - { - // This destroys the contact and removes it from - // this body's contact list. - m_world->m_contactManager.Destroy(c); - } - } - - b2BlockAllocator* allocator = &m_world->m_blockAllocator; - - if (m_flags & e_activeFlag) - { - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - fixture->DestroyProxies(broadPhase); - } - - fixture->m_body = nullptr; - fixture->m_next = nullptr; - fixture->Destroy(allocator); - fixture->~b2Fixture(); - allocator->Free(fixture, sizeof(b2Fixture)); - - --m_fixtureCount; - - // Reset the mass data. - ResetMassData(); -} - -void b2Body::ResetMassData() -{ - // Compute mass data from shapes. Each shape has its own density. - m_mass = 0.0f; - m_invMass = 0.0f; - m_I = 0.0f; - m_invI = 0.0f; - m_sweep.localCenter.SetZero(); - - // Static and kinematic bodies have zero mass. - if (m_type == b2_staticBody || m_type == b2_kinematicBody) - { - m_sweep.c0 = m_xf.p; - m_sweep.c = m_xf.p; - m_sweep.a0 = m_sweep.a; - return; - } - - b2Assert(m_type == b2_dynamicBody); - - // Accumulate mass over all fixtures. - b2Vec2 localCenter = b2Vec2_zero; - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - if (f->m_density == 0.0f) - { - continue; - } - - b2MassData massData; - f->GetMassData(&massData); - m_mass += massData.mass; - localCenter += massData.mass * massData.center; - m_I += massData.I; - } - - // Compute center of mass. - if (m_mass > 0.0f) - { - m_invMass = 1.0f / m_mass; - localCenter *= m_invMass; - } - else - { - // Force all dynamic bodies to have a positive mass. - m_mass = 1.0f; - m_invMass = 1.0f; - } - - if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) - { - // Center the inertia about the center of mass. - m_I -= m_mass * b2Dot(localCenter, localCenter); - b2Assert(m_I > 0.0f); - m_invI = 1.0f / m_I; - - } - else - { - m_I = 0.0f; - m_invI = 0.0f; - } - - // Move center of mass. - b2Vec2 oldCenter = m_sweep.c; - m_sweep.localCenter = localCenter; - m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); - - // Update center of mass velocity. - m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter); -} - -void b2Body::SetMassData(const b2MassData* massData) -{ - b2Assert(m_world->IsLocked() == false); - if (m_world->IsLocked() == true) - { - return; - } - - if (m_type != b2_dynamicBody) - { - return; - } - - m_invMass = 0.0f; - m_I = 0.0f; - m_invI = 0.0f; - - m_mass = massData->mass; - if (m_mass <= 0.0f) - { - m_mass = 1.0f; - } - - m_invMass = 1.0f / m_mass; - - if (massData->I > 0.0f && (m_flags & b2Body::e_fixedRotationFlag) == 0) - { - m_I = massData->I - m_mass * b2Dot(massData->center, massData->center); - b2Assert(m_I > 0.0f); - m_invI = 1.0f / m_I; - } - - // Move center of mass. - b2Vec2 oldCenter = m_sweep.c; - m_sweep.localCenter = massData->center; - m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); - - // Update center of mass velocity. - m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter); -} - -bool b2Body::ShouldCollide(const b2Body* other) const -{ - // At least one body should be dynamic. - if (m_type != b2_dynamicBody && other->m_type != b2_dynamicBody) - { - return false; - } - - // Does a joint prevent collision? - for (b2JointEdge* jn = m_jointList; jn; jn = jn->next) - { - if (jn->other == other) - { - if (jn->joint->m_collideConnected == false) - { - return false; - } - } - } - - return true; -} - -void b2Body::SetTransform(const b2Vec2& position, float32 angle) -{ - b2Assert(m_world->IsLocked() == false); - if (m_world->IsLocked() == true) - { - return; - } - - m_xf.q.Set(angle); - m_xf.p = position; - - m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); - m_sweep.a = angle; - - m_sweep.c0 = m_sweep.c; - m_sweep.a0 = angle; - - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - f->Synchronize(broadPhase, m_xf, m_xf); - } -} - -void b2Body::SynchronizeFixtures() -{ - b2Transform xf1; - xf1.q.Set(m_sweep.a0); - xf1.p = m_sweep.c0 - b2Mul(xf1.q, m_sweep.localCenter); - - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - f->Synchronize(broadPhase, xf1, m_xf); - } -} - -void b2Body::SetActive(bool flag) -{ - b2Assert(m_world->IsLocked() == false); - - if (flag == IsActive()) - { - return; - } - - if (flag) - { - m_flags |= e_activeFlag; - - // Create all proxies. - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - f->CreateProxies(broadPhase, m_xf); - } - - // Contacts are created the next time step. - } - else - { - m_flags &= ~e_activeFlag; - - // Destroy all proxies. - b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - f->DestroyProxies(broadPhase); - } - - // Destroy the attached contacts. - b2ContactEdge* ce = m_contactList; - while (ce) - { - b2ContactEdge* ce0 = ce; - ce = ce->next; - m_world->m_contactManager.Destroy(ce0->contact); - } - m_contactList = nullptr; - } -} - -void b2Body::SetFixedRotation(bool flag) -{ - bool status = (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; - if (status == flag) - { - return; - } - - if (flag) - { - m_flags |= e_fixedRotationFlag; - } - else - { - m_flags &= ~e_fixedRotationFlag; - } - - m_angularVelocity = 0.0f; - - ResetMassData(); -} - -void b2Body::Dump() -{ - int32 bodyIndex = m_islandIndex; - - b2Log("{\n"); - b2Log(" b2BodyDef bd;\n"); - b2Log(" bd.type = b2BodyType(%d);\n", m_type); - b2Log(" bd.position.Set(%.15lef, %.15lef);\n", m_xf.p.x, m_xf.p.y); - b2Log(" bd.angle = %.15lef;\n", m_sweep.a); - b2Log(" bd.linearVelocity.Set(%.15lef, %.15lef);\n", m_linearVelocity.x, m_linearVelocity.y); - b2Log(" bd.angularVelocity = %.15lef;\n", m_angularVelocity); - b2Log(" bd.linearDamping = %.15lef;\n", m_linearDamping); - b2Log(" bd.angularDamping = %.15lef;\n", m_angularDamping); - b2Log(" bd.allowSleep = bool(%d);\n", m_flags & e_autoSleepFlag); - b2Log(" bd.awake = bool(%d);\n", m_flags & e_awakeFlag); - b2Log(" bd.fixedRotation = bool(%d);\n", m_flags & e_fixedRotationFlag); - b2Log(" bd.bullet = bool(%d);\n", m_flags & e_bulletFlag); - b2Log(" bd.active = bool(%d);\n", m_flags & e_activeFlag); - b2Log(" bd.gravityScale = %.15lef;\n", m_gravityScale); - b2Log(" bodies[%d] = m_world->CreateBody(&bd);\n", m_islandIndex); - b2Log("\n"); - for (b2Fixture* f = m_fixtureList; f; f = f->m_next) - { - b2Log(" {\n"); - f->Dump(bodyIndex); - b2Log(" }\n"); - } - b2Log("}\n"); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2Body.h b/src/libjin/3rdparty/Box2D/Dynamics/b2Body.h deleted file mode 100644 index c191f6d..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2Body.h +++ /dev/null @@ -1,882 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_BODY_H -#define B2_BODY_H - -#include "Box2D/Common/b2Math.h" -#include "Box2D/Collision/Shapes/b2Shape.h" -#include <memory> - -class b2Fixture; -class b2Joint; -class b2Contact; -class b2Controller; -class b2World; -struct b2FixtureDef; -struct b2JointEdge; -struct b2ContactEdge; - -/// The body type. -/// static: zero mass, zero velocity, may be manually moved -/// kinematic: zero mass, non-zero velocity set by user, moved by solver -/// dynamic: positive mass, non-zero velocity determined by forces, moved by solver -enum b2BodyType -{ - b2_staticBody = 0, - b2_kinematicBody, - b2_dynamicBody - - // TODO_ERIN - //b2_bulletBody, -}; - -/// A body definition holds all the data needed to construct a rigid body. -/// You can safely re-use body definitions. Shapes are added to a body after construction. -struct b2BodyDef -{ - /// This constructor sets the body definition default values. - b2BodyDef() - { - userData = nullptr; - position.Set(0.0f, 0.0f); - angle = 0.0f; - linearVelocity.Set(0.0f, 0.0f); - angularVelocity = 0.0f; - linearDamping = 0.0f; - angularDamping = 0.0f; - allowSleep = true; - awake = true; - fixedRotation = false; - bullet = false; - type = b2_staticBody; - active = true; - gravityScale = 1.0f; - } - - /// The body type: static, kinematic, or dynamic. - /// Note: if a dynamic body would have zero mass, the mass is set to one. - b2BodyType type; - - /// The world position of the body. Avoid creating bodies at the origin - /// since this can lead to many overlapping shapes. - b2Vec2 position; - - /// The world angle of the body in radians. - float32 angle; - - /// The linear velocity of the body's origin in world co-ordinates. - b2Vec2 linearVelocity; - - /// The angular velocity of the body. - float32 angularVelocity; - - /// Linear damping is use to reduce the linear velocity. The damping parameter - /// can be larger than 1.0f but the damping effect becomes sensitive to the - /// time step when the damping parameter is large. - /// Units are 1/time - float32 linearDamping; - - /// Angular damping is use to reduce the angular velocity. The damping parameter - /// can be larger than 1.0f but the damping effect becomes sensitive to the - /// time step when the damping parameter is large. - /// Units are 1/time - float32 angularDamping; - - /// Set this flag to false if this body should never fall asleep. Note that - /// this increases CPU usage. - bool allowSleep; - - /// Is this body initially awake or sleeping? - bool awake; - - /// Should this body be prevented from rotating? Useful for characters. - bool fixedRotation; - - /// Is this a fast moving body that should be prevented from tunneling through - /// other moving bodies? Note that all bodies are prevented from tunneling through - /// kinematic and static bodies. This setting is only considered on dynamic bodies. - /// @warning You should use this flag sparingly since it increases processing time. - bool bullet; - - /// Does this body start out active? - bool active; - - /// Use this to store application specific body data. - void* userData; - - /// Scale the gravity applied to this body. - float32 gravityScale; -}; - -/// A rigid body. These are created via b2World::CreateBody. -class b2Body -{ -public: - /// Creates a fixture and attach it to this body. Use this function if you need - /// to set some fixture parameters, like friction. Otherwise you can create the - /// fixture directly from a shape. - /// If the density is non-zero, this function automatically updates the mass of the body. - /// Contacts are not created until the next time step. - /// @param def the fixture definition. - /// @warning This function is locked during callbacks. - b2Fixture* CreateFixture(const b2FixtureDef* def); - - /// Creates a fixture from a shape and attach it to this body. - /// This is a convenience function. Use b2FixtureDef if you need to set parameters - /// like friction, restitution, user data, or filtering. - /// If the density is non-zero, this function automatically updates the mass of the body. - /// @param shape the shape to be cloned. - /// @param density the shape density (set to zero for static bodies). - /// @warning This function is locked during callbacks. - b2Fixture* CreateFixture(const b2Shape* shape, float32 density); - - /// Destroy a fixture. This removes the fixture from the broad-phase and - /// destroys all contacts associated with this fixture. This will - /// automatically adjust the mass of the body if the body is dynamic and the - /// fixture has positive density. - /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. - /// @param fixture the fixture to be removed. - /// @warning This function is locked during callbacks. - void DestroyFixture(b2Fixture* fixture); - - /// Set the position of the body's origin and rotation. - /// Manipulating a body's transform may cause non-physical behavior. - /// Note: contacts are updated on the next call to b2World::Step. - /// @param position the world position of the body's local origin. - /// @param angle the world rotation in radians. - void SetTransform(const b2Vec2& position, float32 angle); - - /// Get the body transform for the body's origin. - /// @return the world transform of the body's origin. - const b2Transform& GetTransform() const; - - /// Get the world body origin position. - /// @return the world position of the body's origin. - const b2Vec2& GetPosition() const; - - /// Get the angle in radians. - /// @return the current world rotation angle in radians. - float32 GetAngle() const; - - /// Get the world position of the center of mass. - const b2Vec2& GetWorldCenter() const; - - /// Get the local position of the center of mass. - const b2Vec2& GetLocalCenter() const; - - /// Set the linear velocity of the center of mass. - /// @param v the new linear velocity of the center of mass. - void SetLinearVelocity(const b2Vec2& v); - - /// Get the linear velocity of the center of mass. - /// @return the linear velocity of the center of mass. - const b2Vec2& GetLinearVelocity() const; - - /// Set the angular velocity. - /// @param omega the new angular velocity in radians/second. - void SetAngularVelocity(float32 omega); - - /// Get the angular velocity. - /// @return the angular velocity in radians/second. - float32 GetAngularVelocity() const; - - /// Apply a force at a world point. If the force is not - /// applied at the center of mass, it will generate a torque and - /// affect the angular velocity. This wakes up the body. - /// @param force the world force vector, usually in Newtons (N). - /// @param point the world position of the point of application. - /// @param wake also wake up the body - void ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake); - - /// Apply a force to the center of mass. This wakes up the body. - /// @param force the world force vector, usually in Newtons (N). - /// @param wake also wake up the body - void ApplyForceToCenter(const b2Vec2& force, bool wake); - - /// Apply a torque. This affects the angular velocity - /// without affecting the linear velocity of the center of mass. - /// @param torque about the z-axis (out of the screen), usually in N-m. - /// @param wake also wake up the body - void ApplyTorque(float32 torque, bool wake); - - /// Apply an impulse at a point. This immediately modifies the velocity. - /// It also modifies the angular velocity if the point of application - /// is not at the center of mass. This wakes up the body. - /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. - /// @param point the world position of the point of application. - /// @param wake also wake up the body - void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point, bool wake); - - /// Apply an impulse to the center of mass. This immediately modifies the velocity. - /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. - /// @param wake also wake up the body - void ApplyLinearImpulseToCenter(const b2Vec2& impulse, bool wake); - - /// Apply an angular impulse. - /// @param impulse the angular impulse in units of kg*m*m/s - /// @param wake also wake up the body - void ApplyAngularImpulse(float32 impulse, bool wake); - - /// Get the total mass of the body. - /// @return the mass, usually in kilograms (kg). - float32 GetMass() const; - - /// Get the rotational inertia of the body about the local origin. - /// @return the rotational inertia, usually in kg-m^2. - float32 GetInertia() const; - - /// Get the mass data of the body. - /// @return a struct containing the mass, inertia and center of the body. - void GetMassData(b2MassData* data) const; - - /// Set the mass properties to override the mass properties of the fixtures. - /// Note that this changes the center of mass position. - /// Note that creating or destroying fixtures can also alter the mass. - /// This function has no effect if the body isn't dynamic. - /// @param massData the mass properties. - void SetMassData(const b2MassData* data); - - /// This resets the mass properties to the sum of the mass properties of the fixtures. - /// This normally does not need to be called unless you called SetMassData to override - /// the mass and you later want to reset the mass. - void ResetMassData(); - - /// Get the world coordinates of a point given the local coordinates. - /// @param localPoint a point on the body measured relative the the body's origin. - /// @return the same point expressed in world coordinates. - b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const; - - /// Get the world coordinates of a vector given the local coordinates. - /// @param localVector a vector fixed in the body. - /// @return the same vector expressed in world coordinates. - b2Vec2 GetWorldVector(const b2Vec2& localVector) const; - - /// Gets a local point relative to the body's origin given a world point. - /// @param a point in world coordinates. - /// @return the corresponding local point relative to the body's origin. - b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const; - - /// Gets a local vector given a world vector. - /// @param a vector in world coordinates. - /// @return the corresponding local vector. - b2Vec2 GetLocalVector(const b2Vec2& worldVector) const; - - /// Get the world linear velocity of a world point attached to this body. - /// @param a point in world coordinates. - /// @return the world velocity of a point. - b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const; - - /// Get the world velocity of a local point. - /// @param a point in local coordinates. - /// @return the world velocity of a point. - b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const; - - /// Get the linear damping of the body. - float32 GetLinearDamping() const; - - /// Set the linear damping of the body. - void SetLinearDamping(float32 linearDamping); - - /// Get the angular damping of the body. - float32 GetAngularDamping() const; - - /// Set the angular damping of the body. - void SetAngularDamping(float32 angularDamping); - - /// Get the gravity scale of the body. - float32 GetGravityScale() const; - - /// Set the gravity scale of the body. - void SetGravityScale(float32 scale); - - /// Set the type of this body. This may alter the mass and velocity. - void SetType(b2BodyType type); - - /// Get the type of this body. - b2BodyType GetType() const; - - /// Should this body be treated like a bullet for continuous collision detection? - void SetBullet(bool flag); - - /// Is this body treated like a bullet for continuous collision detection? - bool IsBullet() const; - - /// You can disable sleeping on this body. If you disable sleeping, the - /// body will be woken. - void SetSleepingAllowed(bool flag); - - /// Is this body allowed to sleep - bool IsSleepingAllowed() const; - - /// Set the sleep state of the body. A sleeping body has very - /// low CPU cost. - /// @param flag set to true to wake the body, false to put it to sleep. - void SetAwake(bool flag); - - /// Get the sleeping state of this body. - /// @return true if the body is awake. - bool IsAwake() const; - - /// Set the active state of the body. An inactive body is not - /// simulated and cannot be collided with or woken up. - /// If you pass a flag of true, all fixtures will be added to the - /// broad-phase. - /// If you pass a flag of false, all fixtures will be removed from - /// the broad-phase and all contacts will be destroyed. - /// Fixtures and joints are otherwise unaffected. You may continue - /// to create/destroy fixtures and joints on inactive bodies. - /// Fixtures on an inactive body are implicitly inactive and will - /// not participate in collisions, ray-casts, or queries. - /// Joints connected to an inactive body are implicitly inactive. - /// An inactive body is still owned by a b2World object and remains - /// in the body list. - void SetActive(bool flag); - - /// Get the active state of the body. - bool IsActive() const; - - /// Set this body to have fixed rotation. This causes the mass - /// to be reset. - void SetFixedRotation(bool flag); - - /// Does this body have fixed rotation? - bool IsFixedRotation() const; - - /// Get the list of all fixtures attached to this body. - b2Fixture* GetFixtureList(); - const b2Fixture* GetFixtureList() const; - - /// Get the list of all joints attached to this body. - b2JointEdge* GetJointList(); - const b2JointEdge* GetJointList() const; - - /// Get the list of all contacts attached to this body. - /// @warning this list changes during the time step and you may - /// miss some collisions if you don't use b2ContactListener. - b2ContactEdge* GetContactList(); - const b2ContactEdge* GetContactList() const; - - /// Get the next body in the world's body list. - b2Body* GetNext(); - const b2Body* GetNext() const; - - /// Get the user data pointer that was provided in the body definition. - void* GetUserData() const; - - /// Set the user data. Use this to store your application specific data. - void SetUserData(void* data); - - /// Get the parent world of this body. - b2World* GetWorld(); - const b2World* GetWorld() const; - - /// Dump this body to a log file - void Dump(); - -private: - - friend class b2World; - friend class b2Island; - friend class b2ContactManager; - friend class b2ContactSolver; - friend class b2Contact; - - friend class b2DistanceJoint; - friend class b2FrictionJoint; - friend class b2GearJoint; - friend class b2MotorJoint; - friend class b2MouseJoint; - friend class b2PrismaticJoint; - friend class b2PulleyJoint; - friend class b2RevoluteJoint; - friend class b2RopeJoint; - friend class b2WeldJoint; - friend class b2WheelJoint; - - // m_flags - enum - { - e_islandFlag = 0x0001, - e_awakeFlag = 0x0002, - e_autoSleepFlag = 0x0004, - e_bulletFlag = 0x0008, - e_fixedRotationFlag = 0x0010, - e_activeFlag = 0x0020, - e_toiFlag = 0x0040 - }; - - b2Body(const b2BodyDef* bd, b2World* world); - ~b2Body(); - - void SynchronizeFixtures(); - void SynchronizeTransform(); - - // This is used to prevent connected bodies from colliding. - // It may lie, depending on the collideConnected flag. - bool ShouldCollide(const b2Body* other) const; - - void Advance(float32 t); - - b2BodyType m_type; - - uint16 m_flags; - - int32 m_islandIndex; - - b2Transform m_xf; // the body origin transform - b2Sweep m_sweep; // the swept motion for CCD - - b2Vec2 m_linearVelocity; - float32 m_angularVelocity; - - b2Vec2 m_force; - float32 m_torque; - - b2World* m_world; - b2Body* m_prev; - b2Body* m_next; - - b2Fixture* m_fixtureList; - int32 m_fixtureCount; - - b2JointEdge* m_jointList; - b2ContactEdge* m_contactList; - - float32 m_mass, m_invMass; - - // Rotational inertia about the center of mass. - float32 m_I, m_invI; - - float32 m_linearDamping; - float32 m_angularDamping; - float32 m_gravityScale; - - float32 m_sleepTime; - - void* m_userData; -}; - -inline b2BodyType b2Body::GetType() const -{ - return m_type; -} - -inline const b2Transform& b2Body::GetTransform() const -{ - return m_xf; -} - -inline const b2Vec2& b2Body::GetPosition() const -{ - return m_xf.p; -} - -inline float32 b2Body::GetAngle() const -{ - return m_sweep.a; -} - -inline const b2Vec2& b2Body::GetWorldCenter() const -{ - return m_sweep.c; -} - -inline const b2Vec2& b2Body::GetLocalCenter() const -{ - return m_sweep.localCenter; -} - -inline void b2Body::SetLinearVelocity(const b2Vec2& v) -{ - if (m_type == b2_staticBody) - { - return; - } - - if (b2Dot(v,v) > 0.0f) - { - SetAwake(true); - } - - m_linearVelocity = v; -} - -inline const b2Vec2& b2Body::GetLinearVelocity() const -{ - return m_linearVelocity; -} - -inline void b2Body::SetAngularVelocity(float32 w) -{ - if (m_type == b2_staticBody) - { - return; - } - - if (w * w > 0.0f) - { - SetAwake(true); - } - - m_angularVelocity = w; -} - -inline float32 b2Body::GetAngularVelocity() const -{ - return m_angularVelocity; -} - -inline float32 b2Body::GetMass() const -{ - return m_mass; -} - -inline float32 b2Body::GetInertia() const -{ - return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); -} - -inline void b2Body::GetMassData(b2MassData* data) const -{ - data->mass = m_mass; - data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); - data->center = m_sweep.localCenter; -} - -inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const -{ - return b2Mul(m_xf, localPoint); -} - -inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const -{ - return b2Mul(m_xf.q, localVector); -} - -inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const -{ - return b2MulT(m_xf, worldPoint); -} - -inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const -{ - return b2MulT(m_xf.q, worldVector); -} - -inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const -{ - return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c); -} - -inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const -{ - return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint)); -} - -inline float32 b2Body::GetLinearDamping() const -{ - return m_linearDamping; -} - -inline void b2Body::SetLinearDamping(float32 linearDamping) -{ - m_linearDamping = linearDamping; -} - -inline float32 b2Body::GetAngularDamping() const -{ - return m_angularDamping; -} - -inline void b2Body::SetAngularDamping(float32 angularDamping) -{ - m_angularDamping = angularDamping; -} - -inline float32 b2Body::GetGravityScale() const -{ - return m_gravityScale; -} - -inline void b2Body::SetGravityScale(float32 scale) -{ - m_gravityScale = scale; -} - -inline void b2Body::SetBullet(bool flag) -{ - if (flag) - { - m_flags |= e_bulletFlag; - } - else - { - m_flags &= ~e_bulletFlag; - } -} - -inline bool b2Body::IsBullet() const -{ - return (m_flags & e_bulletFlag) == e_bulletFlag; -} - -inline void b2Body::SetAwake(bool flag) -{ - if (flag) - { - m_flags |= e_awakeFlag; - m_sleepTime = 0.0f; - } - else - { - m_flags &= ~e_awakeFlag; - m_sleepTime = 0.0f; - m_linearVelocity.SetZero(); - m_angularVelocity = 0.0f; - m_force.SetZero(); - m_torque = 0.0f; - } -} - -inline bool b2Body::IsAwake() const -{ - return (m_flags & e_awakeFlag) == e_awakeFlag; -} - -inline bool b2Body::IsActive() const -{ - return (m_flags & e_activeFlag) == e_activeFlag; -} - -inline bool b2Body::IsFixedRotation() const -{ - return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; -} - -inline void b2Body::SetSleepingAllowed(bool flag) -{ - if (flag) - { - m_flags |= e_autoSleepFlag; - } - else - { - m_flags &= ~e_autoSleepFlag; - SetAwake(true); - } -} - -inline bool b2Body::IsSleepingAllowed() const -{ - return (m_flags & e_autoSleepFlag) == e_autoSleepFlag; -} - -inline b2Fixture* b2Body::GetFixtureList() -{ - return m_fixtureList; -} - -inline const b2Fixture* b2Body::GetFixtureList() const -{ - return m_fixtureList; -} - -inline b2JointEdge* b2Body::GetJointList() -{ - return m_jointList; -} - -inline const b2JointEdge* b2Body::GetJointList() const -{ - return m_jointList; -} - -inline b2ContactEdge* b2Body::GetContactList() -{ - return m_contactList; -} - -inline const b2ContactEdge* b2Body::GetContactList() const -{ - return m_contactList; -} - -inline b2Body* b2Body::GetNext() -{ - return m_next; -} - -inline const b2Body* b2Body::GetNext() const -{ - return m_next; -} - -inline void b2Body::SetUserData(void* data) -{ - m_userData = data; -} - -inline void* b2Body::GetUserData() const -{ - return m_userData; -} - -inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake) -{ - if (m_type != b2_dynamicBody) - { - return; - } - - if (wake && (m_flags & e_awakeFlag) == 0) - { - SetAwake(true); - } - - // Don't accumulate a force if the body is sleeping. - if (m_flags & e_awakeFlag) - { - m_force += force; - m_torque += b2Cross(point - m_sweep.c, force); - } -} - -inline void b2Body::ApplyForceToCenter(const b2Vec2& force, bool wake) -{ - if (m_type != b2_dynamicBody) - { - return; - } - - if (wake && (m_flags & e_awakeFlag) == 0) - { - SetAwake(true); - } - - // Don't accumulate a force if the body is sleeping - if (m_flags & e_awakeFlag) - { - m_force += force; - } -} - -inline void b2Body::ApplyTorque(float32 torque, bool wake) -{ - if (m_type != b2_dynamicBody) - { - return; - } - - if (wake && (m_flags & e_awakeFlag) == 0) - { - SetAwake(true); - } - - // Don't accumulate a force if the body is sleeping - if (m_flags & e_awakeFlag) - { - m_torque += torque; - } -} - -inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point, bool wake) -{ - if (m_type != b2_dynamicBody) - { - return; - } - - if (wake && (m_flags & e_awakeFlag) == 0) - { - SetAwake(true); - } - - // Don't accumulate velocity if the body is sleeping - if (m_flags & e_awakeFlag) - { - m_linearVelocity += m_invMass * impulse; - m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse); - } -} - -inline void b2Body::ApplyLinearImpulseToCenter(const b2Vec2& impulse, bool wake) -{ - if (m_type != b2_dynamicBody) - { - return; - } - - if (wake && (m_flags & e_awakeFlag) == 0) - { - SetAwake(true); - } - - // Don't accumulate velocity if the body is sleeping - if (m_flags & e_awakeFlag) - { - m_linearVelocity += m_invMass * impulse; - } -} - -inline void b2Body::ApplyAngularImpulse(float32 impulse, bool wake) -{ - if (m_type != b2_dynamicBody) - { - return; - } - - if (wake && (m_flags & e_awakeFlag) == 0) - { - SetAwake(true); - } - - // Don't accumulate velocity if the body is sleeping - if (m_flags & e_awakeFlag) - { - m_angularVelocity += m_invI * impulse; - } -} - -inline void b2Body::SynchronizeTransform() -{ - m_xf.q.Set(m_sweep.a); - m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); -} - -inline void b2Body::Advance(float32 alpha) -{ - // Advance to the new safe time. This doesn't sync the broad-phase. - m_sweep.Advance(alpha); - m_sweep.c = m_sweep.c0; - m_sweep.a = m_sweep.a0; - m_xf.q.Set(m_sweep.a); - m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); -} - -inline b2World* b2Body::GetWorld() -{ - return m_world; -} - -inline const b2World* b2Body::GetWorld() const -{ - return m_world; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2ContactManager.cpp b/src/libjin/3rdparty/Box2D/Dynamics/b2ContactManager.cpp deleted file mode 100644 index 051cc2f..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2ContactManager.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/b2ContactManager.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2WorldCallbacks.h" -#include "Box2D/Dynamics/Contacts/b2Contact.h" - -b2ContactFilter b2_defaultFilter; -b2ContactListener b2_defaultListener; - -b2ContactManager::b2ContactManager() -{ - m_contactList = nullptr; - m_contactCount = 0; - m_contactFilter = &b2_defaultFilter; - m_contactListener = &b2_defaultListener; - m_allocator = nullptr; -} - -void b2ContactManager::Destroy(b2Contact* c) -{ - b2Fixture* fixtureA = c->GetFixtureA(); - b2Fixture* fixtureB = c->GetFixtureB(); - b2Body* bodyA = fixtureA->GetBody(); - b2Body* bodyB = fixtureB->GetBody(); - - if (m_contactListener && c->IsTouching()) - { - m_contactListener->EndContact(c); - } - - // Remove from the world. - if (c->m_prev) - { - c->m_prev->m_next = c->m_next; - } - - if (c->m_next) - { - c->m_next->m_prev = c->m_prev; - } - - if (c == m_contactList) - { - m_contactList = c->m_next; - } - - // Remove from body 1 - if (c->m_nodeA.prev) - { - c->m_nodeA.prev->next = c->m_nodeA.next; - } - - if (c->m_nodeA.next) - { - c->m_nodeA.next->prev = c->m_nodeA.prev; - } - - if (&c->m_nodeA == bodyA->m_contactList) - { - bodyA->m_contactList = c->m_nodeA.next; - } - - // Remove from body 2 - if (c->m_nodeB.prev) - { - c->m_nodeB.prev->next = c->m_nodeB.next; - } - - if (c->m_nodeB.next) - { - c->m_nodeB.next->prev = c->m_nodeB.prev; - } - - if (&c->m_nodeB == bodyB->m_contactList) - { - bodyB->m_contactList = c->m_nodeB.next; - } - - // Call the factory. - b2Contact::Destroy(c, m_allocator); - --m_contactCount; -} - -// This is the top level collision call for the time step. Here -// all the narrow phase collision is processed for the world -// contact list. -void b2ContactManager::Collide() -{ - // Update awake contacts. - b2Contact* c = m_contactList; - while (c) - { - b2Fixture* fixtureA = c->GetFixtureA(); - b2Fixture* fixtureB = c->GetFixtureB(); - int32 indexA = c->GetChildIndexA(); - int32 indexB = c->GetChildIndexB(); - b2Body* bodyA = fixtureA->GetBody(); - b2Body* bodyB = fixtureB->GetBody(); - - // Is this contact flagged for filtering? - if (c->m_flags & b2Contact::e_filterFlag) - { - // Should these bodies collide? - if (bodyB->ShouldCollide(bodyA) == false) - { - b2Contact* cNuke = c; - c = cNuke->GetNext(); - Destroy(cNuke); - continue; - } - - // Check user filtering. - if (m_contactFilter && m_contactFilter->ShouldCollide(fixtureA, fixtureB) == false) - { - b2Contact* cNuke = c; - c = cNuke->GetNext(); - Destroy(cNuke); - continue; - } - - // Clear the filtering flag. - c->m_flags &= ~b2Contact::e_filterFlag; - } - - bool activeA = bodyA->IsAwake() && bodyA->m_type != b2_staticBody; - bool activeB = bodyB->IsAwake() && bodyB->m_type != b2_staticBody; - - // At least one body must be awake and it must be dynamic or kinematic. - if (activeA == false && activeB == false) - { - c = c->GetNext(); - continue; - } - - int32 proxyIdA = fixtureA->m_proxies[indexA].proxyId; - int32 proxyIdB = fixtureB->m_proxies[indexB].proxyId; - bool overlap = m_broadPhase.TestOverlap(proxyIdA, proxyIdB); - - // Here we destroy contacts that cease to overlap in the broad-phase. - if (overlap == false) - { - b2Contact* cNuke = c; - c = cNuke->GetNext(); - Destroy(cNuke); - continue; - } - - // The contact persists. - c->Update(m_contactListener); - c = c->GetNext(); - } -} - -void b2ContactManager::FindNewContacts() -{ - m_broadPhase.UpdatePairs(this); -} - -void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) -{ - b2FixtureProxy* proxyA = (b2FixtureProxy*)proxyUserDataA; - b2FixtureProxy* proxyB = (b2FixtureProxy*)proxyUserDataB; - - b2Fixture* fixtureA = proxyA->fixture; - b2Fixture* fixtureB = proxyB->fixture; - - int32 indexA = proxyA->childIndex; - int32 indexB = proxyB->childIndex; - - b2Body* bodyA = fixtureA->GetBody(); - b2Body* bodyB = fixtureB->GetBody(); - - // Are the fixtures on the same body? - if (bodyA == bodyB) - { - return; - } - - // TODO_ERIN use a hash table to remove a potential bottleneck when both - // bodies have a lot of contacts. - // Does a contact already exist? - b2ContactEdge* edge = bodyB->GetContactList(); - while (edge) - { - if (edge->other == bodyA) - { - b2Fixture* fA = edge->contact->GetFixtureA(); - b2Fixture* fB = edge->contact->GetFixtureB(); - int32 iA = edge->contact->GetChildIndexA(); - int32 iB = edge->contact->GetChildIndexB(); - - if (fA == fixtureA && fB == fixtureB && iA == indexA && iB == indexB) - { - // A contact already exists. - return; - } - - if (fA == fixtureB && fB == fixtureA && iA == indexB && iB == indexA) - { - // A contact already exists. - return; - } - } - - edge = edge->next; - } - - // Does a joint override collision? Is at least one body dynamic? - if (bodyB->ShouldCollide(bodyA) == false) - { - return; - } - - // Check user filtering. - if (m_contactFilter && m_contactFilter->ShouldCollide(fixtureA, fixtureB) == false) - { - return; - } - - // Call the factory. - b2Contact* c = b2Contact::Create(fixtureA, indexA, fixtureB, indexB, m_allocator); - if (c == nullptr) - { - return; - } - - // Contact creation may swap fixtures. - fixtureA = c->GetFixtureA(); - fixtureB = c->GetFixtureB(); - indexA = c->GetChildIndexA(); - indexB = c->GetChildIndexB(); - bodyA = fixtureA->GetBody(); - bodyB = fixtureB->GetBody(); - - // Insert into the world. - c->m_prev = nullptr; - c->m_next = m_contactList; - if (m_contactList != nullptr) - { - m_contactList->m_prev = c; - } - m_contactList = c; - - // Connect to island graph. - - // Connect to body A - c->m_nodeA.contact = c; - c->m_nodeA.other = bodyB; - - c->m_nodeA.prev = nullptr; - c->m_nodeA.next = bodyA->m_contactList; - if (bodyA->m_contactList != nullptr) - { - bodyA->m_contactList->prev = &c->m_nodeA; - } - bodyA->m_contactList = &c->m_nodeA; - - // Connect to body B - c->m_nodeB.contact = c; - c->m_nodeB.other = bodyA; - - c->m_nodeB.prev = nullptr; - c->m_nodeB.next = bodyB->m_contactList; - if (bodyB->m_contactList != nullptr) - { - bodyB->m_contactList->prev = &c->m_nodeB; - } - bodyB->m_contactList = &c->m_nodeB; - - // Wake up the bodies - if (fixtureA->IsSensor() == false && fixtureB->IsSensor() == false) - { - bodyA->SetAwake(true); - bodyB->SetAwake(true); - } - - ++m_contactCount; -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2ContactManager.h b/src/libjin/3rdparty/Box2D/Dynamics/b2ContactManager.h deleted file mode 100644 index 4c969e7..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2ContactManager.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_CONTACT_MANAGER_H -#define B2_CONTACT_MANAGER_H - -#include "Box2D/Collision/b2BroadPhase.h" - -class b2Contact; -class b2ContactFilter; -class b2ContactListener; -class b2BlockAllocator; - -// Delegate of b2World. -class b2ContactManager -{ -public: - b2ContactManager(); - - // Broad-phase callback. - void AddPair(void* proxyUserDataA, void* proxyUserDataB); - - void FindNewContacts(); - - void Destroy(b2Contact* c); - - void Collide(); - - b2BroadPhase m_broadPhase; - b2Contact* m_contactList; - int32 m_contactCount; - b2ContactFilter* m_contactFilter; - b2ContactListener* m_contactListener; - b2BlockAllocator* m_allocator; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2Fixture.cpp b/src/libjin/3rdparty/Box2D/Dynamics/b2Fixture.cpp deleted file mode 100644 index 956b485..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2Fixture.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/Contacts/b2Contact.h" -#include "Box2D/Dynamics/b2World.h" -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/b2BroadPhase.h" -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Common/b2BlockAllocator.h" - -b2Fixture::b2Fixture() -{ - m_userData = nullptr; - m_body = nullptr; - m_next = nullptr; - m_proxies = nullptr; - m_proxyCount = 0; - m_shape = nullptr; - m_density = 0.0f; -} - -void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def) -{ - m_userData = def->userData; - m_friction = def->friction; - m_restitution = def->restitution; - - m_body = body; - m_next = nullptr; - - m_filter = def->filter; - - m_isSensor = def->isSensor; - - m_shape = def->shape->Clone(allocator); - - // Reserve proxy space - int32 childCount = m_shape->GetChildCount(); - m_proxies = (b2FixtureProxy*)allocator->Allocate(childCount * sizeof(b2FixtureProxy)); - for (int32 i = 0; i < childCount; ++i) - { - m_proxies[i].fixture = nullptr; - m_proxies[i].proxyId = b2BroadPhase::e_nullProxy; - } - m_proxyCount = 0; - - m_density = def->density; -} - -void b2Fixture::Destroy(b2BlockAllocator* allocator) -{ - // The proxies must be destroyed before calling this. - b2Assert(m_proxyCount == 0); - - // Free the proxy array. - int32 childCount = m_shape->GetChildCount(); - allocator->Free(m_proxies, childCount * sizeof(b2FixtureProxy)); - m_proxies = nullptr; - - // Free the child shape. - switch (m_shape->m_type) - { - case b2Shape::e_circle: - { - b2CircleShape* s = (b2CircleShape*)m_shape; - s->~b2CircleShape(); - allocator->Free(s, sizeof(b2CircleShape)); - } - break; - - case b2Shape::e_edge: - { - b2EdgeShape* s = (b2EdgeShape*)m_shape; - s->~b2EdgeShape(); - allocator->Free(s, sizeof(b2EdgeShape)); - } - break; - - case b2Shape::e_polygon: - { - b2PolygonShape* s = (b2PolygonShape*)m_shape; - s->~b2PolygonShape(); - allocator->Free(s, sizeof(b2PolygonShape)); - } - break; - - case b2Shape::e_chain: - { - b2ChainShape* s = (b2ChainShape*)m_shape; - s->~b2ChainShape(); - allocator->Free(s, sizeof(b2ChainShape)); - } - break; - - default: - b2Assert(false); - break; - } - - m_shape = nullptr; -} - -void b2Fixture::CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf) -{ - b2Assert(m_proxyCount == 0); - - // Create proxies in the broad-phase. - m_proxyCount = m_shape->GetChildCount(); - - for (int32 i = 0; i < m_proxyCount; ++i) - { - b2FixtureProxy* proxy = m_proxies + i; - m_shape->ComputeAABB(&proxy->aabb, xf, i); - proxy->proxyId = broadPhase->CreateProxy(proxy->aabb, proxy); - proxy->fixture = this; - proxy->childIndex = i; - } -} - -void b2Fixture::DestroyProxies(b2BroadPhase* broadPhase) -{ - // Destroy proxies in the broad-phase. - for (int32 i = 0; i < m_proxyCount; ++i) - { - b2FixtureProxy* proxy = m_proxies + i; - broadPhase->DestroyProxy(proxy->proxyId); - proxy->proxyId = b2BroadPhase::e_nullProxy; - } - - m_proxyCount = 0; -} - -void b2Fixture::Synchronize(b2BroadPhase* broadPhase, const b2Transform& transform1, const b2Transform& transform2) -{ - if (m_proxyCount == 0) - { - return; - } - - for (int32 i = 0; i < m_proxyCount; ++i) - { - b2FixtureProxy* proxy = m_proxies + i; - - // Compute an AABB that covers the swept shape (may miss some rotation effect). - b2AABB aabb1, aabb2; - m_shape->ComputeAABB(&aabb1, transform1, proxy->childIndex); - m_shape->ComputeAABB(&aabb2, transform2, proxy->childIndex); - - proxy->aabb.Combine(aabb1, aabb2); - - b2Vec2 displacement = transform2.p - transform1.p; - - broadPhase->MoveProxy(proxy->proxyId, proxy->aabb, displacement); - } -} - -void b2Fixture::SetFilterData(const b2Filter& filter) -{ - m_filter = filter; - - Refilter(); -} - -void b2Fixture::Refilter() -{ - if (m_body == nullptr) - { - return; - } - - // Flag associated contacts for filtering. - b2ContactEdge* edge = m_body->GetContactList(); - while (edge) - { - b2Contact* contact = edge->contact; - b2Fixture* fixtureA = contact->GetFixtureA(); - b2Fixture* fixtureB = contact->GetFixtureB(); - if (fixtureA == this || fixtureB == this) - { - contact->FlagForFiltering(); - } - - edge = edge->next; - } - - b2World* world = m_body->GetWorld(); - - if (world == nullptr) - { - return; - } - - // Touch each proxy so that new pairs may be created - b2BroadPhase* broadPhase = &world->m_contactManager.m_broadPhase; - for (int32 i = 0; i < m_proxyCount; ++i) - { - broadPhase->TouchProxy(m_proxies[i].proxyId); - } -} - -void b2Fixture::SetSensor(bool sensor) -{ - if (sensor != m_isSensor) - { - m_body->SetAwake(true); - m_isSensor = sensor; - } -} - -void b2Fixture::Dump(int32 bodyIndex) -{ - b2Log(" b2FixtureDef fd;\n"); - b2Log(" fd.friction = %.15lef;\n", m_friction); - b2Log(" fd.restitution = %.15lef;\n", m_restitution); - b2Log(" fd.density = %.15lef;\n", m_density); - b2Log(" fd.isSensor = bool(%d);\n", m_isSensor); - b2Log(" fd.filter.categoryBits = uint16(%d);\n", m_filter.categoryBits); - b2Log(" fd.filter.maskBits = uint16(%d);\n", m_filter.maskBits); - b2Log(" fd.filter.groupIndex = int16(%d);\n", m_filter.groupIndex); - - switch (m_shape->m_type) - { - case b2Shape::e_circle: - { - b2CircleShape* s = (b2CircleShape*)m_shape; - b2Log(" b2CircleShape shape;\n"); - b2Log(" shape.m_radius = %.15lef;\n", s->m_radius); - b2Log(" shape.m_p.Set(%.15lef, %.15lef);\n", s->m_p.x, s->m_p.y); - } - break; - - case b2Shape::e_edge: - { - b2EdgeShape* s = (b2EdgeShape*)m_shape; - b2Log(" b2EdgeShape shape;\n"); - b2Log(" shape.m_radius = %.15lef;\n", s->m_radius); - b2Log(" shape.m_vertex0.Set(%.15lef, %.15lef);\n", s->m_vertex0.x, s->m_vertex0.y); - b2Log(" shape.m_vertex1.Set(%.15lef, %.15lef);\n", s->m_vertex1.x, s->m_vertex1.y); - b2Log(" shape.m_vertex2.Set(%.15lef, %.15lef);\n", s->m_vertex2.x, s->m_vertex2.y); - b2Log(" shape.m_vertex3.Set(%.15lef, %.15lef);\n", s->m_vertex3.x, s->m_vertex3.y); - b2Log(" shape.m_hasVertex0 = bool(%d);\n", s->m_hasVertex0); - b2Log(" shape.m_hasVertex3 = bool(%d);\n", s->m_hasVertex3); - } - break; - - case b2Shape::e_polygon: - { - b2PolygonShape* s = (b2PolygonShape*)m_shape; - b2Log(" b2PolygonShape shape;\n"); - b2Log(" b2Vec2 vs[%d];\n", b2_maxPolygonVertices); - for (int32 i = 0; i < s->m_count; ++i) - { - b2Log(" vs[%d].Set(%.15lef, %.15lef);\n", i, s->m_vertices[i].x, s->m_vertices[i].y); - } - b2Log(" shape.Set(vs, %d);\n", s->m_count); - } - break; - - case b2Shape::e_chain: - { - b2ChainShape* s = (b2ChainShape*)m_shape; - b2Log(" b2ChainShape shape;\n"); - b2Log(" b2Vec2 vs[%d];\n", s->m_count); - for (int32 i = 0; i < s->m_count; ++i) - { - b2Log(" vs[%d].Set(%.15lef, %.15lef);\n", i, s->m_vertices[i].x, s->m_vertices[i].y); - } - b2Log(" shape.CreateChain(vs, %d);\n", s->m_count); - b2Log(" shape.m_prevVertex.Set(%.15lef, %.15lef);\n", s->m_prevVertex.x, s->m_prevVertex.y); - b2Log(" shape.m_nextVertex.Set(%.15lef, %.15lef);\n", s->m_nextVertex.x, s->m_nextVertex.y); - b2Log(" shape.m_hasPrevVertex = bool(%d);\n", s->m_hasPrevVertex); - b2Log(" shape.m_hasNextVertex = bool(%d);\n", s->m_hasNextVertex); - } - break; - - default: - return; - } - - b2Log("\n"); - b2Log(" fd.shape = &shape;\n"); - b2Log("\n"); - b2Log(" bodies[%d]->CreateFixture(&fd);\n", bodyIndex); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2Fixture.h b/src/libjin/3rdparty/Box2D/Dynamics/b2Fixture.h deleted file mode 100644 index 9f7a8aa..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2Fixture.h +++ /dev/null @@ -1,345 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_FIXTURE_H -#define B2_FIXTURE_H - -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/Shapes/b2Shape.h" - -class b2BlockAllocator; -class b2Body; -class b2BroadPhase; -class b2Fixture; - -/// This holds contact filtering data. -struct b2Filter -{ - b2Filter() - { - categoryBits = 0x0001; - maskBits = 0xFFFF; - groupIndex = 0; - } - - /// The collision category bits. Normally you would just set one bit. - uint16 categoryBits; - - /// The collision mask bits. This states the categories that this - /// shape would accept for collision. - uint16 maskBits; - - /// Collision groups allow a certain group of objects to never collide (negative) - /// or always collide (positive). Zero means no collision group. Non-zero group - /// filtering always wins against the mask bits. - int16 groupIndex; -}; - -/// A fixture definition is used to create a fixture. This class defines an -/// abstract fixture definition. You can reuse fixture definitions safely. -struct b2FixtureDef -{ - /// The constructor sets the default fixture definition values. - b2FixtureDef() - { - shape = nullptr; - userData = nullptr; - friction = 0.2f; - restitution = 0.0f; - density = 0.0f; - isSensor = false; - } - - /// The shape, this must be set. The shape will be cloned, so you - /// can create the shape on the stack. - const b2Shape* shape; - - /// Use this to store application specific fixture data. - void* userData; - - /// The friction coefficient, usually in the range [0,1]. - float32 friction; - - /// The restitution (elasticity) usually in the range [0,1]. - float32 restitution; - - /// The density, usually in kg/m^2. - float32 density; - - /// A sensor shape collects contact information but never generates a collision - /// response. - bool isSensor; - - /// Contact filtering data. - b2Filter filter; -}; - -/// This proxy is used internally to connect fixtures to the broad-phase. -struct b2FixtureProxy -{ - b2AABB aabb; - b2Fixture* fixture; - int32 childIndex; - int32 proxyId; -}; - -/// A fixture is used to attach a shape to a body for collision detection. A fixture -/// inherits its transform from its parent. Fixtures hold additional non-geometric data -/// such as friction, collision filters, etc. -/// Fixtures are created via b2Body::CreateFixture. -/// @warning you cannot reuse fixtures. -class b2Fixture -{ -public: - /// Get the type of the child shape. You can use this to down cast to the concrete shape. - /// @return the shape type. - b2Shape::Type GetType() const; - - /// Get the child shape. You can modify the child shape, however you should not change the - /// number of vertices because this will crash some collision caching mechanisms. - /// Manipulating the shape may lead to non-physical behavior. - b2Shape* GetShape(); - const b2Shape* GetShape() const; - - /// Set if this fixture is a sensor. - void SetSensor(bool sensor); - - /// Is this fixture a sensor (non-solid)? - /// @return the true if the shape is a sensor. - bool IsSensor() const; - - /// Set the contact filtering data. This will not update contacts until the next time - /// step when either parent body is active and awake. - /// This automatically calls Refilter. - void SetFilterData(const b2Filter& filter); - - /// Get the contact filtering data. - const b2Filter& GetFilterData() const; - - /// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide. - void Refilter(); - - /// Get the parent body of this fixture. This is nullptr if the fixture is not attached. - /// @return the parent body. - b2Body* GetBody(); - const b2Body* GetBody() const; - - /// Get the next fixture in the parent body's fixture list. - /// @return the next shape. - b2Fixture* GetNext(); - const b2Fixture* GetNext() const; - - /// Get the user data that was assigned in the fixture definition. Use this to - /// store your application specific data. - void* GetUserData() const; - - /// Set the user data. Use this to store your application specific data. - void SetUserData(void* data); - - /// Test a point for containment in this fixture. - /// @param p a point in world coordinates. - bool TestPoint(const b2Vec2& p) const; - - /// Cast a ray against this shape. - /// @param output the ray-cast results. - /// @param input the ray-cast input parameters. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const; - - /// Get the mass data for this fixture. The mass data is based on the density and - /// the shape. The rotational inertia is about the shape's origin. This operation - /// may be expensive. - void GetMassData(b2MassData* massData) const; - - /// Set the density of this fixture. This will _not_ automatically adjust the mass - /// of the body. You must call b2Body::ResetMassData to update the body's mass. - void SetDensity(float32 density); - - /// Get the density of this fixture. - float32 GetDensity() const; - - /// Get the coefficient of friction. - float32 GetFriction() const; - - /// Set the coefficient of friction. This will _not_ change the friction of - /// existing contacts. - void SetFriction(float32 friction); - - /// Get the coefficient of restitution. - float32 GetRestitution() const; - - /// Set the coefficient of restitution. This will _not_ change the restitution of - /// existing contacts. - void SetRestitution(float32 restitution); - - /// Get the fixture's AABB. This AABB may be enlarge and/or stale. - /// If you need a more accurate AABB, compute it using the shape and - /// the body transform. - const b2AABB& GetAABB(int32 childIndex) const; - - /// Dump this fixture to the log file. - void Dump(int32 bodyIndex); - -protected: - - friend class b2Body; - friend class b2World; - friend class b2Contact; - friend class b2ContactManager; - - b2Fixture(); - - // We need separation create/destroy functions from the constructor/destructor because - // the destructor cannot access the allocator (no destructor arguments allowed by C++). - void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def); - void Destroy(b2BlockAllocator* allocator); - - // These support body activation/deactivation. - void CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf); - void DestroyProxies(b2BroadPhase* broadPhase); - - void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2); - - float32 m_density; - - b2Fixture* m_next; - b2Body* m_body; - - b2Shape* m_shape; - - float32 m_friction; - float32 m_restitution; - - b2FixtureProxy* m_proxies; - int32 m_proxyCount; - - b2Filter m_filter; - - bool m_isSensor; - - void* m_userData; -}; - -inline b2Shape::Type b2Fixture::GetType() const -{ - return m_shape->GetType(); -} - -inline b2Shape* b2Fixture::GetShape() -{ - return m_shape; -} - -inline const b2Shape* b2Fixture::GetShape() const -{ - return m_shape; -} - -inline bool b2Fixture::IsSensor() const -{ - return m_isSensor; -} - -inline const b2Filter& b2Fixture::GetFilterData() const -{ - return m_filter; -} - -inline void* b2Fixture::GetUserData() const -{ - return m_userData; -} - -inline void b2Fixture::SetUserData(void* data) -{ - m_userData = data; -} - -inline b2Body* b2Fixture::GetBody() -{ - return m_body; -} - -inline const b2Body* b2Fixture::GetBody() const -{ - return m_body; -} - -inline b2Fixture* b2Fixture::GetNext() -{ - return m_next; -} - -inline const b2Fixture* b2Fixture::GetNext() const -{ - return m_next; -} - -inline void b2Fixture::SetDensity(float32 density) -{ - b2Assert(b2IsValid(density) && density >= 0.0f); - m_density = density; -} - -inline float32 b2Fixture::GetDensity() const -{ - return m_density; -} - -inline float32 b2Fixture::GetFriction() const -{ - return m_friction; -} - -inline void b2Fixture::SetFriction(float32 friction) -{ - m_friction = friction; -} - -inline float32 b2Fixture::GetRestitution() const -{ - return m_restitution; -} - -inline void b2Fixture::SetRestitution(float32 restitution) -{ - m_restitution = restitution; -} - -inline bool b2Fixture::TestPoint(const b2Vec2& p) const -{ - return m_shape->TestPoint(m_body->GetTransform(), p); -} - -inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, int32 childIndex) const -{ - return m_shape->RayCast(output, input, m_body->GetTransform(), childIndex); -} - -inline void b2Fixture::GetMassData(b2MassData* massData) const -{ - m_shape->ComputeMass(massData, m_density); -} - -inline const b2AABB& b2Fixture::GetAABB(int32 childIndex) const -{ - b2Assert(0 <= childIndex && childIndex < m_proxyCount); - return m_proxies[childIndex].aabb; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2Island.cpp b/src/libjin/3rdparty/Box2D/Dynamics/b2Island.cpp deleted file mode 100644 index dd19a8f..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2Island.cpp +++ /dev/null @@ -1,539 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Collision/b2Distance.h" -#include "Box2D/Dynamics/b2Island.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2World.h" -#include "Box2D/Dynamics/Contacts/b2Contact.h" -#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" -#include "Box2D/Dynamics/Joints/b2Joint.h" -#include "Box2D/Common/b2StackAllocator.h" -#include "Box2D/Common/b2Timer.h" - -/* -Position Correction Notes -========================= -I tried the several algorithms for position correction of the 2D revolute joint. -I looked at these systems: -- simple pendulum (1m diameter sphere on massless 5m stick) with initial angular velocity of 100 rad/s. -- suspension bridge with 30 1m long planks of length 1m. -- multi-link chain with 30 1m long links. - -Here are the algorithms: - -Baumgarte - A fraction of the position error is added to the velocity error. There is no -separate position solver. - -Pseudo Velocities - After the velocity solver and position integration, -the position error, Jacobian, and effective mass are recomputed. Then -the velocity constraints are solved with pseudo velocities and a fraction -of the position error is added to the pseudo velocity error. The pseudo -velocities are initialized to zero and there is no warm-starting. After -the position solver, the pseudo velocities are added to the positions. -This is also called the First Order World method or the Position LCP method. - -Modified Nonlinear Gauss-Seidel (NGS) - Like Pseudo Velocities except the -position error is re-computed for each constraint and the positions are updated -after the constraint is solved. The radius vectors (aka Jacobians) are -re-computed too (otherwise the algorithm has horrible instability). The pseudo -velocity states are not needed because they are effectively zero at the beginning -of each iteration. Since we have the current position error, we allow the -iterations to terminate early if the error becomes smaller than b2_linearSlop. - -Full NGS or just NGS - Like Modified NGS except the effective mass are re-computed -each time a constraint is solved. - -Here are the results: -Baumgarte - this is the cheapest algorithm but it has some stability problems, -especially with the bridge. The chain links separate easily close to the root -and they jitter as they struggle to pull together. This is one of the most common -methods in the field. The big drawback is that the position correction artificially -affects the momentum, thus leading to instabilities and false bounce. I used a -bias factor of 0.2. A larger bias factor makes the bridge less stable, a smaller -factor makes joints and contacts more spongy. - -Pseudo Velocities - the is more stable than the Baumgarte method. The bridge is -stable. However, joints still separate with large angular velocities. Drag the -simple pendulum in a circle quickly and the joint will separate. The chain separates -easily and does not recover. I used a bias factor of 0.2. A larger value lead to -the bridge collapsing when a heavy cube drops on it. - -Modified NGS - this algorithm is better in some ways than Baumgarte and Pseudo -Velocities, but in other ways it is worse. The bridge and chain are much more -stable, but the simple pendulum goes unstable at high angular velocities. - -Full NGS - stable in all tests. The joints display good stiffness. The bridge -still sags, but this is better than infinite forces. - -Recommendations -Pseudo Velocities are not really worthwhile because the bridge and chain cannot -recover from joint separation. In other cases the benefit over Baumgarte is small. - -Modified NGS is not a robust method for the revolute joint due to the violent -instability seen in the simple pendulum. Perhaps it is viable with other constraint -types, especially scalar constraints where the effective mass is a scalar. - -This leaves Baumgarte and Full NGS. Baumgarte has small, but manageable instabilities -and is very fast. I don't think we can escape Baumgarte, especially in highly -demanding cases where high constraint fidelity is not needed. - -Full NGS is robust and easy on the eyes. I recommend this as an option for -higher fidelity simulation and certainly for suspension bridges and long chains. -Full NGS might be a good choice for ragdolls, especially motorized ragdolls where -joint separation can be problematic. The number of NGS iterations can be reduced -for better performance without harming robustness much. - -Each joint in a can be handled differently in the position solver. So I recommend -a system where the user can select the algorithm on a per joint basis. I would -probably default to the slower Full NGS and let the user select the faster -Baumgarte method in performance critical scenarios. -*/ - -/* -Cache Performance - -The Box2D solvers are dominated by cache misses. Data structures are designed -to increase the number of cache hits. Much of misses are due to random access -to body data. The constraint structures are iterated over linearly, which leads -to few cache misses. - -The bodies are not accessed during iteration. Instead read only data, such as -the mass values are stored with the constraints. The mutable data are the constraint -impulses and the bodies velocities/positions. The impulses are held inside the -constraint structures. The body velocities/positions are held in compact, temporary -arrays to increase the number of cache hits. Linear and angular velocity are -stored in a single array since multiple arrays lead to multiple misses. -*/ - -/* -2D Rotation - -R = [cos(theta) -sin(theta)] - [sin(theta) cos(theta) ] - -thetaDot = omega - -Let q1 = cos(theta), q2 = sin(theta). -R = [q1 -q2] - [q2 q1] - -q1Dot = -thetaDot * q2 -q2Dot = thetaDot * q1 - -q1_new = q1_old - dt * w * q2 -q2_new = q2_old + dt * w * q1 -then normalize. - -This might be faster than computing sin+cos. -However, we can compute sin+cos of the same angle fast. -*/ - -b2Island::b2Island( - int32 bodyCapacity, - int32 contactCapacity, - int32 jointCapacity, - b2StackAllocator* allocator, - b2ContactListener* listener) -{ - m_bodyCapacity = bodyCapacity; - m_contactCapacity = contactCapacity; - m_jointCapacity = jointCapacity; - m_bodyCount = 0; - m_contactCount = 0; - m_jointCount = 0; - - m_allocator = allocator; - m_listener = listener; - - m_bodies = (b2Body**)m_allocator->Allocate(bodyCapacity * sizeof(b2Body*)); - m_contacts = (b2Contact**)m_allocator->Allocate(contactCapacity * sizeof(b2Contact*)); - m_joints = (b2Joint**)m_allocator->Allocate(jointCapacity * sizeof(b2Joint*)); - - m_velocities = (b2Velocity*)m_allocator->Allocate(m_bodyCapacity * sizeof(b2Velocity)); - m_positions = (b2Position*)m_allocator->Allocate(m_bodyCapacity * sizeof(b2Position)); -} - -b2Island::~b2Island() -{ - // Warning: the order should reverse the constructor order. - m_allocator->Free(m_positions); - m_allocator->Free(m_velocities); - m_allocator->Free(m_joints); - m_allocator->Free(m_contacts); - m_allocator->Free(m_bodies); -} - -void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& gravity, bool allowSleep) -{ - b2Timer timer; - - float32 h = step.dt; - - // Integrate velocities and apply damping. Initialize the body state. - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Body* b = m_bodies[i]; - - b2Vec2 c = b->m_sweep.c; - float32 a = b->m_sweep.a; - b2Vec2 v = b->m_linearVelocity; - float32 w = b->m_angularVelocity; - - // Store positions for continuous collision. - b->m_sweep.c0 = b->m_sweep.c; - b->m_sweep.a0 = b->m_sweep.a; - - if (b->m_type == b2_dynamicBody) - { - // Integrate velocities. - v += h * (b->m_gravityScale * gravity + b->m_invMass * b->m_force); - w += h * b->m_invI * b->m_torque; - - // Apply damping. - // ODE: dv/dt + c * v = 0 - // Solution: v(t) = v0 * exp(-c * t) - // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt) - // v2 = exp(-c * dt) * v1 - // Pade approximation: - // v2 = v1 * 1 / (1 + c * dt) - v *= 1.0f / (1.0f + h * b->m_linearDamping); - w *= 1.0f / (1.0f + h * b->m_angularDamping); - } - - m_positions[i].c = c; - m_positions[i].a = a; - m_velocities[i].v = v; - m_velocities[i].w = w; - } - - timer.Reset(); - - // Solver data - b2SolverData solverData; - solverData.step = step; - solverData.positions = m_positions; - solverData.velocities = m_velocities; - - // Initialize velocity constraints. - b2ContactSolverDef contactSolverDef; - contactSolverDef.step = step; - contactSolverDef.contacts = m_contacts; - contactSolverDef.count = m_contactCount; - contactSolverDef.positions = m_positions; - contactSolverDef.velocities = m_velocities; - contactSolverDef.allocator = m_allocator; - - b2ContactSolver contactSolver(&contactSolverDef); - contactSolver.InitializeVelocityConstraints(); - - if (step.warmStarting) - { - contactSolver.WarmStart(); - } - - for (int32 i = 0; i < m_jointCount; ++i) - { - m_joints[i]->InitVelocityConstraints(solverData); - } - - profile->solveInit = timer.GetMilliseconds(); - - // Solve velocity constraints - timer.Reset(); - for (int32 i = 0; i < step.velocityIterations; ++i) - { - for (int32 j = 0; j < m_jointCount; ++j) - { - m_joints[j]->SolveVelocityConstraints(solverData); - } - - contactSolver.SolveVelocityConstraints(); - } - - // Store impulses for warm starting - contactSolver.StoreImpulses(); - profile->solveVelocity = timer.GetMilliseconds(); - - // Integrate positions - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Vec2 c = m_positions[i].c; - float32 a = m_positions[i].a; - b2Vec2 v = m_velocities[i].v; - float32 w = m_velocities[i].w; - - // Check for large velocities - b2Vec2 translation = h * v; - if (b2Dot(translation, translation) > b2_maxTranslationSquared) - { - float32 ratio = b2_maxTranslation / translation.Length(); - v *= ratio; - } - - float32 rotation = h * w; - if (rotation * rotation > b2_maxRotationSquared) - { - float32 ratio = b2_maxRotation / b2Abs(rotation); - w *= ratio; - } - - // Integrate - c += h * v; - a += h * w; - - m_positions[i].c = c; - m_positions[i].a = a; - m_velocities[i].v = v; - m_velocities[i].w = w; - } - - // Solve position constraints - timer.Reset(); - bool positionSolved = false; - for (int32 i = 0; i < step.positionIterations; ++i) - { - bool contactsOkay = contactSolver.SolvePositionConstraints(); - - bool jointsOkay = true; - for (int32 j = 0; j < m_jointCount; ++j) - { - bool jointOkay = m_joints[j]->SolvePositionConstraints(solverData); - jointsOkay = jointsOkay && jointOkay; - } - - if (contactsOkay && jointsOkay) - { - // Exit early if the position errors are small. - positionSolved = true; - break; - } - } - - // Copy state buffers back to the bodies - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Body* body = m_bodies[i]; - body->m_sweep.c = m_positions[i].c; - body->m_sweep.a = m_positions[i].a; - body->m_linearVelocity = m_velocities[i].v; - body->m_angularVelocity = m_velocities[i].w; - body->SynchronizeTransform(); - } - - profile->solvePosition = timer.GetMilliseconds(); - - Report(contactSolver.m_velocityConstraints); - - if (allowSleep) - { - float32 minSleepTime = b2_maxFloat; - - const float32 linTolSqr = b2_linearSleepTolerance * b2_linearSleepTolerance; - const float32 angTolSqr = b2_angularSleepTolerance * b2_angularSleepTolerance; - - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Body* b = m_bodies[i]; - if (b->GetType() == b2_staticBody) - { - continue; - } - - if ((b->m_flags & b2Body::e_autoSleepFlag) == 0 || - b->m_angularVelocity * b->m_angularVelocity > angTolSqr || - b2Dot(b->m_linearVelocity, b->m_linearVelocity) > linTolSqr) - { - b->m_sleepTime = 0.0f; - minSleepTime = 0.0f; - } - else - { - b->m_sleepTime += h; - minSleepTime = b2Min(minSleepTime, b->m_sleepTime); - } - } - - if (minSleepTime >= b2_timeToSleep && positionSolved) - { - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Body* b = m_bodies[i]; - b->SetAwake(false); - } - } - } -} - -void b2Island::SolveTOI(const b2TimeStep& subStep, int32 toiIndexA, int32 toiIndexB) -{ - b2Assert(toiIndexA < m_bodyCount); - b2Assert(toiIndexB < m_bodyCount); - - // Initialize the body state. - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Body* b = m_bodies[i]; - m_positions[i].c = b->m_sweep.c; - m_positions[i].a = b->m_sweep.a; - m_velocities[i].v = b->m_linearVelocity; - m_velocities[i].w = b->m_angularVelocity; - } - - b2ContactSolverDef contactSolverDef; - contactSolverDef.contacts = m_contacts; - contactSolverDef.count = m_contactCount; - contactSolverDef.allocator = m_allocator; - contactSolverDef.step = subStep; - contactSolverDef.positions = m_positions; - contactSolverDef.velocities = m_velocities; - b2ContactSolver contactSolver(&contactSolverDef); - - // Solve position constraints. - for (int32 i = 0; i < subStep.positionIterations; ++i) - { - bool contactsOkay = contactSolver.SolveTOIPositionConstraints(toiIndexA, toiIndexB); - if (contactsOkay) - { - break; - } - } - -#if 0 - // Is the new position really safe? - for (int32 i = 0; i < m_contactCount; ++i) - { - b2Contact* c = m_contacts[i]; - b2Fixture* fA = c->GetFixtureA(); - b2Fixture* fB = c->GetFixtureB(); - - b2Body* bA = fA->GetBody(); - b2Body* bB = fB->GetBody(); - - int32 indexA = c->GetChildIndexA(); - int32 indexB = c->GetChildIndexB(); - - b2DistanceInput input; - input.proxyA.Set(fA->GetShape(), indexA); - input.proxyB.Set(fB->GetShape(), indexB); - input.transformA = bA->GetTransform(); - input.transformB = bB->GetTransform(); - input.useRadii = false; - - b2DistanceOutput output; - b2SimplexCache cache; - cache.count = 0; - b2Distance(&output, &cache, &input); - - if (output.distance == 0 || cache.count == 3) - { - cache.count += 0; - } - } -#endif - - // Leap of faith to new safe state. - m_bodies[toiIndexA]->m_sweep.c0 = m_positions[toiIndexA].c; - m_bodies[toiIndexA]->m_sweep.a0 = m_positions[toiIndexA].a; - m_bodies[toiIndexB]->m_sweep.c0 = m_positions[toiIndexB].c; - m_bodies[toiIndexB]->m_sweep.a0 = m_positions[toiIndexB].a; - - // No warm starting is needed for TOI events because warm - // starting impulses were applied in the discrete solver. - contactSolver.InitializeVelocityConstraints(); - - // Solve velocity constraints. - for (int32 i = 0; i < subStep.velocityIterations; ++i) - { - contactSolver.SolveVelocityConstraints(); - } - - // Don't store the TOI contact forces for warm starting - // because they can be quite large. - - float32 h = subStep.dt; - - // Integrate positions - for (int32 i = 0; i < m_bodyCount; ++i) - { - b2Vec2 c = m_positions[i].c; - float32 a = m_positions[i].a; - b2Vec2 v = m_velocities[i].v; - float32 w = m_velocities[i].w; - - // Check for large velocities - b2Vec2 translation = h * v; - if (b2Dot(translation, translation) > b2_maxTranslationSquared) - { - float32 ratio = b2_maxTranslation / translation.Length(); - v *= ratio; - } - - float32 rotation = h * w; - if (rotation * rotation > b2_maxRotationSquared) - { - float32 ratio = b2_maxRotation / b2Abs(rotation); - w *= ratio; - } - - // Integrate - c += h * v; - a += h * w; - - m_positions[i].c = c; - m_positions[i].a = a; - m_velocities[i].v = v; - m_velocities[i].w = w; - - // Sync bodies - b2Body* body = m_bodies[i]; - body->m_sweep.c = c; - body->m_sweep.a = a; - body->m_linearVelocity = v; - body->m_angularVelocity = w; - body->SynchronizeTransform(); - } - - Report(contactSolver.m_velocityConstraints); -} - -void b2Island::Report(const b2ContactVelocityConstraint* constraints) -{ - if (m_listener == nullptr) - { - return; - } - - for (int32 i = 0; i < m_contactCount; ++i) - { - b2Contact* c = m_contacts[i]; - - const b2ContactVelocityConstraint* vc = constraints + i; - - b2ContactImpulse impulse; - impulse.count = vc->pointCount; - for (int32 j = 0; j < vc->pointCount; ++j) - { - impulse.normalImpulses[j] = vc->points[j].normalImpulse; - impulse.tangentImpulses[j] = vc->points[j].tangentImpulse; - } - - m_listener->PostSolve(c, &impulse); - } -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2Island.h b/src/libjin/3rdparty/Box2D/Dynamics/b2Island.h deleted file mode 100644 index 68f6d4b..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2Island.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_ISLAND_H -#define B2_ISLAND_H - -#include "Box2D/Common/b2Math.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -class b2Contact; -class b2Joint; -class b2StackAllocator; -class b2ContactListener; -struct b2ContactVelocityConstraint; -struct b2Profile; - -/// This is an internal class. -class b2Island -{ -public: - b2Island(int32 bodyCapacity, int32 contactCapacity, int32 jointCapacity, - b2StackAllocator* allocator, b2ContactListener* listener); - ~b2Island(); - - void Clear() - { - m_bodyCount = 0; - m_contactCount = 0; - m_jointCount = 0; - } - - void Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& gravity, bool allowSleep); - - void SolveTOI(const b2TimeStep& subStep, int32 toiIndexA, int32 toiIndexB); - - void Add(b2Body* body) - { - b2Assert(m_bodyCount < m_bodyCapacity); - body->m_islandIndex = m_bodyCount; - m_bodies[m_bodyCount] = body; - ++m_bodyCount; - } - - void Add(b2Contact* contact) - { - b2Assert(m_contactCount < m_contactCapacity); - m_contacts[m_contactCount++] = contact; - } - - void Add(b2Joint* joint) - { - b2Assert(m_jointCount < m_jointCapacity); - m_joints[m_jointCount++] = joint; - } - - void Report(const b2ContactVelocityConstraint* constraints); - - b2StackAllocator* m_allocator; - b2ContactListener* m_listener; - - b2Body** m_bodies; - b2Contact** m_contacts; - b2Joint** m_joints; - - b2Position* m_positions; - b2Velocity* m_velocities; - - int32 m_bodyCount; - int32 m_jointCount; - int32 m_contactCount; - - int32 m_bodyCapacity; - int32 m_contactCapacity; - int32 m_jointCapacity; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2TimeStep.h b/src/libjin/3rdparty/Box2D/Dynamics/b2TimeStep.h deleted file mode 100644 index 72a4838..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2TimeStep.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_TIME_STEP_H -#define B2_TIME_STEP_H - -#include "Box2D/Common/b2Math.h" - -/// Profiling data. Times are in milliseconds. -struct b2Profile -{ - float32 step; - float32 collide; - float32 solve; - float32 solveInit; - float32 solveVelocity; - float32 solvePosition; - float32 broadphase; - float32 solveTOI; -}; - -/// This is an internal structure. -struct b2TimeStep -{ - float32 dt; // time step - float32 inv_dt; // inverse time step (0 if dt == 0). - float32 dtRatio; // dt * inv_dt0 - int32 velocityIterations; - int32 positionIterations; - bool warmStarting; -}; - -/// This is an internal structure. -struct b2Position -{ - b2Vec2 c; - float32 a; -}; - -/// This is an internal structure. -struct b2Velocity -{ - b2Vec2 v; - float32 w; -}; - -/// Solver Data -struct b2SolverData -{ - b2TimeStep step; - b2Position* positions; - b2Velocity* velocities; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2World.cpp b/src/libjin/3rdparty/Box2D/Dynamics/b2World.cpp deleted file mode 100644 index f21812e..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2World.cpp +++ /dev/null @@ -1,1366 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/b2World.h" -#include "Box2D/Dynamics/b2Body.h" -#include "Box2D/Dynamics/b2Fixture.h" -#include "Box2D/Dynamics/b2Island.h" -#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" -#include "Box2D/Dynamics/Contacts/b2Contact.h" -#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" -#include "Box2D/Collision/b2Collision.h" -#include "Box2D/Collision/b2BroadPhase.h" -#include "Box2D/Collision/Shapes/b2CircleShape.h" -#include "Box2D/Collision/Shapes/b2EdgeShape.h" -#include "Box2D/Collision/Shapes/b2ChainShape.h" -#include "Box2D/Collision/Shapes/b2PolygonShape.h" -#include "Box2D/Collision/b2TimeOfImpact.h" -#include "Box2D/Common/b2Draw.h" -#include "Box2D/Common/b2Timer.h" -#include <new> - -b2World::b2World(const b2Vec2& gravity) -{ - m_destructionListener = nullptr; - m_debugDraw = nullptr; - - m_bodyList = nullptr; - m_jointList = nullptr; - - m_bodyCount = 0; - m_jointCount = 0; - - m_warmStarting = true; - m_continuousPhysics = true; - m_subStepping = false; - - m_stepComplete = true; - - m_allowSleep = true; - m_gravity = gravity; - - m_flags = e_clearForces; - - m_inv_dt0 = 0.0f; - - m_contactManager.m_allocator = &m_blockAllocator; - - memset(&m_profile, 0, sizeof(b2Profile)); -} - -b2World::~b2World() -{ - // Some shapes allocate using b2Alloc. - b2Body* b = m_bodyList; - while (b) - { - b2Body* bNext = b->m_next; - - b2Fixture* f = b->m_fixtureList; - while (f) - { - b2Fixture* fNext = f->m_next; - f->m_proxyCount = 0; - f->Destroy(&m_blockAllocator); - f = fNext; - } - - b = bNext; - } -} - -void b2World::SetDestructionListener(b2DestructionListener* listener) -{ - m_destructionListener = listener; -} - -void b2World::SetContactFilter(b2ContactFilter* filter) -{ - m_contactManager.m_contactFilter = filter; -} - -void b2World::SetContactListener(b2ContactListener* listener) -{ - m_contactManager.m_contactListener = listener; -} - -void b2World::SetDebugDraw(b2Draw* debugDraw) -{ - m_debugDraw = debugDraw; -} - -b2Body* b2World::CreateBody(const b2BodyDef* def) -{ - b2Assert(IsLocked() == false); - if (IsLocked()) - { - return nullptr; - } - - void* mem = m_blockAllocator.Allocate(sizeof(b2Body)); - b2Body* b = new (mem) b2Body(def, this); - - // Add to world doubly linked list. - b->m_prev = nullptr; - b->m_next = m_bodyList; - if (m_bodyList) - { - m_bodyList->m_prev = b; - } - m_bodyList = b; - ++m_bodyCount; - - return b; -} - -void b2World::DestroyBody(b2Body* b) -{ - b2Assert(m_bodyCount > 0); - b2Assert(IsLocked() == false); - if (IsLocked()) - { - return; - } - - // Delete the attached joints. - b2JointEdge* je = b->m_jointList; - while (je) - { - b2JointEdge* je0 = je; - je = je->next; - - if (m_destructionListener) - { - m_destructionListener->SayGoodbye(je0->joint); - } - - DestroyJoint(je0->joint); - - b->m_jointList = je; - } - b->m_jointList = nullptr; - - // Delete the attached contacts. - b2ContactEdge* ce = b->m_contactList; - while (ce) - { - b2ContactEdge* ce0 = ce; - ce = ce->next; - m_contactManager.Destroy(ce0->contact); - } - b->m_contactList = nullptr; - - // Delete the attached fixtures. This destroys broad-phase proxies. - b2Fixture* f = b->m_fixtureList; - while (f) - { - b2Fixture* f0 = f; - f = f->m_next; - - if (m_destructionListener) - { - m_destructionListener->SayGoodbye(f0); - } - - f0->DestroyProxies(&m_contactManager.m_broadPhase); - f0->Destroy(&m_blockAllocator); - f0->~b2Fixture(); - m_blockAllocator.Free(f0, sizeof(b2Fixture)); - - b->m_fixtureList = f; - b->m_fixtureCount -= 1; - } - b->m_fixtureList = nullptr; - b->m_fixtureCount = 0; - - // Remove world body list. - if (b->m_prev) - { - b->m_prev->m_next = b->m_next; - } - - if (b->m_next) - { - b->m_next->m_prev = b->m_prev; - } - - if (b == m_bodyList) - { - m_bodyList = b->m_next; - } - - --m_bodyCount; - b->~b2Body(); - m_blockAllocator.Free(b, sizeof(b2Body)); -} - -b2Joint* b2World::CreateJoint(const b2JointDef* def) -{ - b2Assert(IsLocked() == false); - if (IsLocked()) - { - return nullptr; - } - - b2Joint* j = b2Joint::Create(def, &m_blockAllocator); - - // Connect to the world list. - j->m_prev = nullptr; - j->m_next = m_jointList; - if (m_jointList) - { - m_jointList->m_prev = j; - } - m_jointList = j; - ++m_jointCount; - - // Connect to the bodies' doubly linked lists. - j->m_edgeA.joint = j; - j->m_edgeA.other = j->m_bodyB; - j->m_edgeA.prev = nullptr; - j->m_edgeA.next = j->m_bodyA->m_jointList; - if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA; - j->m_bodyA->m_jointList = &j->m_edgeA; - - j->m_edgeB.joint = j; - j->m_edgeB.other = j->m_bodyA; - j->m_edgeB.prev = nullptr; - j->m_edgeB.next = j->m_bodyB->m_jointList; - if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB; - j->m_bodyB->m_jointList = &j->m_edgeB; - - b2Body* bodyA = def->bodyA; - b2Body* bodyB = def->bodyB; - - // If the joint prevents collisions, then flag any contacts for filtering. - if (def->collideConnected == false) - { - b2ContactEdge* edge = bodyB->GetContactList(); - while (edge) - { - if (edge->other == bodyA) - { - // Flag the contact for filtering at the next time step (where either - // body is awake). - edge->contact->FlagForFiltering(); - } - - edge = edge->next; - } - } - - // Note: creating a joint doesn't wake the bodies. - - return j; -} - -void b2World::DestroyJoint(b2Joint* j) -{ - b2Assert(IsLocked() == false); - if (IsLocked()) - { - return; - } - - bool collideConnected = j->m_collideConnected; - - // Remove from the doubly linked list. - if (j->m_prev) - { - j->m_prev->m_next = j->m_next; - } - - if (j->m_next) - { - j->m_next->m_prev = j->m_prev; - } - - if (j == m_jointList) - { - m_jointList = j->m_next; - } - - // Disconnect from island graph. - b2Body* bodyA = j->m_bodyA; - b2Body* bodyB = j->m_bodyB; - - // Wake up connected bodies. - bodyA->SetAwake(true); - bodyB->SetAwake(true); - - // Remove from body 1. - if (j->m_edgeA.prev) - { - j->m_edgeA.prev->next = j->m_edgeA.next; - } - - if (j->m_edgeA.next) - { - j->m_edgeA.next->prev = j->m_edgeA.prev; - } - - if (&j->m_edgeA == bodyA->m_jointList) - { - bodyA->m_jointList = j->m_edgeA.next; - } - - j->m_edgeA.prev = nullptr; - j->m_edgeA.next = nullptr; - - // Remove from body 2 - if (j->m_edgeB.prev) - { - j->m_edgeB.prev->next = j->m_edgeB.next; - } - - if (j->m_edgeB.next) - { - j->m_edgeB.next->prev = j->m_edgeB.prev; - } - - if (&j->m_edgeB == bodyB->m_jointList) - { - bodyB->m_jointList = j->m_edgeB.next; - } - - j->m_edgeB.prev = nullptr; - j->m_edgeB.next = nullptr; - - b2Joint::Destroy(j, &m_blockAllocator); - - b2Assert(m_jointCount > 0); - --m_jointCount; - - // If the joint prevents collisions, then flag any contacts for filtering. - if (collideConnected == false) - { - b2ContactEdge* edge = bodyB->GetContactList(); - while (edge) - { - if (edge->other == bodyA) - { - // Flag the contact for filtering at the next time step (where either - // body is awake). - edge->contact->FlagForFiltering(); - } - - edge = edge->next; - } - } -} - -// -void b2World::SetAllowSleeping(bool flag) -{ - if (flag == m_allowSleep) - { - return; - } - - m_allowSleep = flag; - if (m_allowSleep == false) - { - for (b2Body* b = m_bodyList; b; b = b->m_next) - { - b->SetAwake(true); - } - } -} - -// Find islands, integrate and solve constraints, solve position constraints -void b2World::Solve(const b2TimeStep& step) -{ - m_profile.solveInit = 0.0f; - m_profile.solveVelocity = 0.0f; - m_profile.solvePosition = 0.0f; - - // Size the island for the worst case. - b2Island island(m_bodyCount, - m_contactManager.m_contactCount, - m_jointCount, - &m_stackAllocator, - m_contactManager.m_contactListener); - - // Clear all the island flags. - for (b2Body* b = m_bodyList; b; b = b->m_next) - { - b->m_flags &= ~b2Body::e_islandFlag; - } - for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) - { - c->m_flags &= ~b2Contact::e_islandFlag; - } - for (b2Joint* j = m_jointList; j; j = j->m_next) - { - j->m_islandFlag = false; - } - - // Build and simulate all awake islands. - int32 stackSize = m_bodyCount; - b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*)); - for (b2Body* seed = m_bodyList; seed; seed = seed->m_next) - { - if (seed->m_flags & b2Body::e_islandFlag) - { - continue; - } - - if (seed->IsAwake() == false || seed->IsActive() == false) - { - continue; - } - - // The seed can be dynamic or kinematic. - if (seed->GetType() == b2_staticBody) - { - continue; - } - - // Reset island and stack. - island.Clear(); - int32 stackCount = 0; - stack[stackCount++] = seed; - seed->m_flags |= b2Body::e_islandFlag; - - // Perform a depth first search (DFS) on the constraint graph. - while (stackCount > 0) - { - // Grab the next body off the stack and add it to the island. - b2Body* b = stack[--stackCount]; - b2Assert(b->IsActive() == true); - island.Add(b); - - // Make sure the body is awake (without resetting sleep timer). - b->m_flags |= b2Body::e_awakeFlag; - - // To keep islands as small as possible, we don't - // propagate islands across static bodies. - if (b->GetType() == b2_staticBody) - { - continue; - } - - // Search all contacts connected to this body. - for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next) - { - b2Contact* contact = ce->contact; - - // Has this contact already been added to an island? - if (contact->m_flags & b2Contact::e_islandFlag) - { - continue; - } - - // Is this contact solid and touching? - if (contact->IsEnabled() == false || - contact->IsTouching() == false) - { - continue; - } - - // Skip sensors. - bool sensorA = contact->m_fixtureA->m_isSensor; - bool sensorB = contact->m_fixtureB->m_isSensor; - if (sensorA || sensorB) - { - continue; - } - - island.Add(contact); - contact->m_flags |= b2Contact::e_islandFlag; - - b2Body* other = ce->other; - - // Was the other body already added to this island? - if (other->m_flags & b2Body::e_islandFlag) - { - continue; - } - - b2Assert(stackCount < stackSize); - stack[stackCount++] = other; - other->m_flags |= b2Body::e_islandFlag; - } - - // Search all joints connect to this body. - for (b2JointEdge* je = b->m_jointList; je; je = je->next) - { - if (je->joint->m_islandFlag == true) - { - continue; - } - - b2Body* other = je->other; - - // Don't simulate joints connected to inactive bodies. - if (other->IsActive() == false) - { - continue; - } - - island.Add(je->joint); - je->joint->m_islandFlag = true; - - if (other->m_flags & b2Body::e_islandFlag) - { - continue; - } - - b2Assert(stackCount < stackSize); - stack[stackCount++] = other; - other->m_flags |= b2Body::e_islandFlag; - } - } - - b2Profile profile; - island.Solve(&profile, step, m_gravity, m_allowSleep); - m_profile.solveInit += profile.solveInit; - m_profile.solveVelocity += profile.solveVelocity; - m_profile.solvePosition += profile.solvePosition; - - // Post solve cleanup. - for (int32 i = 0; i < island.m_bodyCount; ++i) - { - // Allow static bodies to participate in other islands. - b2Body* b = island.m_bodies[i]; - if (b->GetType() == b2_staticBody) - { - b->m_flags &= ~b2Body::e_islandFlag; - } - } - } - - m_stackAllocator.Free(stack); - - { - b2Timer timer; - // Synchronize fixtures, check for out of range bodies. - for (b2Body* b = m_bodyList; b; b = b->GetNext()) - { - // If a body was not in an island then it did not move. - if ((b->m_flags & b2Body::e_islandFlag) == 0) - { - continue; - } - - if (b->GetType() == b2_staticBody) - { - continue; - } - - // Update fixtures (for broad-phase). - b->SynchronizeFixtures(); - } - - // Look for new contacts. - m_contactManager.FindNewContacts(); - m_profile.broadphase = timer.GetMilliseconds(); - } -} - -// Find TOI contacts and solve them. -void b2World::SolveTOI(const b2TimeStep& step) -{ - b2Island island(2 * b2_maxTOIContacts, b2_maxTOIContacts, 0, &m_stackAllocator, m_contactManager.m_contactListener); - - if (m_stepComplete) - { - for (b2Body* b = m_bodyList; b; b = b->m_next) - { - b->m_flags &= ~b2Body::e_islandFlag; - b->m_sweep.alpha0 = 0.0f; - } - - for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) - { - // Invalidate TOI - c->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag); - c->m_toiCount = 0; - c->m_toi = 1.0f; - } - } - - // Find TOI events and solve them. - for (;;) - { - // Find the first TOI. - b2Contact* minContact = nullptr; - float32 minAlpha = 1.0f; - - for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) - { - // Is this contact disabled? - if (c->IsEnabled() == false) - { - continue; - } - - // Prevent excessive sub-stepping. - if (c->m_toiCount > b2_maxSubSteps) - { - continue; - } - - float32 alpha = 1.0f; - if (c->m_flags & b2Contact::e_toiFlag) - { - // This contact has a valid cached TOI. - alpha = c->m_toi; - } - else - { - b2Fixture* fA = c->GetFixtureA(); - b2Fixture* fB = c->GetFixtureB(); - - // Is there a sensor? - if (fA->IsSensor() || fB->IsSensor()) - { - continue; - } - - b2Body* bA = fA->GetBody(); - b2Body* bB = fB->GetBody(); - - b2BodyType typeA = bA->m_type; - b2BodyType typeB = bB->m_type; - b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody); - - bool activeA = bA->IsAwake() && typeA != b2_staticBody; - bool activeB = bB->IsAwake() && typeB != b2_staticBody; - - // Is at least one body active (awake and dynamic or kinematic)? - if (activeA == false && activeB == false) - { - continue; - } - - bool collideA = bA->IsBullet() || typeA != b2_dynamicBody; - bool collideB = bB->IsBullet() || typeB != b2_dynamicBody; - - // Are these two non-bullet dynamic bodies? - if (collideA == false && collideB == false) - { - continue; - } - - // Compute the TOI for this contact. - // Put the sweeps onto the same time interval. - float32 alpha0 = bA->m_sweep.alpha0; - - if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0) - { - alpha0 = bB->m_sweep.alpha0; - bA->m_sweep.Advance(alpha0); - } - else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0) - { - alpha0 = bA->m_sweep.alpha0; - bB->m_sweep.Advance(alpha0); - } - - b2Assert(alpha0 < 1.0f); - - int32 indexA = c->GetChildIndexA(); - int32 indexB = c->GetChildIndexB(); - - // Compute the time of impact in interval [0, minTOI] - b2TOIInput input; - input.proxyA.Set(fA->GetShape(), indexA); - input.proxyB.Set(fB->GetShape(), indexB); - input.sweepA = bA->m_sweep; - input.sweepB = bB->m_sweep; - input.tMax = 1.0f; - - b2TOIOutput output; - b2TimeOfImpact(&output, &input); - - // Beta is the fraction of the remaining portion of the . - float32 beta = output.t; - if (output.state == b2TOIOutput::e_touching) - { - alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f); - } - else - { - alpha = 1.0f; - } - - c->m_toi = alpha; - c->m_flags |= b2Contact::e_toiFlag; - } - - if (alpha < minAlpha) - { - // This is the minimum TOI found so far. - minContact = c; - minAlpha = alpha; - } - } - - if (minContact == nullptr || 1.0f - 10.0f * b2_epsilon < minAlpha) - { - // No more TOI events. Done! - m_stepComplete = true; - break; - } - - // Advance the bodies to the TOI. - b2Fixture* fA = minContact->GetFixtureA(); - b2Fixture* fB = minContact->GetFixtureB(); - b2Body* bA = fA->GetBody(); - b2Body* bB = fB->GetBody(); - - b2Sweep backup1 = bA->m_sweep; - b2Sweep backup2 = bB->m_sweep; - - bA->Advance(minAlpha); - bB->Advance(minAlpha); - - // The TOI contact likely has some new contact points. - minContact->Update(m_contactManager.m_contactListener); - minContact->m_flags &= ~b2Contact::e_toiFlag; - ++minContact->m_toiCount; - - // Is the contact solid? - if (minContact->IsEnabled() == false || minContact->IsTouching() == false) - { - // Restore the sweeps. - minContact->SetEnabled(false); - bA->m_sweep = backup1; - bB->m_sweep = backup2; - bA->SynchronizeTransform(); - bB->SynchronizeTransform(); - continue; - } - - bA->SetAwake(true); - bB->SetAwake(true); - - // Build the island - island.Clear(); - island.Add(bA); - island.Add(bB); - island.Add(minContact); - - bA->m_flags |= b2Body::e_islandFlag; - bB->m_flags |= b2Body::e_islandFlag; - minContact->m_flags |= b2Contact::e_islandFlag; - - // Get contacts on bodyA and bodyB. - b2Body* bodies[2] = {bA, bB}; - for (int32 i = 0; i < 2; ++i) - { - b2Body* body = bodies[i]; - if (body->m_type == b2_dynamicBody) - { - for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next) - { - if (island.m_bodyCount == island.m_bodyCapacity) - { - break; - } - - if (island.m_contactCount == island.m_contactCapacity) - { - break; - } - - b2Contact* contact = ce->contact; - - // Has this contact already been added to the island? - if (contact->m_flags & b2Contact::e_islandFlag) - { - continue; - } - - // Only add static, kinematic, or bullet bodies. - b2Body* other = ce->other; - if (other->m_type == b2_dynamicBody && - body->IsBullet() == false && other->IsBullet() == false) - { - continue; - } - - // Skip sensors. - bool sensorA = contact->m_fixtureA->m_isSensor; - bool sensorB = contact->m_fixtureB->m_isSensor; - if (sensorA || sensorB) - { - continue; - } - - // Tentatively advance the body to the TOI. - b2Sweep backup = other->m_sweep; - if ((other->m_flags & b2Body::e_islandFlag) == 0) - { - other->Advance(minAlpha); - } - - // Update the contact points - contact->Update(m_contactManager.m_contactListener); - - // Was the contact disabled by the user? - if (contact->IsEnabled() == false) - { - other->m_sweep = backup; - other->SynchronizeTransform(); - continue; - } - - // Are there contact points? - if (contact->IsTouching() == false) - { - other->m_sweep = backup; - other->SynchronizeTransform(); - continue; - } - - // Add the contact to the island - contact->m_flags |= b2Contact::e_islandFlag; - island.Add(contact); - - // Has the other body already been added to the island? - if (other->m_flags & b2Body::e_islandFlag) - { - continue; - } - - // Add the other body to the island. - other->m_flags |= b2Body::e_islandFlag; - - if (other->m_type != b2_staticBody) - { - other->SetAwake(true); - } - - island.Add(other); - } - } - } - - b2TimeStep subStep; - subStep.dt = (1.0f - minAlpha) * step.dt; - subStep.inv_dt = 1.0f / subStep.dt; - subStep.dtRatio = 1.0f; - subStep.positionIterations = 20; - subStep.velocityIterations = step.velocityIterations; - subStep.warmStarting = false; - island.SolveTOI(subStep, bA->m_islandIndex, bB->m_islandIndex); - - // Reset island flags and synchronize broad-phase proxies. - for (int32 i = 0; i < island.m_bodyCount; ++i) - { - b2Body* body = island.m_bodies[i]; - body->m_flags &= ~b2Body::e_islandFlag; - - if (body->m_type != b2_dynamicBody) - { - continue; - } - - body->SynchronizeFixtures(); - - // Invalidate all contact TOIs on this displaced body. - for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next) - { - ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag); - } - } - - // Commit fixture proxy movements to the broad-phase so that new contacts are created. - // Also, some contacts can be destroyed. - m_contactManager.FindNewContacts(); - - if (m_subStepping) - { - m_stepComplete = false; - break; - } - } -} - -void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations) -{ - b2Timer stepTimer; - - // If new fixtures were added, we need to find the new contacts. - if (m_flags & e_newFixture) - { - m_contactManager.FindNewContacts(); - m_flags &= ~e_newFixture; - } - - m_flags |= e_locked; - - b2TimeStep step; - step.dt = dt; - step.velocityIterations = velocityIterations; - step.positionIterations = positionIterations; - if (dt > 0.0f) - { - step.inv_dt = 1.0f / dt; - } - else - { - step.inv_dt = 0.0f; - } - - step.dtRatio = m_inv_dt0 * dt; - - step.warmStarting = m_warmStarting; - - // Update contacts. This is where some contacts are destroyed. - { - b2Timer timer; - m_contactManager.Collide(); - m_profile.collide = timer.GetMilliseconds(); - } - - // Integrate velocities, solve velocity constraints, and integrate positions. - if (m_stepComplete && step.dt > 0.0f) - { - b2Timer timer; - Solve(step); - m_profile.solve = timer.GetMilliseconds(); - } - - // Handle TOI events. - if (m_continuousPhysics && step.dt > 0.0f) - { - b2Timer timer; - SolveTOI(step); - m_profile.solveTOI = timer.GetMilliseconds(); - } - - if (step.dt > 0.0f) - { - m_inv_dt0 = step.inv_dt; - } - - if (m_flags & e_clearForces) - { - ClearForces(); - } - - m_flags &= ~e_locked; - - m_profile.step = stepTimer.GetMilliseconds(); -} - -void b2World::ClearForces() -{ - for (b2Body* body = m_bodyList; body; body = body->GetNext()) - { - body->m_force.SetZero(); - body->m_torque = 0.0f; - } -} - -struct b2WorldQueryWrapper -{ - bool QueryCallback(int32 proxyId) - { - b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId); - return callback->ReportFixture(proxy->fixture); - } - - const b2BroadPhase* broadPhase; - b2QueryCallback* callback; -}; - -void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const -{ - b2WorldQueryWrapper wrapper; - wrapper.broadPhase = &m_contactManager.m_broadPhase; - wrapper.callback = callback; - m_contactManager.m_broadPhase.Query(&wrapper, aabb); -} - -struct b2WorldRayCastWrapper -{ - float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId) - { - void* userData = broadPhase->GetUserData(proxyId); - b2FixtureProxy* proxy = (b2FixtureProxy*)userData; - b2Fixture* fixture = proxy->fixture; - int32 index = proxy->childIndex; - b2RayCastOutput output; - bool hit = fixture->RayCast(&output, input, index); - - if (hit) - { - float32 fraction = output.fraction; - b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2; - return callback->ReportFixture(fixture, point, output.normal, fraction); - } - - return input.maxFraction; - } - - const b2BroadPhase* broadPhase; - b2RayCastCallback* callback; -}; - -void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const -{ - b2WorldRayCastWrapper wrapper; - wrapper.broadPhase = &m_contactManager.m_broadPhase; - wrapper.callback = callback; - b2RayCastInput input; - input.maxFraction = 1.0f; - input.p1 = point1; - input.p2 = point2; - m_contactManager.m_broadPhase.RayCast(&wrapper, input); -} - -void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color) -{ - switch (fixture->GetType()) - { - case b2Shape::e_circle: - { - b2CircleShape* circle = (b2CircleShape*)fixture->GetShape(); - - b2Vec2 center = b2Mul(xf, circle->m_p); - float32 radius = circle->m_radius; - b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f)); - - m_debugDraw->DrawSolidCircle(center, radius, axis, color); - } - break; - - case b2Shape::e_edge: - { - b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape(); - b2Vec2 v1 = b2Mul(xf, edge->m_vertex1); - b2Vec2 v2 = b2Mul(xf, edge->m_vertex2); - m_debugDraw->DrawSegment(v1, v2, color); - } - break; - - case b2Shape::e_chain: - { - b2ChainShape* chain = (b2ChainShape*)fixture->GetShape(); - int32 count = chain->m_count; - const b2Vec2* vertices = chain->m_vertices; - - b2Color ghostColor(0.75f * color.r, 0.75f * color.g, 0.75f * color.b, color.a); - - b2Vec2 v1 = b2Mul(xf, vertices[0]); - m_debugDraw->DrawPoint(v1, 4.0f, color); - - if (chain->m_hasPrevVertex) - { - b2Vec2 vp = b2Mul(xf, chain->m_prevVertex); - m_debugDraw->DrawSegment(vp, v1, ghostColor); - m_debugDraw->DrawCircle(vp, 0.1f, ghostColor); - } - - for (int32 i = 1; i < count; ++i) - { - b2Vec2 v2 = b2Mul(xf, vertices[i]); - m_debugDraw->DrawSegment(v1, v2, color); - m_debugDraw->DrawPoint(v2, 4.0f, color); - v1 = v2; - } - - if (chain->m_hasNextVertex) - { - b2Vec2 vn = b2Mul(xf, chain->m_nextVertex); - m_debugDraw->DrawSegment(v1, vn, ghostColor); - m_debugDraw->DrawCircle(vn, 0.1f, ghostColor); - } - } - break; - - case b2Shape::e_polygon: - { - b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape(); - int32 vertexCount = poly->m_count; - b2Assert(vertexCount <= b2_maxPolygonVertices); - b2Vec2 vertices[b2_maxPolygonVertices]; - - for (int32 i = 0; i < vertexCount; ++i) - { - vertices[i] = b2Mul(xf, poly->m_vertices[i]); - } - - m_debugDraw->DrawSolidPolygon(vertices, vertexCount, color); - } - break; - - default: - break; - } -} - -void b2World::DrawJoint(b2Joint* joint) -{ - b2Body* bodyA = joint->GetBodyA(); - b2Body* bodyB = joint->GetBodyB(); - const b2Transform& xf1 = bodyA->GetTransform(); - const b2Transform& xf2 = bodyB->GetTransform(); - b2Vec2 x1 = xf1.p; - b2Vec2 x2 = xf2.p; - b2Vec2 p1 = joint->GetAnchorA(); - b2Vec2 p2 = joint->GetAnchorB(); - - b2Color color(0.5f, 0.8f, 0.8f); - - switch (joint->GetType()) - { - case e_distanceJoint: - m_debugDraw->DrawSegment(p1, p2, color); - break; - - case e_pulleyJoint: - { - b2PulleyJoint* pulley = (b2PulleyJoint*)joint; - b2Vec2 s1 = pulley->GetGroundAnchorA(); - b2Vec2 s2 = pulley->GetGroundAnchorB(); - m_debugDraw->DrawSegment(s1, p1, color); - m_debugDraw->DrawSegment(s2, p2, color); - m_debugDraw->DrawSegment(s1, s2, color); - } - break; - - case e_mouseJoint: - { - b2Color c; - c.Set(0.0f, 1.0f, 0.0f); - m_debugDraw->DrawPoint(p1, 4.0f, c); - m_debugDraw->DrawPoint(p2, 4.0f, c); - - c.Set(0.8f, 0.8f, 0.8f); - m_debugDraw->DrawSegment(p1, p2, c); - - } - break; - - default: - m_debugDraw->DrawSegment(x1, p1, color); - m_debugDraw->DrawSegment(p1, p2, color); - m_debugDraw->DrawSegment(x2, p2, color); - } -} - -void b2World::DrawDebugData() -{ - if (m_debugDraw == nullptr) - { - return; - } - - uint32 flags = m_debugDraw->GetFlags(); - - if (flags & b2Draw::e_shapeBit) - { - for (b2Body* b = m_bodyList; b; b = b->GetNext()) - { - const b2Transform& xf = b->GetTransform(); - for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) - { - if (b->IsActive() == false) - { - DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f)); - } - else if (b->GetType() == b2_staticBody) - { - DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f)); - } - else if (b->GetType() == b2_kinematicBody) - { - DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f)); - } - else if (b->IsAwake() == false) - { - DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f)); - } - else - { - DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f)); - } - } - } - } - - if (flags & b2Draw::e_jointBit) - { - for (b2Joint* j = m_jointList; j; j = j->GetNext()) - { - DrawJoint(j); - } - } - - if (flags & b2Draw::e_pairBit) - { - b2Color color(0.3f, 0.9f, 0.9f); - for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext()) - { - //b2Fixture* fixtureA = c->GetFixtureA(); - //b2Fixture* fixtureB = c->GetFixtureB(); - - //b2Vec2 cA = fixtureA->GetAABB().GetCenter(); - //b2Vec2 cB = fixtureB->GetAABB().GetCenter(); - - //g_debugDraw->DrawSegment(cA, cB, color); - } - } - - if (flags & b2Draw::e_aabbBit) - { - b2Color color(0.9f, 0.3f, 0.9f); - b2BroadPhase* bp = &m_contactManager.m_broadPhase; - - for (b2Body* b = m_bodyList; b; b = b->GetNext()) - { - if (b->IsActive() == false) - { - continue; - } - - for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) - { - for (int32 i = 0; i < f->m_proxyCount; ++i) - { - b2FixtureProxy* proxy = f->m_proxies + i; - b2AABB aabb = bp->GetFatAABB(proxy->proxyId); - b2Vec2 vs[4]; - vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); - vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); - vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); - vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); - - m_debugDraw->DrawPolygon(vs, 4, color); - } - } - } - } - - if (flags & b2Draw::e_centerOfMassBit) - { - for (b2Body* b = m_bodyList; b; b = b->GetNext()) - { - b2Transform xf = b->GetTransform(); - xf.p = b->GetWorldCenter(); - m_debugDraw->DrawTransform(xf); - } - } -} - -int32 b2World::GetProxyCount() const -{ - return m_contactManager.m_broadPhase.GetProxyCount(); -} - -int32 b2World::GetTreeHeight() const -{ - return m_contactManager.m_broadPhase.GetTreeHeight(); -} - -int32 b2World::GetTreeBalance() const -{ - return m_contactManager.m_broadPhase.GetTreeBalance(); -} - -float32 b2World::GetTreeQuality() const -{ - return m_contactManager.m_broadPhase.GetTreeQuality(); -} - -void b2World::ShiftOrigin(const b2Vec2& newOrigin) -{ - b2Assert((m_flags & e_locked) == 0); - if ((m_flags & e_locked) == e_locked) - { - return; - } - - for (b2Body* b = m_bodyList; b; b = b->m_next) - { - b->m_xf.p -= newOrigin; - b->m_sweep.c0 -= newOrigin; - b->m_sweep.c -= newOrigin; - } - - for (b2Joint* j = m_jointList; j; j = j->m_next) - { - j->ShiftOrigin(newOrigin); - } - - m_contactManager.m_broadPhase.ShiftOrigin(newOrigin); -} - -void b2World::Dump() -{ - if ((m_flags & e_locked) == e_locked) - { - return; - } - - b2Log("b2Vec2 g(%.15lef, %.15lef);\n", m_gravity.x, m_gravity.y); - b2Log("m_world->SetGravity(g);\n"); - - b2Log("b2Body** bodies = (b2Body**)b2Alloc(%d * sizeof(b2Body*));\n", m_bodyCount); - b2Log("b2Joint** joints = (b2Joint**)b2Alloc(%d * sizeof(b2Joint*));\n", m_jointCount); - int32 i = 0; - for (b2Body* b = m_bodyList; b; b = b->m_next) - { - b->m_islandIndex = i; - b->Dump(); - ++i; - } - - i = 0; - for (b2Joint* j = m_jointList; j; j = j->m_next) - { - j->m_index = i; - ++i; - } - - // First pass on joints, skip gear joints. - for (b2Joint* j = m_jointList; j; j = j->m_next) - { - if (j->m_type == e_gearJoint) - { - continue; - } - - b2Log("{\n"); - j->Dump(); - b2Log("}\n"); - } - - // Second pass on joints, only gear joints. - for (b2Joint* j = m_jointList; j; j = j->m_next) - { - if (j->m_type != e_gearJoint) - { - continue; - } - - b2Log("{\n"); - j->Dump(); - b2Log("}\n"); - } - - b2Log("b2Free(joints);\n"); - b2Log("b2Free(bodies);\n"); - b2Log("joints = nullptr;\n"); - b2Log("bodies = nullptr;\n"); -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2World.h b/src/libjin/3rdparty/Box2D/Dynamics/b2World.h deleted file mode 100644 index d5ad20c..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2World.h +++ /dev/null @@ -1,354 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_WORLD_H -#define B2_WORLD_H - -#include "Box2D/Common/b2Math.h" -#include "Box2D/Common/b2BlockAllocator.h" -#include "Box2D/Common/b2StackAllocator.h" -#include "Box2D/Dynamics/b2ContactManager.h" -#include "Box2D/Dynamics/b2WorldCallbacks.h" -#include "Box2D/Dynamics/b2TimeStep.h" - -struct b2AABB; -struct b2BodyDef; -struct b2Color; -struct b2JointDef; -class b2Body; -class b2Draw; -class b2Fixture; -class b2Joint; - -/// The world class manages all physics entities, dynamic simulation, -/// and asynchronous queries. The world also contains efficient memory -/// management facilities. -class b2World -{ -public: - /// Construct a world object. - /// @param gravity the world gravity vector. - b2World(const b2Vec2& gravity); - - /// Destruct the world. All physics entities are destroyed and all heap memory is released. - ~b2World(); - - /// Register a destruction listener. The listener is owned by you and must - /// remain in scope. - void SetDestructionListener(b2DestructionListener* listener); - - /// Register a contact filter to provide specific control over collision. - /// Otherwise the default filter is used (b2_defaultFilter). The listener is - /// owned by you and must remain in scope. - void SetContactFilter(b2ContactFilter* filter); - - /// Register a contact event listener. The listener is owned by you and must - /// remain in scope. - void SetContactListener(b2ContactListener* listener); - - /// Register a routine for debug drawing. The debug draw functions are called - /// inside with b2World::DrawDebugData method. The debug draw object is owned - /// by you and must remain in scope. - void SetDebugDraw(b2Draw* debugDraw); - - /// Create a rigid body given a definition. No reference to the definition - /// is retained. - /// @warning This function is locked during callbacks. - b2Body* CreateBody(const b2BodyDef* def); - - /// Destroy a rigid body given a definition. No reference to the definition - /// is retained. This function is locked during callbacks. - /// @warning This automatically deletes all associated shapes and joints. - /// @warning This function is locked during callbacks. - void DestroyBody(b2Body* body); - - /// Create a joint to constrain bodies together. No reference to the definition - /// is retained. This may cause the connected bodies to cease colliding. - /// @warning This function is locked during callbacks. - b2Joint* CreateJoint(const b2JointDef* def); - - /// Destroy a joint. This may cause the connected bodies to begin colliding. - /// @warning This function is locked during callbacks. - void DestroyJoint(b2Joint* joint); - - /// Take a time step. This performs collision detection, integration, - /// and constraint solution. - /// @param timeStep the amount of time to simulate, this should not vary. - /// @param velocityIterations for the velocity constraint solver. - /// @param positionIterations for the position constraint solver. - void Step( float32 timeStep, - int32 velocityIterations, - int32 positionIterations); - - /// Manually clear the force buffer on all bodies. By default, forces are cleared automatically - /// after each call to Step. The default behavior is modified by calling SetAutoClearForces. - /// The purpose of this function is to support sub-stepping. Sub-stepping is often used to maintain - /// a fixed sized time step under a variable frame-rate. - /// When you perform sub-stepping you will disable auto clearing of forces and instead call - /// ClearForces after all sub-steps are complete in one pass of your game loop. - /// @see SetAutoClearForces - void ClearForces(); - - /// Call this to draw shapes and other debug draw data. This is intentionally non-const. - void DrawDebugData(); - - /// Query the world for all fixtures that potentially overlap the - /// provided AABB. - /// @param callback a user implemented callback class. - /// @param aabb the query box. - void QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const; - - /// Ray-cast the world for all fixtures in the path of the ray. Your callback - /// controls whether you get the closest point, any point, or n-points. - /// The ray-cast ignores shapes that contain the starting point. - /// @param callback a user implemented callback class. - /// @param point1 the ray starting point - /// @param point2 the ray ending point - void RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const; - - /// Get the world body list. With the returned body, use b2Body::GetNext to get - /// the next body in the world list. A nullptr body indicates the end of the list. - /// @return the head of the world body list. - b2Body* GetBodyList(); - const b2Body* GetBodyList() const; - - /// Get the world joint list. With the returned joint, use b2Joint::GetNext to get - /// the next joint in the world list. A nullptr joint indicates the end of the list. - /// @return the head of the world joint list. - b2Joint* GetJointList(); - const b2Joint* GetJointList() const; - - /// Get the world contact list. With the returned contact, use b2Contact::GetNext to get - /// the next contact in the world list. A nullptr contact indicates the end of the list. - /// @return the head of the world contact list. - /// @warning contacts are created and destroyed in the middle of a time step. - /// Use b2ContactListener to avoid missing contacts. - b2Contact* GetContactList(); - const b2Contact* GetContactList() const; - - /// Enable/disable sleep. - void SetAllowSleeping(bool flag); - bool GetAllowSleeping() const { return m_allowSleep; } - - /// Enable/disable warm starting. For testing. - void SetWarmStarting(bool flag) { m_warmStarting = flag; } - bool GetWarmStarting() const { return m_warmStarting; } - - /// Enable/disable continuous physics. For testing. - void SetContinuousPhysics(bool flag) { m_continuousPhysics = flag; } - bool GetContinuousPhysics() const { return m_continuousPhysics; } - - /// Enable/disable single stepped continuous physics. For testing. - void SetSubStepping(bool flag) { m_subStepping = flag; } - bool GetSubStepping() const { return m_subStepping; } - - /// Get the number of broad-phase proxies. - int32 GetProxyCount() const; - - /// Get the number of bodies. - int32 GetBodyCount() const; - - /// Get the number of joints. - int32 GetJointCount() const; - - /// Get the number of contacts (each may have 0 or more contact points). - int32 GetContactCount() const; - - /// Get the height of the dynamic tree. - int32 GetTreeHeight() const; - - /// Get the balance of the dynamic tree. - int32 GetTreeBalance() const; - - /// Get the quality metric of the dynamic tree. The smaller the better. - /// The minimum is 1. - float32 GetTreeQuality() const; - - /// Change the global gravity vector. - void SetGravity(const b2Vec2& gravity); - - /// Get the global gravity vector. - b2Vec2 GetGravity() const; - - /// Is the world locked (in the middle of a time step). - bool IsLocked() const; - - /// Set flag to control automatic clearing of forces after each time step. - void SetAutoClearForces(bool flag); - - /// Get the flag that controls automatic clearing of forces after each time step. - bool GetAutoClearForces() const; - - /// Shift the world origin. Useful for large worlds. - /// The body shift formula is: position -= newOrigin - /// @param newOrigin the new origin with respect to the old origin - void ShiftOrigin(const b2Vec2& newOrigin); - - /// Get the contact manager for testing. - const b2ContactManager& GetContactManager() const; - - /// Get the current profile. - const b2Profile& GetProfile() const; - - /// Dump the world into the log file. - /// @warning this should be called outside of a time step. - void Dump(); - -private: - - // m_flags - enum - { - e_newFixture = 0x0001, - e_locked = 0x0002, - e_clearForces = 0x0004 - }; - - friend class b2Body; - friend class b2Fixture; - friend class b2ContactManager; - friend class b2Controller; - - void Solve(const b2TimeStep& step); - void SolveTOI(const b2TimeStep& step); - - void DrawJoint(b2Joint* joint); - void DrawShape(b2Fixture* shape, const b2Transform& xf, const b2Color& color); - - b2BlockAllocator m_blockAllocator; - b2StackAllocator m_stackAllocator; - - int32 m_flags; - - b2ContactManager m_contactManager; - - b2Body* m_bodyList; - b2Joint* m_jointList; - - int32 m_bodyCount; - int32 m_jointCount; - - b2Vec2 m_gravity; - bool m_allowSleep; - - b2DestructionListener* m_destructionListener; - b2Draw* m_debugDraw; - - // This is used to compute the time step ratio to - // support a variable time step. - float32 m_inv_dt0; - - // These are for debugging the solver. - bool m_warmStarting; - bool m_continuousPhysics; - bool m_subStepping; - - bool m_stepComplete; - - b2Profile m_profile; -}; - -inline b2Body* b2World::GetBodyList() -{ - return m_bodyList; -} - -inline const b2Body* b2World::GetBodyList() const -{ - return m_bodyList; -} - -inline b2Joint* b2World::GetJointList() -{ - return m_jointList; -} - -inline const b2Joint* b2World::GetJointList() const -{ - return m_jointList; -} - -inline b2Contact* b2World::GetContactList() -{ - return m_contactManager.m_contactList; -} - -inline const b2Contact* b2World::GetContactList() const -{ - return m_contactManager.m_contactList; -} - -inline int32 b2World::GetBodyCount() const -{ - return m_bodyCount; -} - -inline int32 b2World::GetJointCount() const -{ - return m_jointCount; -} - -inline int32 b2World::GetContactCount() const -{ - return m_contactManager.m_contactCount; -} - -inline void b2World::SetGravity(const b2Vec2& gravity) -{ - m_gravity = gravity; -} - -inline b2Vec2 b2World::GetGravity() const -{ - return m_gravity; -} - -inline bool b2World::IsLocked() const -{ - return (m_flags & e_locked) == e_locked; -} - -inline void b2World::SetAutoClearForces(bool flag) -{ - if (flag) - { - m_flags |= e_clearForces; - } - else - { - m_flags &= ~e_clearForces; - } -} - -/// Get the flag that controls automatic clearing of forces after each time step. -inline bool b2World::GetAutoClearForces() const -{ - return (m_flags & e_clearForces) == e_clearForces; -} - -inline const b2ContactManager& b2World::GetContactManager() const -{ - return m_contactManager; -} - -inline const b2Profile& b2World::GetProfile() const -{ - return m_profile; -} - -#endif diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2WorldCallbacks.cpp b/src/libjin/3rdparty/Box2D/Dynamics/b2WorldCallbacks.cpp deleted file mode 100644 index fe71073..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2WorldCallbacks.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Dynamics/b2WorldCallbacks.h" -#include "Box2D/Dynamics/b2Fixture.h" - -// Return true if contact calculations should be performed between these two shapes. -// If you implement your own collision filter you may want to build from this implementation. -bool b2ContactFilter::ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB) -{ - const b2Filter& filterA = fixtureA->GetFilterData(); - const b2Filter& filterB = fixtureB->GetFilterData(); - - if (filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0) - { - return filterA.groupIndex > 0; - } - - bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0; - return collide; -} diff --git a/src/libjin/3rdparty/Box2D/Dynamics/b2WorldCallbacks.h b/src/libjin/3rdparty/Box2D/Dynamics/b2WorldCallbacks.h deleted file mode 100644 index 3d5580a..0000000 --- a/src/libjin/3rdparty/Box2D/Dynamics/b2WorldCallbacks.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_WORLD_CALLBACKS_H -#define B2_WORLD_CALLBACKS_H - -#include "Box2D/Common/b2Settings.h" - -struct b2Vec2; -struct b2Transform; -class b2Fixture; -class b2Body; -class b2Joint; -class b2Contact; -struct b2ContactResult; -struct b2Manifold; - -/// Joints and fixtures are destroyed when their associated -/// body is destroyed. Implement this listener so that you -/// may nullify references to these joints and shapes. -class b2DestructionListener -{ -public: - virtual ~b2DestructionListener() {} - - /// Called when any joint is about to be destroyed due - /// to the destruction of one of its attached bodies. - virtual void SayGoodbye(b2Joint* joint) = 0; - - /// Called when any fixture is about to be destroyed due - /// to the destruction of its parent body. - virtual void SayGoodbye(b2Fixture* fixture) = 0; -}; - -/// Implement this class to provide collision filtering. In other words, you can implement -/// this class if you want finer control over contact creation. -class b2ContactFilter -{ -public: - virtual ~b2ContactFilter() {} - - /// Return true if contact calculations should be performed between these two shapes. - /// @warning for performance reasons this is only called when the AABBs begin to overlap. - virtual bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB); -}; - -/// Contact impulses for reporting. Impulses are used instead of forces because -/// sub-step forces may approach infinity for rigid body collisions. These -/// match up one-to-one with the contact points in b2Manifold. -struct b2ContactImpulse -{ - float32 normalImpulses[b2_maxManifoldPoints]; - float32 tangentImpulses[b2_maxManifoldPoints]; - int32 count; -}; - -/// Implement this class to get contact information. You can use these results for -/// things like sounds and game logic. You can also get contact results by -/// traversing the contact lists after the time step. However, you might miss -/// some contacts because continuous physics leads to sub-stepping. -/// Additionally you may receive multiple callbacks for the same contact in a -/// single time step. -/// You should strive to make your callbacks efficient because there may be -/// many callbacks per time step. -/// @warning You cannot create/destroy Box2D entities inside these callbacks. -class b2ContactListener -{ -public: - virtual ~b2ContactListener() {} - - /// Called when two fixtures begin to touch. - virtual void BeginContact(b2Contact* contact) { B2_NOT_USED(contact); } - - /// Called when two fixtures cease to touch. - virtual void EndContact(b2Contact* contact) { B2_NOT_USED(contact); } - - /// This is called after a contact is updated. This allows you to inspect a - /// contact before it goes to the solver. If you are careful, you can modify the - /// contact manifold (e.g. disable contact). - /// A copy of the old manifold is provided so that you can detect changes. - /// Note: this is called only for awake bodies. - /// Note: this is called even when the number of contact points is zero. - /// Note: this is not called for sensors. - /// Note: if you set the number of contact points to zero, you will not - /// get an EndContact callback. However, you may get a BeginContact callback - /// the next step. - virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) - { - B2_NOT_USED(contact); - B2_NOT_USED(oldManifold); - } - - /// This lets you inspect a contact after the solver is finished. This is useful - /// for inspecting impulses. - /// Note: the contact manifold does not include time of impact impulses, which can be - /// arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly - /// in a separate data structure. - /// Note: this is only called for contacts that are touching, solid, and awake. - virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) - { - B2_NOT_USED(contact); - B2_NOT_USED(impulse); - } -}; - -/// Callback class for AABB queries. -/// See b2World::Query -class b2QueryCallback -{ -public: - virtual ~b2QueryCallback() {} - - /// Called for each fixture found in the query AABB. - /// @return false to terminate the query. - virtual bool ReportFixture(b2Fixture* fixture) = 0; -}; - -/// Callback class for ray casts. -/// See b2World::RayCast -class b2RayCastCallback -{ -public: - virtual ~b2RayCastCallback() {} - - /// Called for each fixture found in the query. You control how the ray cast - /// proceeds by returning a float: - /// return -1: ignore this fixture and continue - /// return 0: terminate the ray cast - /// return fraction: clip the ray to this point - /// return 1: don't clip the ray and continue - /// @param fixture the fixture hit by the ray - /// @param point the point of initial intersection - /// @param normal the normal vector at the point of intersection - /// @return -1 to filter, 0 to terminate, fraction to clip the ray for - /// closest hit, 1 to continue - virtual float32 ReportFixture( b2Fixture* fixture, const b2Vec2& point, - const b2Vec2& normal, float32 fraction) = 0; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/Rope/b2Rope.cpp b/src/libjin/3rdparty/Box2D/Rope/b2Rope.cpp deleted file mode 100644 index 847b11d..0000000 --- a/src/libjin/3rdparty/Box2D/Rope/b2Rope.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* -* Copyright (c) 2011 Erin Catto http://box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "Box2D/Rope/b2Rope.h" -#include "Box2D/Common/b2Draw.h" - -b2Rope::b2Rope() -{ - m_count = 0; - m_ps = nullptr; - m_p0s = nullptr; - m_vs = nullptr; - m_ims = nullptr; - m_Ls = nullptr; - m_as = nullptr; - m_gravity.SetZero(); - m_k2 = 1.0f; - m_k3 = 0.1f; -} - -b2Rope::~b2Rope() -{ - b2Free(m_ps); - b2Free(m_p0s); - b2Free(m_vs); - b2Free(m_ims); - b2Free(m_Ls); - b2Free(m_as); -} - -void b2Rope::Initialize(const b2RopeDef* def) -{ - b2Assert(def->count >= 3); - m_count = def->count; - m_ps = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2)); - m_p0s = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2)); - m_vs = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2)); - m_ims = (float32*)b2Alloc(m_count * sizeof(float32)); - - for (int32 i = 0; i < m_count; ++i) - { - m_ps[i] = def->vertices[i]; - m_p0s[i] = def->vertices[i]; - m_vs[i].SetZero(); - - float32 m = def->masses[i]; - if (m > 0.0f) - { - m_ims[i] = 1.0f / m; - } - else - { - m_ims[i] = 0.0f; - } - } - - int32 count2 = m_count - 1; - int32 count3 = m_count - 2; - m_Ls = (float32*)b2Alloc(count2 * sizeof(float32)); - m_as = (float32*)b2Alloc(count3 * sizeof(float32)); - - for (int32 i = 0; i < count2; ++i) - { - b2Vec2 p1 = m_ps[i]; - b2Vec2 p2 = m_ps[i+1]; - m_Ls[i] = b2Distance(p1, p2); - } - - for (int32 i = 0; i < count3; ++i) - { - b2Vec2 p1 = m_ps[i]; - b2Vec2 p2 = m_ps[i + 1]; - b2Vec2 p3 = m_ps[i + 2]; - - b2Vec2 d1 = p2 - p1; - b2Vec2 d2 = p3 - p2; - - float32 a = b2Cross(d1, d2); - float32 b = b2Dot(d1, d2); - - m_as[i] = b2Atan2(a, b); - } - - m_gravity = def->gravity; - m_damping = def->damping; - m_k2 = def->k2; - m_k3 = def->k3; -} - -void b2Rope::Step(float32 h, int32 iterations) -{ - if (h == 0.0) - { - return; - } - - float32 d = expf(- h * m_damping); - - for (int32 i = 0; i < m_count; ++i) - { - m_p0s[i] = m_ps[i]; - if (m_ims[i] > 0.0f) - { - m_vs[i] += h * m_gravity; - } - m_vs[i] *= d; - m_ps[i] += h * m_vs[i]; - - } - - for (int32 i = 0; i < iterations; ++i) - { - SolveC2(); - SolveC3(); - SolveC2(); - } - - float32 inv_h = 1.0f / h; - for (int32 i = 0; i < m_count; ++i) - { - m_vs[i] = inv_h * (m_ps[i] - m_p0s[i]); - } -} - -void b2Rope::SolveC2() -{ - int32 count2 = m_count - 1; - - for (int32 i = 0; i < count2; ++i) - { - b2Vec2 p1 = m_ps[i]; - b2Vec2 p2 = m_ps[i + 1]; - - b2Vec2 d = p2 - p1; - float32 L = d.Normalize(); - - float32 im1 = m_ims[i]; - float32 im2 = m_ims[i + 1]; - - if (im1 + im2 == 0.0f) - { - continue; - } - - float32 s1 = im1 / (im1 + im2); - float32 s2 = im2 / (im1 + im2); - - p1 -= m_k2 * s1 * (m_Ls[i] - L) * d; - p2 += m_k2 * s2 * (m_Ls[i] - L) * d; - - m_ps[i] = p1; - m_ps[i + 1] = p2; - } -} - -void b2Rope::SetAngle(float32 angle) -{ - int32 count3 = m_count - 2; - for (int32 i = 0; i < count3; ++i) - { - m_as[i] = angle; - } -} - -void b2Rope::SolveC3() -{ - int32 count3 = m_count - 2; - - for (int32 i = 0; i < count3; ++i) - { - b2Vec2 p1 = m_ps[i]; - b2Vec2 p2 = m_ps[i + 1]; - b2Vec2 p3 = m_ps[i + 2]; - - float32 m1 = m_ims[i]; - float32 m2 = m_ims[i + 1]; - float32 m3 = m_ims[i + 2]; - - b2Vec2 d1 = p2 - p1; - b2Vec2 d2 = p3 - p2; - - float32 L1sqr = d1.LengthSquared(); - float32 L2sqr = d2.LengthSquared(); - - if (L1sqr * L2sqr == 0.0f) - { - continue; - } - - float32 a = b2Cross(d1, d2); - float32 b = b2Dot(d1, d2); - - float32 angle = b2Atan2(a, b); - - b2Vec2 Jd1 = (-1.0f / L1sqr) * d1.Skew(); - b2Vec2 Jd2 = (1.0f / L2sqr) * d2.Skew(); - - b2Vec2 J1 = -Jd1; - b2Vec2 J2 = Jd1 - Jd2; - b2Vec2 J3 = Jd2; - - float32 mass = m1 * b2Dot(J1, J1) + m2 * b2Dot(J2, J2) + m3 * b2Dot(J3, J3); - if (mass == 0.0f) - { - continue; - } - - mass = 1.0f / mass; - - float32 C = angle - m_as[i]; - - while (C > b2_pi) - { - angle -= 2 * b2_pi; - C = angle - m_as[i]; - } - - while (C < -b2_pi) - { - angle += 2.0f * b2_pi; - C = angle - m_as[i]; - } - - float32 impulse = - m_k3 * mass * C; - - p1 += (m1 * impulse) * J1; - p2 += (m2 * impulse) * J2; - p3 += (m3 * impulse) * J3; - - m_ps[i] = p1; - m_ps[i + 1] = p2; - m_ps[i + 2] = p3; - } -} - -void b2Rope::Draw(b2Draw* draw) const -{ - b2Color c(0.4f, 0.5f, 0.7f); - - for (int32 i = 0; i < m_count - 1; ++i) - { - draw->DrawSegment(m_ps[i], m_ps[i+1], c); - } -} diff --git a/src/libjin/3rdparty/Box2D/Rope/b2Rope.h b/src/libjin/3rdparty/Box2D/Rope/b2Rope.h deleted file mode 100644 index 40be9e7..0000000 --- a/src/libjin/3rdparty/Box2D/Rope/b2Rope.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -* Copyright (c) 2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_ROPE_H -#define B2_ROPE_H - -#include "Box2D/Common/b2Math.h" - -class b2Draw; - -/// -struct b2RopeDef -{ - b2RopeDef() - { - vertices = nullptr; - count = 0; - masses = nullptr; - gravity.SetZero(); - damping = 0.1f; - k2 = 0.9f; - k3 = 0.1f; - } - - /// - b2Vec2* vertices; - - /// - int32 count; - - /// - float32* masses; - - /// - b2Vec2 gravity; - - /// - float32 damping; - - /// Stretching stiffness - float32 k2; - - /// Bending stiffness. Values above 0.5 can make the simulation blow up. - float32 k3; -}; - -/// -class b2Rope -{ -public: - b2Rope(); - ~b2Rope(); - - /// - void Initialize(const b2RopeDef* def); - - /// - void Step(float32 timeStep, int32 iterations); - - /// - int32 GetVertexCount() const - { - return m_count; - } - - /// - const b2Vec2* GetVertices() const - { - return m_ps; - } - - /// - void Draw(b2Draw* draw) const; - - /// - void SetAngle(float32 angle); - -private: - - void SolveC2(); - void SolveC3(); - - int32 m_count; - b2Vec2* m_ps; - b2Vec2* m_p0s; - b2Vec2* m_vs; - - float32* m_ims; - - float32* m_Ls; - float32* m_as; - - b2Vec2 m_gravity; - float32 m_damping; - - float32 m_k2; - float32 m_k3; -}; - -#endif diff --git a/src/libjin/3rdparty/Box2D/manual.docx b/src/libjin/3rdparty/Box2D/manual.docx Binary files differdeleted file mode 100644 index 1228e2a..0000000 --- a/src/libjin/3rdparty/Box2D/manual.docx +++ /dev/null diff --git a/src/libjin/3rdparty/Box2D/manual_Chinese.docx b/src/libjin/3rdparty/Box2D/manual_Chinese.docx Binary files differdeleted file mode 100644 index 37592c8..0000000 --- a/src/libjin/3rdparty/Box2D/manual_Chinese.docx +++ /dev/null diff --git a/src/libjin/3rdparty/GLee/GLee.c b/src/libjin/3rdparty/GLee/GLee.c index 02dc670..0f32273 100644 --- a/src/libjin/3rdparty/GLee/GLee.c +++ b/src/libjin/3rdparty/GLee/GLee.c @@ -14082,10 +14082,10 @@ int __GLeeGLXNumExtensions=51; /* GLX_SGIX_hyperpipe */ #ifdef __GLEE_GLX_SGIX_hyperpipe -#ifndef GLEE_C_DEFINED_glXQueryHyperpipeNetworkSGIX -#define GLEE_C_DEFINED_glXQueryHyperpipeNetworkSGIX - GLXHyperpipeNetworkSGIX * __stdcall GLee_Lazy_glXQueryHyperpipeNetworkSGIX(Display * dpy, int * npipes) {if (GLeeInit()) return glXQueryHyperpipeNetworkSGIX(dpy, npipes); return (GLXHyperpipeNetworkSGIX *)0;} - GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX=GLee_Lazy_glXQueryHyperpipeNetworkSGIX; +#ifndef GLEE_C_DEFINED_glXQueryHyperpipeNetManagerworkSGIX +#define GLEE_C_DEFINED_glXQueryHyperpipeNetManagerworkSGIX + GLXHyperpipeNetManagerworkSGIX * __stdcall GLee_Lazy_glXQueryHyperpipeNetManagerworkSGIX(Display * dpy, int * npipes) {if (GLeeInit()) return glXQueryHyperpipeNetManagerworkSGIX(dpy, npipes); return (GLXHyperpipeNetManagerworkSGIX *)0;} + GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC GLeeFuncPtr_glXQueryHyperpipeNetManagerworkSGIX=GLee_Lazy_glXQueryHyperpipeNetManagerworkSGIX; #endif #ifndef GLEE_C_DEFINED_glXHyperpipeConfigSGIX #define GLEE_C_DEFINED_glXHyperpipeConfigSGIX @@ -19976,7 +19976,7 @@ GLuint __GLeeLink_GLX_SGIX_hyperpipe(void) { GLint nLinked=0; #ifdef __GLEE_GLX_SGIX_hyperpipe - if ((GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX = (GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeNetworkSGIX"))!=0) nLinked++; + if ((GLeeFuncPtr_glXQueryHyperpipeNetManagerworkSGIX = (GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeNetManagerworkSGIX"))!=0) nLinked++; if ((GLeeFuncPtr_glXHyperpipeConfigSGIX = (GLEEPFNGLXHYPERPIPECONFIGSGIXPROC) __GLeeGetProcAddress("glXHyperpipeConfigSGIX"))!=0) nLinked++; if ((GLeeFuncPtr_glXQueryHyperpipeConfigSGIX = (GLEEPFNGLXQUERYHYPERPIPECONFIGSGIXPROC) __GLeeGetProcAddress("glXQueryHyperpipeConfigSGIX"))!=0) nLinked++; if ((GLeeFuncPtr_glXDestroyHyperpipeConfigSGIX = (GLEEPFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) __GLeeGetProcAddress("glXDestroyHyperpipeConfigSGIX"))!=0) nLinked++; diff --git a/src/libjin/3rdparty/GLee/GLee.h b/src/libjin/3rdparty/GLee/GLee.h index 97c98ab..1e9a297 100644 --- a/src/libjin/3rdparty/GLee/GLee.h +++ b/src/libjin/3rdparty/GLee/GLee.h @@ -1090,7 +1090,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; { char pipeName[_GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; int networkId; - } GLXHyperpipeNetworkSGIX; + } GLXHyperpipeNetManagerworkSGIX; typedef struct { @@ -21851,11 +21851,11 @@ GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; #define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 #define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 #define GLX_HYPERPIPE_ID_SGIX 0x8030 -#ifndef GLEE_H_DEFINED_glXQueryHyperpipeNetworkSGIX -#define GLEE_H_DEFINED_glXQueryHyperpipeNetworkSGIX - typedef GLXHyperpipeNetworkSGIX * (APIENTRYP GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display * dpy, int * npipes); - GLEE_EXTERN GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX; - #define glXQueryHyperpipeNetworkSGIX GLeeFuncPtr_glXQueryHyperpipeNetworkSGIX +#ifndef GLEE_H_DEFINED_glXQueryHyperpipeNetManagerworkSGIX +#define GLEE_H_DEFINED_glXQueryHyperpipeNetManagerworkSGIX + typedef GLXHyperpipeNetManagerworkSGIX * (APIENTRYP GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display * dpy, int * npipes); + GLEE_EXTERN GLEEPFNGLXQUERYHYPERPIPENETWORKSGIXPROC GLeeFuncPtr_glXQueryHyperpipeNetManagerworkSGIX; + #define glXQueryHyperpipeNetManagerworkSGIX GLeeFuncPtr_glXQueryHyperpipeNetManagerworkSGIX #endif #ifndef GLEE_H_DEFINED_glXHyperpipeConfigSGIX #define GLEE_H_DEFINED_glXHyperpipeConfigSGIX diff --git a/src/libjin/3rdparty/base64/base64.h b/src/libjin/3rdparty/base64/base64.h new file mode 100644 index 0000000..2519797 --- /dev/null +++ b/src/libjin/3rdparty/base64/base64.h @@ -0,0 +1,186 @@ +#ifndef BASE64_H +#define BASE64_H + +#define BASE64_ENCODE_OUT_SIZE(s) ((unsigned int)((((s) + 2) / 3) * 4 + 1)) +#define BASE64_DECODE_OUT_SIZE(s) ((unsigned int)(((s) / 4) * 3)) + +/* +* out is null-terminated encode string. +* return values is out length, exclusive terminating `\0' +*/ +unsigned int +base64_encode(const unsigned char *in, unsigned int inlen, char *out); + +/* +* return values is out length +*/ +unsigned int +base64_decode(const char *in, unsigned int inlen, unsigned char *out); + +#endif /* BASE64_H */ + +#ifdef BASE64_IMPLEMENT + +/* This is a public domain base64 implementation written by WEI Zhicheng. */ + +#define BASE64_PAD '=' + +/* BASE 64 encode table */ +static const char base64en[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', +}; + +/* ASCII order for BASE 64 decode, 255 in unused character */ +static const unsigned char base64de[] = { + /* nul, soh, stx, etx, eot, enq, ack, bel, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* bs, ht, nl, vt, np, cr, so, si, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* dle, dc1, dc2, dc3, dc4, nak, syn, etb, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* can, em, sub, esc, fs, gs, rs, us, */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* sp, '!', '"', '#', '$', '%', '&', ''', */ + 255, 255, 255, 255, 255, 255, 255, 255, + + /* '(', ')', '*', '+', ',', '-', '.', '/', */ + 255, 255, 255, 62, 255, 255, 255, 63, + + /* '0', '1', '2', '3', '4', '5', '6', '7', */ + 52, 53, 54, 55, 56, 57, 58, 59, + + /* '8', '9', ':', ';', '<', '=', '>', '?', */ + 60, 61, 255, 255, 255, 255, 255, 255, + + /* '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', */ + 255, 0, 1, 2, 3, 4, 5, 6, + + /* 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', */ + 7, 8, 9, 10, 11, 12, 13, 14, + + /* 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', */ + 15, 16, 17, 18, 19, 20, 21, 22, + + /* 'X', 'Y', 'Z', '[', '\', ']', '^', '_', */ + 23, 24, 25, 255, 255, 255, 255, 255, + + /* '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', */ + 255, 26, 27, 28, 29, 30, 31, 32, + + /* 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', */ + 33, 34, 35, 36, 37, 38, 39, 40, + + /* 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', */ + 41, 42, 43, 44, 45, 46, 47, 48, + + /* 'x', 'y', 'z', '{', '|', '}', '~', del, */ + 49, 50, 51, 255, 255, 255, 255, 255 +}; + +unsigned int +base64_encode(const unsigned char *in, unsigned int inlen, char *out) +{ + int s; + unsigned int i; + unsigned int j; + unsigned char c; + unsigned char l; + + s = 0; + l = 0; + for (i = j = 0; i < inlen; i++) { + c = in[i]; + + switch (s) { + case 0: + s = 1; + out[j++] = base64en[(c >> 2) & 0x3F]; + break; + case 1: + s = 2; + out[j++] = base64en[((l & 0x3) << 4) | ((c >> 4) & 0xF)]; + break; + case 2: + s = 0; + out[j++] = base64en[((l & 0xF) << 2) | ((c >> 6) & 0x3)]; + out[j++] = base64en[c & 0x3F]; + break; + } + l = c; + } + + switch (s) { + case 1: + out[j++] = base64en[(l & 0x3) << 4]; + out[j++] = BASE64_PAD; + out[j++] = BASE64_PAD; + break; + case 2: + out[j++] = base64en[(l & 0xF) << 2]; + out[j++] = BASE64_PAD; + break; + } + + out[j] = 0; + + return j; +} + +unsigned int +base64_decode(const char *in, unsigned int inlen, unsigned char *out) +{ + unsigned int i; + unsigned int j; + unsigned char c; + + if (inlen & 0x3) { + return 0; + } + + for (i = j = 0; i < inlen; i++) { + if (in[i] == BASE64_PAD) { + break; + } + if (in[i] < 0) { + return 0; + } + + c = base64de[in[i]]; + if (c == 255) { + return 0; + } + + switch (i & 0x3) { + case 0: + out[j] = (c << 2) & 0xFF; + break; + case 1: + out[j++] |= (c >> 4) & 0x3; + out[j] = (c & 0xF) << 4; + break; + case 2: + out[j++] |= (c >> 2) & 0xF; + out[j] = (c & 0x3) << 6; + break; + case 3: + out[j++] |= c; + break; + } + } + out[j] = '\0'; + + return j; +} + +#endif diff --git a/src/libjin/3rdparty/ogl/OpenGL.h b/src/libjin/3rdparty/ogl/OpenGL.h new file mode 100644 index 0000000..3984b49 --- /dev/null +++ b/src/libjin/3rdparty/ogl/OpenGL.h @@ -0,0 +1,520 @@ +#ifndef __OGL2D_H +#define __OGL2D_H +#include <vector> + +/* include gl.h before this file */ +namespace ogl2d +{ + /* 2d wrap of opengl 3.0 */ + class OpenGL + { + public: + OpenGL(); + ~OpenGL(); + + inline void enable(GLenum cap) + { + glEnable(cap); + } + + inline void disable(GLenum cap) + { + glDisable(cap); + } + + inline void setBlendFunc(GLenum sfactor, GLenum dfactor) + { + glBlendFunc(sfactor, dfactor); + } + + inline void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) + { + glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); + } + + void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255); + void popColor(); + void flushError(); + GLuint genTexture(); + void bindTexture(GLuint texture = 0); + inline GLuint curTexture() + { + return _texture; + } + void setTexParameter(GLenum pname, GLint param); + void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL); + void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + void activeTexUnit(unsigned int unit = 0); + + inline void drawArrays(GLenum mode, GLint first, GLsizei count) + { + glDrawArrays(mode, first, count); + } + + inline void drawBuffer(GLenum mode) + { + + } + + inline void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) + { + + } + + inline void enableClientState(GLenum arr) + { + glEnableClientState(arr); + } + + inline void disableClientState(GLenum arr) + { + glDisableClientState(arr); + } + + inline GLuint genFrameBuffer() + { + GLuint fbo; + glGenFramebuffers(1, &fbo); + return fbo; + } + + inline void bindFrameBuffer(GLuint fbo) + { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + } + + // Ļһ + inline void ortho(int w, float radio) + { + glOrtho(0, w, w*radio, 0, -1, 1); + } + + inline void orthox(int w, int h) + { + glOrtho(0, w, h, 0, -1, 1); + } + + protected: + struct { GLubyte r, g, b, a; } _color; // current draw color + struct { GLubyte r, g, b, a; } _precolor; // previous draw color + GLuint _texture; // current binded texture + + }; + + ///* OpenGL instance singleton */ + extern OpenGL gl; + +#if defined(OGL2D_IMPLEMENT) + + OpenGL gl; + + OpenGL::OpenGL() + { + memset(&_color, 0xff, sizeof(_color)); + memset(&_precolor, 0xff, sizeof(_precolor)); + } + + OpenGL::~OpenGL() + { + } + + void OpenGL::pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) + { + memcpy(&_precolor, &_color, sizeof(_precolor)); + _color.r = r; + _color.g = g; + _color.b = b; + _color.a = a; + glColor4ub(r, g, b, a); + } + + void OpenGL::popColor() + { + memcpy(&_color, &_precolor, sizeof(_precolor)); + glColor4ub(_color.r, _color.g, _color.b, _color.a); + } + + void OpenGL::flushError() + { + while (glGetError() != GL_NO_ERROR); + } + + GLuint OpenGL::genTexture() + { + GLuint t; + glGenTextures(1, &t); + return t; + } + + void OpenGL::bindTexture(GLuint texture) + { + glBindTexture(GL_TEXTURE_2D, texture); + } + + void OpenGL::setTexParameter(GLenum pname, GLint param) + { + glTexParameteri(GL_TEXTURE_2D, pname, param); + } + + void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels); + } + + void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels); + } + + void OpenGL::activeTexUnit(unsigned int unit) + { + // glActiveTexture selects which texture unit subsequent texture state calls will affect. + glActiveTexture(GL_TEXTURE0 + unit); + } + +#endif // OGL2D_IMPLEMENT +} + +#endif + + +/* GL.h + +WINGDIAPI void APIENTRY glAccum(GLenum op, GLfloat value); +WINGDIAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref); +WINGDIAPI GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences); +WINGDIAPI void APIENTRY glArrayElement(GLint i); +WINGDIAPI void APIENTRY glBegin(GLenum mode); +WINGDIAPI void APIENTRY glBindTexture(GLenum target, GLuint texture); +WINGDIAPI void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +WINGDIAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor); +WINGDIAPI void APIENTRY glCallList(GLuint list); +WINGDIAPI void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists); +WINGDIAPI void APIENTRY glClear(GLbitfield mask); +WINGDIAPI void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +WINGDIAPI void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +WINGDIAPI void APIENTRY glClearDepth(GLclampd depth); +WINGDIAPI void APIENTRY glClearIndex(GLfloat c); +WINGDIAPI void APIENTRY glClearStencil(GLint s); +WINGDIAPI void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation); +WINGDIAPI void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue); +WINGDIAPI void APIENTRY glColor3bv(const GLbyte *v); +WINGDIAPI void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue); +WINGDIAPI void APIENTRY glColor3dv(const GLdouble *v); +WINGDIAPI void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue); +WINGDIAPI void APIENTRY glColor3fv(const GLfloat *v); +WINGDIAPI void APIENTRY glColor3i(GLint red, GLint green, GLint blue); +WINGDIAPI void APIENTRY glColor3iv(const GLint *v); +WINGDIAPI void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue); +WINGDIAPI void APIENTRY glColor3sv(const GLshort *v); +WINGDIAPI void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue); +WINGDIAPI void APIENTRY glColor3ubv(const GLubyte *v); +WINGDIAPI void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue); +WINGDIAPI void APIENTRY glColor3uiv(const GLuint *v); +WINGDIAPI void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue); +WINGDIAPI void APIENTRY glColor3usv(const GLushort *v); +WINGDIAPI void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +WINGDIAPI void APIENTRY glColor4bv(const GLbyte *v); +WINGDIAPI void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +WINGDIAPI void APIENTRY glColor4dv(const GLdouble *v); +WINGDIAPI void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +WINGDIAPI void APIENTRY glColor4fv(const GLfloat *v); +WINGDIAPI void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha); +WINGDIAPI void APIENTRY glColor4iv(const GLint *v); +WINGDIAPI void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); +WINGDIAPI void APIENTRY glColor4sv(const GLshort *v); +WINGDIAPI void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +WINGDIAPI void APIENTRY glColor4ubv(const GLubyte *v); +WINGDIAPI void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); +WINGDIAPI void APIENTRY glColor4uiv(const GLuint *v); +WINGDIAPI void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); +WINGDIAPI void APIENTRY glColor4usv(const GLushort *v); +WINGDIAPI void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +WINGDIAPI void APIENTRY glColorMaterial(GLenum face, GLenum mode); +WINGDIAPI void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +WINGDIAPI void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +WINGDIAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +WINGDIAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +WINGDIAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +WINGDIAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +WINGDIAPI void APIENTRY glCullFace(GLenum mode); +WINGDIAPI void APIENTRY glDeleteLists(GLuint list, GLsizei range); +WINGDIAPI void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures); +WINGDIAPI void APIENTRY glDepthFunc(GLenum func); +WINGDIAPI void APIENTRY glDepthMask(GLboolean flag); +WINGDIAPI void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar); +WINGDIAPI void APIENTRY glDisable(GLenum cap); +WINGDIAPI void APIENTRY glDisableClientState(GLenum array); +WINGDIAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); +WINGDIAPI void APIENTRY glDrawBuffer(GLenum mode); +WINGDIAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +WINGDIAPI void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +WINGDIAPI void APIENTRY glEdgeFlag(GLboolean flag); +WINGDIAPI void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer); +WINGDIAPI void APIENTRY glEdgeFlagv(const GLboolean *flag); +WINGDIAPI void APIENTRY glEnable(GLenum cap); +WINGDIAPI void APIENTRY glEnableClientState(GLenum array); +WINGDIAPI void APIENTRY glEnd(void); +WINGDIAPI void APIENTRY glEndList(void); +WINGDIAPI void APIENTRY glEvalCoord1d(GLdouble u); +WINGDIAPI void APIENTRY glEvalCoord1dv(const GLdouble *u); +WINGDIAPI void APIENTRY glEvalCoord1f(GLfloat u); +WINGDIAPI void APIENTRY glEvalCoord1fv(const GLfloat *u); +WINGDIAPI void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v); +WINGDIAPI void APIENTRY glEvalCoord2dv(const GLdouble *u); +WINGDIAPI void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v); +WINGDIAPI void APIENTRY glEvalCoord2fv(const GLfloat *u); +WINGDIAPI void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2); +WINGDIAPI void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +WINGDIAPI void APIENTRY glEvalPoint1(GLint i); +WINGDIAPI void APIENTRY glEvalPoint2(GLint i, GLint j); +WINGDIAPI void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer); +WINGDIAPI void APIENTRY glFinish(void); +WINGDIAPI void APIENTRY glFlush(void); +WINGDIAPI void APIENTRY glFogf(GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glFogfv(GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glFogi(GLenum pname, GLint param); +WINGDIAPI void APIENTRY glFogiv(GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glFrontFace(GLenum mode); +WINGDIAPI void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +WINGDIAPI GLuint APIENTRY glGenLists(GLsizei range); +WINGDIAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures); +WINGDIAPI void APIENTRY glGetBooleanv(GLenum pname, GLboolean *params); +WINGDIAPI void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation); +WINGDIAPI void APIENTRY glGetDoublev(GLenum pname, GLdouble *params); +WINGDIAPI GLenum APIENTRY glGetError(void); +WINGDIAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v); +WINGDIAPI void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v); +WINGDIAPI void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v); +WINGDIAPI void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values); +WINGDIAPI void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values); +WINGDIAPI void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values); +WINGDIAPI void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params); +WINGDIAPI void APIENTRY glGetPolygonStipple(GLubyte *mask); +WINGDIAPI const GLubyte * APIENTRY glGetString(GLenum name); +WINGDIAPI void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params); +WINGDIAPI void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +WINGDIAPI void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params); +WINGDIAPI void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params); +WINGDIAPI void APIENTRY glHint(GLenum target, GLenum mode); +WINGDIAPI void APIENTRY glIndexMask(GLuint mask); +WINGDIAPI void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer); +WINGDIAPI void APIENTRY glIndexd(GLdouble c); +WINGDIAPI void APIENTRY glIndexdv(const GLdouble *c); +WINGDIAPI void APIENTRY glIndexf(GLfloat c); +WINGDIAPI void APIENTRY glIndexfv(const GLfloat *c); +WINGDIAPI void APIENTRY glIndexi(GLint c); +WINGDIAPI void APIENTRY glIndexiv(const GLint *c); +WINGDIAPI void APIENTRY glIndexs(GLshort c); +WINGDIAPI void APIENTRY glIndexsv(const GLshort *c); +WINGDIAPI void APIENTRY glIndexub(GLubyte c); +WINGDIAPI void APIENTRY glIndexubv(const GLubyte *c); +WINGDIAPI void APIENTRY glInitNames(void); +WINGDIAPI void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer); +WINGDIAPI GLboolean APIENTRY glIsEnabled(GLenum cap); +WINGDIAPI GLboolean APIENTRY glIsList(GLuint list); +WINGDIAPI GLboolean APIENTRY glIsTexture(GLuint texture); +WINGDIAPI void APIENTRY glLightModelf(GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glLightModeli(GLenum pname, GLint param); +WINGDIAPI void APIENTRY glLightModeliv(GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glLighti(GLenum light, GLenum pname, GLint param); +WINGDIAPI void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glLineStipple(GLint factor, GLushort pattern); +WINGDIAPI void APIENTRY glLineWidth(GLfloat width); +WINGDIAPI void APIENTRY glListBase(GLuint base); +WINGDIAPI void APIENTRY glLoadIdentity(void); +WINGDIAPI void APIENTRY glLoadMatrixd(const GLdouble *m); +WINGDIAPI void APIENTRY glLoadMatrixf(const GLfloat *m); +WINGDIAPI void APIENTRY glLoadName(GLuint name); +WINGDIAPI void APIENTRY glLogicOp(GLenum opcode); +WINGDIAPI void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +WINGDIAPI void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +WINGDIAPI void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +WINGDIAPI void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +WINGDIAPI void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2); +WINGDIAPI void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2); +WINGDIAPI void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +WINGDIAPI void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +WINGDIAPI void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param); +WINGDIAPI void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glMatrixMode(GLenum mode); +WINGDIAPI void APIENTRY glMultMatrixd(const GLdouble *m); +WINGDIAPI void APIENTRY glMultMatrixf(const GLfloat *m); +WINGDIAPI void APIENTRY glNewList(GLuint list, GLenum mode); +WINGDIAPI void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz); +WINGDIAPI void APIENTRY glNormal3bv(const GLbyte *v); +WINGDIAPI void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz); +WINGDIAPI void APIENTRY glNormal3dv(const GLdouble *v); +WINGDIAPI void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); +WINGDIAPI void APIENTRY glNormal3fv(const GLfloat *v); +WINGDIAPI void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz); +WINGDIAPI void APIENTRY glNormal3iv(const GLint *v); +WINGDIAPI void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz); +WINGDIAPI void APIENTRY glNormal3sv(const GLshort *v); +WINGDIAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer); +WINGDIAPI void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +WINGDIAPI void APIENTRY glPassThrough(GLfloat token); +WINGDIAPI void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values); +WINGDIAPI void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values); +WINGDIAPI void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values); +WINGDIAPI void APIENTRY glPixelStoref(GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glPixelStorei(GLenum pname, GLint param); +WINGDIAPI void APIENTRY glPixelTransferf(GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glPixelTransferi(GLenum pname, GLint param); +WINGDIAPI void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor); +WINGDIAPI void APIENTRY glPointSize(GLfloat size); +WINGDIAPI void APIENTRY glPolygonMode(GLenum face, GLenum mode); +WINGDIAPI void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units); +WINGDIAPI void APIENTRY glPolygonStipple(const GLubyte *mask); +WINGDIAPI void APIENTRY glPopAttrib(void); +WINGDIAPI void APIENTRY glPopClientAttrib(void); +WINGDIAPI void APIENTRY glPopMatrix(void); +WINGDIAPI void APIENTRY glPopName(void); +WINGDIAPI void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities); +WINGDIAPI void APIENTRY glPushAttrib(GLbitfield mask); +WINGDIAPI void APIENTRY glPushClientAttrib(GLbitfield mask); +WINGDIAPI void APIENTRY glPushMatrix(void); +WINGDIAPI void APIENTRY glPushName(GLuint name); +WINGDIAPI void APIENTRY glRasterPos2d(GLdouble x, GLdouble y); +WINGDIAPI void APIENTRY glRasterPos2dv(const GLdouble *v); +WINGDIAPI void APIENTRY glRasterPos2f(GLfloat x, GLfloat y); +WINGDIAPI void APIENTRY glRasterPos2fv(const GLfloat *v); +WINGDIAPI void APIENTRY glRasterPos2i(GLint x, GLint y); +WINGDIAPI void APIENTRY glRasterPos2iv(const GLint *v); +WINGDIAPI void APIENTRY glRasterPos2s(GLshort x, GLshort y); +WINGDIAPI void APIENTRY glRasterPos2sv(const GLshort *v); +WINGDIAPI void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z); +WINGDIAPI void APIENTRY glRasterPos3dv(const GLdouble *v); +WINGDIAPI void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z); +WINGDIAPI void APIENTRY glRasterPos3fv(const GLfloat *v); +WINGDIAPI void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z); +WINGDIAPI void APIENTRY glRasterPos3iv(const GLint *v); +WINGDIAPI void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z); +WINGDIAPI void APIENTRY glRasterPos3sv(const GLshort *v); +WINGDIAPI void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +WINGDIAPI void APIENTRY glRasterPos4dv(const GLdouble *v); +WINGDIAPI void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +WINGDIAPI void APIENTRY glRasterPos4fv(const GLfloat *v); +WINGDIAPI void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w); +WINGDIAPI void APIENTRY glRasterPos4iv(const GLint *v); +WINGDIAPI void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); +WINGDIAPI void APIENTRY glRasterPos4sv(const GLshort *v); +WINGDIAPI void APIENTRY glReadBuffer(GLenum mode); +WINGDIAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +WINGDIAPI void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +WINGDIAPI void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2); +WINGDIAPI void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +WINGDIAPI void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2); +WINGDIAPI void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2); +WINGDIAPI void APIENTRY glRectiv(const GLint *v1, const GLint *v2); +WINGDIAPI void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +WINGDIAPI void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2); +WINGDIAPI GLint APIENTRY glRenderMode(GLenum mode); +WINGDIAPI void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +WINGDIAPI void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +WINGDIAPI void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z); +WINGDIAPI void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z); +WINGDIAPI void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); +WINGDIAPI void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer); +WINGDIAPI void APIENTRY glShadeModel(GLenum mode); +WINGDIAPI void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask); +WINGDIAPI void APIENTRY glStencilMask(GLuint mask); +WINGDIAPI void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); +WINGDIAPI void APIENTRY glTexCoord1d(GLdouble s); +WINGDIAPI void APIENTRY glTexCoord1dv(const GLdouble *v); +WINGDIAPI void APIENTRY glTexCoord1f(GLfloat s); +WINGDIAPI void APIENTRY glTexCoord1fv(const GLfloat *v); +WINGDIAPI void APIENTRY glTexCoord1i(GLint s); +WINGDIAPI void APIENTRY glTexCoord1iv(const GLint *v); +WINGDIAPI void APIENTRY glTexCoord1s(GLshort s); +WINGDIAPI void APIENTRY glTexCoord1sv(const GLshort *v); +WINGDIAPI void APIENTRY glTexCoord2d(GLdouble s, GLdouble t); +WINGDIAPI void APIENTRY glTexCoord2dv(const GLdouble *v); +WINGDIAPI void APIENTRY glTexCoord2f(GLfloat s, GLfloat t); +WINGDIAPI void APIENTRY glTexCoord2fv(const GLfloat *v); +WINGDIAPI void APIENTRY glTexCoord2i(GLint s, GLint t); +WINGDIAPI void APIENTRY glTexCoord2iv(const GLint *v); +WINGDIAPI void APIENTRY glTexCoord2s(GLshort s, GLshort t); +WINGDIAPI void APIENTRY glTexCoord2sv(const GLshort *v); +WINGDIAPI void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r); +WINGDIAPI void APIENTRY glTexCoord3dv(const GLdouble *v); +WINGDIAPI void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r); +WINGDIAPI void APIENTRY glTexCoord3fv(const GLfloat *v); +WINGDIAPI void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r); +WINGDIAPI void APIENTRY glTexCoord3iv(const GLint *v); +WINGDIAPI void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r); +WINGDIAPI void APIENTRY glTexCoord3sv(const GLshort *v); +WINGDIAPI void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +WINGDIAPI void APIENTRY glTexCoord4dv(const GLdouble *v); +WINGDIAPI void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +WINGDIAPI void APIENTRY glTexCoord4fv(const GLfloat *v); +WINGDIAPI void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q); +WINGDIAPI void APIENTRY glTexCoord4iv(const GLint *v); +WINGDIAPI void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); +WINGDIAPI void APIENTRY glTexCoord4sv(const GLshort *v); +WINGDIAPI void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +WINGDIAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); +WINGDIAPI void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param); +WINGDIAPI void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params); +WINGDIAPI void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param); +WINGDIAPI void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +WINGDIAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +WINGDIAPI void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param); +WINGDIAPI void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params); +WINGDIAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); +WINGDIAPI void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params); +WINGDIAPI void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +WINGDIAPI void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +WINGDIAPI void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z); +WINGDIAPI void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z); +WINGDIAPI void APIENTRY glVertex2d(GLdouble x, GLdouble y); +WINGDIAPI void APIENTRY glVertex2dv(const GLdouble *v); +WINGDIAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y); +WINGDIAPI void APIENTRY glVertex2fv(const GLfloat *v); +WINGDIAPI void APIENTRY glVertex2i(GLint x, GLint y); +WINGDIAPI void APIENTRY glVertex2iv(const GLint *v); +WINGDIAPI void APIENTRY glVertex2s(GLshort x, GLshort y); +WINGDIAPI void APIENTRY glVertex2sv(const GLshort *v); +WINGDIAPI void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z); +WINGDIAPI void APIENTRY glVertex3dv(const GLdouble *v); +WINGDIAPI void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z); +WINGDIAPI void APIENTRY glVertex3fv(const GLfloat *v); +WINGDIAPI void APIENTRY glVertex3i(GLint x, GLint y, GLint z); +WINGDIAPI void APIENTRY glVertex3iv(const GLint *v); +WINGDIAPI void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z); +WINGDIAPI void APIENTRY glVertex3sv(const GLshort *v); +WINGDIAPI void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +WINGDIAPI void APIENTRY glVertex4dv(const GLdouble *v); +WINGDIAPI void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +WINGDIAPI void APIENTRY glVertex4fv(const GLfloat *v); +WINGDIAPI void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w); +WINGDIAPI void APIENTRY glVertex4iv(const GLint *v); +WINGDIAPI void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w); +WINGDIAPI void APIENTRY glVertex4sv(const GLshort *v); +WINGDIAPI void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +WINGDIAPI void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height); + +*/ diff --git a/src/libjin/3rdparty/smount/smount.c b/src/libjin/3rdparty/smount/smount.c index 2b4e9b9..6214800 100644 --- a/src/libjin/3rdparty/smount/smount.c +++ b/src/libjin/3rdparty/smount/smount.c @@ -44,7 +44,7 @@ smtShared* smtnewshared() /** * Concatenate strings together. */ -char *concat(const char *str, ...) { +char* concat(const char *str, ...) { va_list args; const char *s; // Get len @@ -66,7 +66,7 @@ char *concat(const char *str, ...) { return res; } -static int isdir(const char *path) { +static int isdir(const char* path) { struct stat s; int res = stat(path, &s); return S_ISDIR(s.st_mode); @@ -75,12 +75,8 @@ static int isdir(const char *path) { int smtmount(smtShared* S, const char *path) { if (!isdir(path)) - { return SMT_INVALIDMOUNT; - } - S->mount = smtnewpath(PATH_DIR, path, 0); - return SMT_SUCCESS; } @@ -132,33 +128,22 @@ const char* smterrstr(int e) { switch (e) { - case SMT_INVALIDMOUNT: return "invalid mount directory"; - default: return "unknown error"; + case SMT_INVALIDMOUNT: return "invalid mount directory"; + default: return "unknown error"; } } void *smtread(smtShared* S, const char *path, unsigned int *size) { - if (!smtisreg(S, path)) return 0; - int fr = 0; - if (size == 0) - { - fr = 1; - size = (unsigned int*)malloc(sizeof(unsigned int)); - } + if (size == NULL) return NULL; + if (!smtisreg(S, path)) return NULL; char *r = concat(S->mount->path, "/", path, NULL); if (!r) - { - free(size); return NULL; - } FILE *fp = fopen(r, "rb"); free(r); if (!fp) - { - free(size); return 0; - } /* Get file size */ fseek(fp, 0, SEEK_END); *size = ftell(fp); @@ -167,13 +152,13 @@ void *smtread(smtShared* S, const char *path, unsigned int *size) char *res = (char*)malloc(*size + 1); if (!res) return NULL; res[*size] = '\0'; - if (fread(res, 1, *size, fp) != *size) { + if (fread(res, 1, *size, fp) != *size) + { free(res); fclose(fp); return NULL; } fclose(fp); - if (fr) free(size); return res; } diff --git a/src/libjin/3rdparty/smount/smount.h b/src/libjin/3rdparty/smount/smount.h index c0836a7..0f8f774 100644 --- a/src/libjin/3rdparty/smount/smount.h +++ b/src/libjin/3rdparty/smount/smount.h @@ -37,53 +37,38 @@ typedef struct smtShared }smtShared; smtShared* smtnewshared(); - void smtcloseshared(smtShared* S); - /** * Get error string with given error code. */ const char *smterrstr(int err); - /** * Mount a sub file system. */ int smtmount(smtShared* S, const char *path); - /** * Free mount */ void smtunmount(smtShared* S); - int smtexists(smtShared* S, const char *path); - /** * Get size of a file. */ int smtsize(smtShared* S, const char *path); - /** * Can only read files under root directory. */ -void *smtread(smtShared* S, const char *path, unsigned int *size); - +void* smtread(smtShared* S, const char *path, unsigned int *size); int smtisdir(smtShared* S, const char *path); - int smtisreg(smtShared* S, const char *path); - /** * List all folders and files inside current mount directory. */ smtPath *smtlist(smtShared*S, const char *path); - void smtfreelist(smtPath* S); - int smtwrite(smtShared* S, const char *path, const void *data, int size); - void smtdelete(smtShared* S, const char *path); - int smtmkdir(smtShared* S, const char *path); - char* smtfullpath(smtShared* S, const char* path); #endif
\ No newline at end of file diff --git a/src/libjin/3rdparty/stb/stb_image.h b/src/libjin/3rdparty/stb/stb_image.h index 72e0ae6..4df317a 100644 --- a/src/libjin/3rdparty/stb/stb_image.h +++ b/src/libjin/3rdparty/stb/stb_image.h @@ -22,7 +22,7 @@ JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) PNG 1/2/4/8/16-bit-per-channel - + TGA (not sure what subset, if a subset) BMP non-1bpp, non-RLE PSD (composited view only, no extra channels, 8/16 bit-per-channel) @@ -79,7 +79,7 @@ RECENT REVISION HISTORY: github:urraka (animated gif) Junggon Kim (PNM comments) Daniel Gibson (16-bit TGA) socks-the-fox (16-bit PNG) - Jeremy Sawicki (handle all ImageNet JPGs) + Jeremy Sawicki (handle all ImageNetManager JPGs) Optimizations & bugfixes Fabian "ryg" Giesen Arseny Kapoulkine @@ -100,7 +100,6 @@ RECENT REVISION HISTORY: Blazej Dariusz Roszkowski Gregory Mullen github:phprus */ -#define STB_IMAGE_IMPLEMENTATION #ifndef STBI_INCLUDE_STB_IMAGE_H #define STBI_INCLUDE_STB_IMAGE_H diff --git a/src/libjin/3rdparty/stb/stb_truetype.h b/src/libjin/3rdparty/stb/stb_truetype.h index cb8f4c2..927ee21 100644 --- a/src/libjin/3rdparty/stb/stb_truetype.h +++ b/src/libjin/3rdparty/stb/stb_truetype.h @@ -1,4 +1,4 @@ -// stb_truetype.h - v1.16 - public domain +// stb_truetype.h - v1.19 - public domain // authored from 2009-2016 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: @@ -22,39 +22,36 @@ // Mikko Mononen: compound shape support, more cmap formats // Tor Andersson: kerning, subpixel rendering // Dougall Johnson: OpenType / Type 2 font handling +// Daniel Ribeiro Maciel: basic GPOS-based kerning // // Misc other: // Ryan Gordon // Simon Glass // github:IntellectualKitty +// Imanol Celaya +// Daniel Ribeiro Maciel // // Bug/warning reports/fixes: -// "Zer" on mollyrocket -// Cass Everitt -// stoiko (Haemimont Games) -// Brian Hook -// Walter van Niftrik -// David Gow -// David Given -// Ivan-Assen Ivanov -// Anthony Pesch -// Johan Duparc -// Hou Qiming -// Fabian "ryg" Giesen -// Martins Mozeiko -// Cap Petschulat -// Omar Cornut -// github:aloucks -// Peter LaValle -// Sergey Popov -// Giumo X. Clanjor -// Higor Euripedes -// Thomas Fields -// Derek Vinyard -// Cort Stratton -// +// "Zer" on mollyrocket Fabian "ryg" Giesen +// Cass Everitt Martins Mozeiko +// stoiko (Haemimont Games) Cap Petschulat +// Brian Hook Omar Cornut +// Walter van Niftrik github:aloucks +// David Gow Peter LaValle +// David Given Sergey Popov +// Ivan-Assen Ivanov Giumo X. Clanjor +// Anthony Pesch Higor Euripedes +// Johan Duparc Thomas Fields +// Hou Qiming Derek Vinyard +// Rob Loach Cort Stratton +// Kenney Phillis Jr. github:oyvindjam +// Brian Costabile github:vassvik +// // VERSION HISTORY // +// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix // 1.16 (2017-07-12) SDF support // 1.15 (2017-03-03) make more arguments const // 1.14 (2017-01-16) num-fonts-in-TTC function @@ -94,7 +91,7 @@ // Improved 3D API (more shippable): // #include "stb_rect_pack.h" -- optional, but you really want it // stbtt_PackBegin() -// stbtt_PackSetOversample() -- for improved quality on small fonts +// stbtt_PackSetOversampling() -- for improved quality on small fonts // stbtt_PackFontRanges() -- pack and renders // stbtt_PackEnd() // stbtt_GetPackedQuad() @@ -112,6 +109,7 @@ // Character advance/positioning // stbtt_GetCodepointHMetrics() // stbtt_GetFontVMetrics() +// stbtt_GetFontVMetricsOS2() // stbtt_GetCodepointKernAdvance() // // Starting with version 1.06, the rasterizer was replaced with a new, @@ -167,7 +165,7 @@ // measurement for describing font size, defined as 72 points per inch. // stb_truetype provides a point API for compatibility. However, true // "per inch" conventions don't make much sense on computer displays -// since they different monitors have different number of pixels per +// since different monitors have different number of pixels per // inch. For example, Windows traditionally uses a convention that // there are 96 pixels per inch, thus making 'inch' measurements have // nothing to do with inches, and thus effectively defining a point to @@ -177,6 +175,39 @@ // for non-commercial fonts, thus making fonts scaled in points // according to the TrueType spec incoherently sized in practice. // +// DETAILED USAGE: +// +// Scale: +// Select how high you want the font to be, in points or pixels. +// Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute +// a scale factor SF that will be used by all other functions. +// +// Baseline: +// You need to select a y-coordinate that is the baseline of where +// your text will appear. Call GetFontBoundingBox to get the baseline-relative +// bounding box for all characters. SF*-y0 will be the distance in pixels +// that the worst-case character could extend above the baseline, so if +// you want the top edge of characters to appear at the top of the +// screen where y=0, then you would set the baseline to SF*-y0. +// +// Current point: +// Set the current point where the first character will appear. The +// first character could extend left of the current point; this is font +// dependent. You can either choose a current point that is the leftmost +// point and hope, or add some padding, or check the bounding box or +// left-side-bearing of the first character to be displayed and set +// the current point based on that. +// +// Displaying a character: +// Compute the bounding box of the character. It will contain signed values +// relative to <current_point, baseline>. I.e. if it returns x0,y0,x1,y1, +// then the character should be displayed in the rectangle from +// <current_point+SF*x0, baseline+SF*y0> to <current_point+SF*x1,baseline+SF*y1). +// +// Advancing for the next character: +// Call GlyphHMetrics, and compute 'current_point += SF * advance'. +// +// // ADVANCED USAGE // // Quality: @@ -258,7 +289,7 @@ void my_stbtt_initfont(void) glGenTextures(1, &ftex); glBindTexture(GL_TEXTURE_2D, ftex); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); - + // can free temp_bitmap at this point glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } @@ -362,7 +393,7 @@ int main(int arg, char **argv) // "alpha blend" that into the working buffer xpos += (advance * scale); if (text[ch + 1]) - xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch], text[ch + 1]); + xpos += scale * stbtt_GetCodepointKernAdvance(&font, text[ch], text[ch + 1]); ++ch; } @@ -383,7 +414,8 @@ int main(int arg, char **argv) //// INTEGRATION WITH YOUR CODEBASE //// //// The following sections allow you to supply alternate definitions -//// of C library functions used by stb_truetype. +//// of C library functions used by stb_truetype, e.g. if you don't +//// link with the C runtime library. #ifdef STB_TRUETYPE_IMPLEMENTATION // #define your own (u)stbtt_int8/16/32 before including to override this @@ -399,7 +431,7 @@ typedef signed int stbtt_int32; typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1]; typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1]; -// #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h +// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h #ifndef STBTT_ifloor #include <math.h> #define STBTT_ifloor(x) ((int) floor(x)) @@ -412,15 +444,15 @@ typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1]; #define STBTT_pow(x,y) pow(x,y) #endif -#ifndef STBTT_cos +#ifndef STBTT_fmod #include <math.h> -#define STBTT_cos(x) cos(x) -#define STBTT_acos(x) acos(x) +#define STBTT_fmod(x,y) fmod(x,y) #endif -#ifndef STBTT_fabs +#ifndef STBTT_cos #include <math.h> -#define STBTT_fabs(x) fabs(x) +#define STBTT_cos(x) cos(x) +#define STBTT_acos(x) acos(x) #endif #ifndef STBTT_fabs @@ -562,7 +594,7 @@ extern "C" { #define STBTT_POINT_SIZE(x) (-(x)) - STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); // Creates character bitmaps from the font_index'th font found in fontdata (use // font_index=0 if you don't know what that is). It creates num_chars_in_range @@ -587,7 +619,7 @@ extern "C" { unsigned char h_oversample, v_oversample; // don't set these, they're used internally } stbtt_pack_range; - STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); + STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); // Creates character bitmaps from multiple ranges of characters stored in // ranges. This will usually create a better-packed bitmap than multiple // calls to stbtt_PackFontRange. Note that you can call this multiple @@ -672,7 +704,7 @@ extern "C" { int numGlyphs; // number of glyphs, needed for range checking - int loca, head, glyf, hhea, hmtx, kern; // table locations as offset from start of .ttf + int loca, head, glyf, hhea, hmtx, kern, gpos; // table locations as offset from start of .ttf int index_map; // a cmap mapping for our chosen character encoding int indexToLocFormat; // format needed to map from glyph index to glyph @@ -729,6 +761,12 @@ extern "C" { // these are expressed in unscaled coordinates, so you must multiply by // the scale factor for a given size + STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); + // analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 + // table (specific to MS/Windows TTF files). + // + // Returns 1 on success (table present), 0 on failure. + STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); // the bounding box around all possible characters @@ -1310,6 +1348,7 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required if (!cmap || !info->head || !info->hhea || !info->hmtx) return 0; @@ -2186,7 +2225,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st // push immediate if (b0 == 255) { - f = (float)stbtt__buf_get32(&b) / 0x10000; + f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; } else { stbtt__buf_skip(&b, -1); @@ -2225,12 +2264,10 @@ static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, in { stbtt__csctx c = STBTT__CSCTX_INIT(1); int r = stbtt__run_charstring(info, glyph_index, &c); - if (x0) { - *x0 = r ? c.min_x : 0; - *y0 = r ? c.min_y : 0; - *x1 = r ? c.max_x : 0; - *y1 = r ? c.max_y : 0; - } + if (x0) *x0 = r ? c.min_x : 0; + if (y0) *y0 = r ? c.min_y : 0; + if (x1) *x1 = r ? c.max_x : 0; + if (y1) *y1 = r ? c.max_y : 0; return r ? c.num_vertices : 0; } @@ -2255,7 +2292,7 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde } } -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { stbtt_uint8 *data = info->data + info->kern; stbtt_uint32 needle, straw; @@ -2285,9 +2322,260 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, return 0; } +static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) +{ + stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); + switch (coverageFormat) { + case 1: { + stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); + + // Binary search. + stbtt_int32 l = 0, r = glyphCount - 1, m; + int straw, needle = glyph; + while (l <= r) { + stbtt_uint8 *glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(glyphArray + 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + return m; + } + } + } break; + + case 2: { + stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); + stbtt_uint8 *rangeArray = coverageTable + 4; + + // Binary search. + stbtt_int32 l = 0, r = rangeCount - 1, m; + int strawStart, strawEnd, needle = glyph; + while (l <= r) { + stbtt_uint8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(rangeRecord); + strawEnd = ttUSHORT(rangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else { + stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; + } + } + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + } break; + } + + return -1; +} + +static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) +{ + stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); + switch (classDefFormat) + { + case 1: { + stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); + stbtt_uint8 *classDef1ValueArray = classDefTable + 6; + + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + + classDefTable = classDef1ValueArray + 2 * glyphCount; + } break; + + case 2: { + stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); + stbtt_uint8 *classRangeRecords = classDefTable + 4; + + // Binary search. + stbtt_int32 l = 0, r = classRangeCount - 1, m; + int strawStart, strawEnd, needle = glyph; + while (l <= r) { + stbtt_uint8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(classRangeRecord); + strawEnd = ttUSHORT(classRangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(classRangeRecord + 4); + } + + classDefTable = classRangeRecords + 6 * classRangeCount; + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + } break; + } + + return -1; +} + +// Define to STBTT_assert(x) if you want to break on unimplemented formats. +#define STBTT_GPOS_TODO_assert(x) + +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint16 lookupListOffset; + stbtt_uint8 *lookupList; + stbtt_uint16 lookupCount; + stbtt_uint8 *data; + stbtt_int32 i; + + if (!info->gpos) return 0; + + data = info->data + info->gpos; + + if (ttUSHORT(data + 0) != 1) return 0; // Major version 1 + if (ttUSHORT(data + 2) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data + 8); + lookupList = data + lookupListOffset; + lookupCount = ttUSHORT(lookupList); + + for (i = 0; i<lookupCount; ++i) { + stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i); + stbtt_uint8 *lookupTable = lookupList + lookupOffset; + + stbtt_uint16 lookupType = ttUSHORT(lookupTable); + stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4); + stbtt_uint8 *subTableOffsets = lookupTable + 6; + switch (lookupType) { + case 2: { // Pair Adjustment Positioning Subtable + stbtt_int32 sti; + for (sti = 0; sti<subTableCount; sti++) { + stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti); + stbtt_uint8 *table = lookupTable + subtableOffset; + stbtt_uint16 posFormat = ttUSHORT(table); + stbtt_uint16 coverageOffset = ttUSHORT(table + 2); + stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1); + if (coverageIndex == -1) continue; + + switch (posFormat) { + case 1: { + stbtt_int32 l, r, m; + int straw, needle; + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + stbtt_int32 valueRecordPairSizeInBytes = 2; + stbtt_uint16 pairSetCount = ttUSHORT(table + 8); + stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex); + stbtt_uint8 *pairValueTable = table + pairPosOffset; + stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable); + stbtt_uint8 *pairValueArray = pairValueTable + 2; + // TODO: Support more formats. + STBTT_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + STBTT_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; + + STBTT_assert(coverageIndex < pairSetCount); + + needle = glyph2; + r = pairValueCount - 1; + l = 0; + + // Binary search. + while (l <= r) { + stbtt_uint16 secondGlyph; + stbtt_uint8 *pairValue; + m = (l + r) >> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(pairValue); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + stbtt_int16 xAdvance = ttSHORT(pairValue + 2); + return xAdvance; + } + } + } break; + + case 2: { + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + + stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); + int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); + + stbtt_uint16 class1Count = ttUSHORT(table + 12); + stbtt_uint16 class2Count = ttUSHORT(table + 14); + STBTT_assert(glyph1class < class1Count); + STBTT_assert(glyph2class < class2Count); + + // TODO: Support more formats. + STBTT_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + STBTT_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; + + if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { + stbtt_uint8 *class1Records = table + 16; + stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); + stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); + return xAdvance; + } + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + break; + }; + } + } + break; + }; + + default: + // TODO: Implement other stuff. + break; + } + } + + return 0; +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) +{ + int xAdvance = 0; + + if (info->gpos) + xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + + if (info->kern) + xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); + + return xAdvance; +} + STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) { - if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs return 0; return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2)); } @@ -2304,6 +2592,17 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in if (lineGap) *lineGap = ttSHORT(info->data + info->hhea + 8); } +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) +{ + int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); + if (!tab) + return 0; + if (typoAscent) *typoAscent = ttSHORT(info->data + tab + 68); + if (typoDescent) *typoDescent = ttSHORT(info->data + tab + 70); + if (typoLineGap) *typoLineGap = ttSHORT(info->data + tab + 72); + return 1; +} + STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) { *x0 = ttSHORT(info->data + info->head + 36); @@ -2402,7 +2701,7 @@ static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) hh->num_remaining_in_head_chunk = count; } --hh->num_remaining_in_head_chunk; - return (char *)(hh->head) + size * hh->num_remaining_in_head_chunk; + return (char *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; } } @@ -3122,7 +3421,7 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x float dy = (y0 + y2) / 2 - my; if (n > 16) // 65536 segments on one curve better be enough! return 1; - if (dx*dx + dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA + if (dx*dx + dy * dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my, objspace_flatness_squared, n + 1); stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2, objspace_flatness_squared, n + 1); } @@ -3144,9 +3443,9 @@ static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float float dy2 = y3 - y2; float dx = x3 - x0; float dy = y3 - y0; - float longlen = (float)(STBTT_sqrt(dx0*dx0 + dy0*dy0) + STBTT_sqrt(dx1*dx1 + dy1*dy1) + STBTT_sqrt(dx2*dx2 + dy2*dy2)); - float shortlen = (float)STBTT_sqrt(dx*dx + dy*dy); - float flatness_squared = longlen*longlen - shortlen*shortlen; + float longlen = (float)(STBTT_sqrt(dx0*dx0 + dy0 * dy0) + STBTT_sqrt(dx1*dx1 + dy1 * dy1) + STBTT_sqrt(dx2*dx2 + dy2 * dy2)); + float shortlen = (float)STBTT_sqrt(dx*dx + dy * dy); + float flatness_squared = longlen * longlen - shortlen * shortlen; if (n > 16) // 65536 segments on one curve better be enough! return; @@ -3257,7 +3556,8 @@ error: STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) { float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count, *winding_lengths; + int winding_count = 0; + int *winding_lengths = NULL; stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); if (windings) { stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); @@ -3345,6 +3645,11 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint), width, height, xoff, yoff); } +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info, codepoint)); +} + STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) { stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint)); @@ -3397,7 +3702,7 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo return -i; STBTT_assert(x + gw < pw); STBTT_assert(y + gh < ph); - stbtt_MakeGlyphBitmap(&f, pixels + x + y*pw, gw, gh, pw, scale, scale, g); + stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); chardata[i].x0 = (stbtt_int16)x; chardata[i].y0 = (stbtt_int16)y; chardata[i].x1 = (stbtt_int16)(x + gw); @@ -3836,7 +4141,7 @@ STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect stbrp_pack_rects((stbrp_context *)spc->pack_info, rects, num_rects); } -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { stbtt_fontinfo info; int i, j, n, return_value = 1; @@ -3872,7 +4177,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd return return_value; } -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) { stbtt_pack_range range; @@ -3935,10 +4240,10 @@ static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], int num_s = 0; if (a != 0.0) { - float discr = b*b - a*c; + float discr = b * b - a * c; if (discr > 0.0) { float rcpna = -1 / a; - float d = (float)sqrt(discr); + float d = (float)STBTT_sqrt(discr); s0 = (b + d) * rcpna; s1 = (b - d) * rcpna; if (s0 >= 0.0 && s0 <= 1.0) @@ -3972,12 +4277,12 @@ static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q20d = q2d - q0d; float q0rd = q0d - rod; - hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d; - hits[0][1] = a*s0 + b; + hits[0][0] = q0rd + s0 * (2.0f - 2.0f*s0)*q10d + s0 * s0*q20d; + hits[0][1] = a * s0 + b; if (num_s > 1) { - hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d; - hits[1][1] = a*s1 + b; + hits[1][0] = q0rd + s1 * (2.0f - 2.0f*s1)*q10d + s1 * s1*q20d; + hits[1][1] = a * s1 + b; return 2; } else { @@ -4002,7 +4307,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex orig[1] = y; // make sure y never passes through a vertex of the shape - y_frac = (float)fmod(y, 1.0f); + y_frac = (float)STBTT_fmod(y, 1.0f); if (y_frac < 0.01f) y += 0.01f; else if (y_frac > 0.99f) @@ -4073,10 +4378,10 @@ static float stbtt__cuberoot(float x) static int stbtt__solve_cubic(float a, float b, float c, float* r) { float s = -a / 3; - float p = b - a*a / 3; + float p = b - a * a / 3; float q = a * (2 * a*a - 9 * b) / 27 + c; - float p3 = p*p*p; - float d = q*q + 4 * p3 / 27; + float p3 = p * p*p; + float d = q * q + 4 * p3 / 27; if (d >= 0) { float z = (float)STBTT_sqrt(d); float u = (-q + z) / 2; @@ -4158,9 +4463,9 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y; float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y; float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; - float len2 = bx*bx + by*by; + float len2 = bx * bx + by * by; if (len2 != 0.0f) - precompute[i] = 1.0f / (bx*bx + by*by); + precompute[i] = 1.0f / (bx*bx + by * by); else precompute[i] = 0.0f; } @@ -4203,7 +4508,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc float px = x0 - sx, py = y0 - sy; // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve - float t = -(px*dx + py*dy) / (dx*dx + dy*dy); + float t = -(px*dx + py * dy) / (dx*dx + dy * dy); if (t >= 0.0f && t <= 1.0f) min_dist = dist; } @@ -4224,16 +4529,16 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc float res[3], px, py, t, it; float a_inv = precompute[i]; if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula - float a = 3 * (ax*bx + ay*by); - float b = 2 * (ax*ax + ay*ay) + (mx*bx + my*by); - float c = mx*ax + my*ay; + float a = 3 * (ax*bx + ay * by); + float b = 2 * (ax*ax + ay * ay) + (mx*bx + my * by); + float c = mx * ax + my * ay; if (a == 0.0) { // if a is 0, it's linear if (b != 0.0) { res[num++] = -c / b; } } else { - float discriminant = b*b - 4 * a*c; + float discriminant = b * b - 4 * a*c; if (discriminant < 0) num = 0; else { @@ -4245,31 +4550,31 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc } } else { - float b = 3 * (ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point - float c = (2 * (ax*ax + ay*ay) + (mx*bx + my*by)) * a_inv; - float d = (mx*ax + my*ay) * a_inv; + float b = 3 * (ax*bx + ay * by) * a_inv; // could precompute this as it doesn't depend on sample point + float c = (2 * (ax*ax + ay * ay) + (mx*bx + my * by)) * a_inv; + float d = (mx*ax + my * ay) * a_inv; num = stbtt__solve_cubic(b, c, d, res); } if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { t = res[0], it = 1.0f - t; - px = it*it*x0 + 2 * t*it*x1 + t*t*x2; - py = it*it*y0 + 2 * t*it*y1 + t*t*y2; + px = it * it*x0 + 2 * t*it*x1 + t * t*x2; + py = it * it*y0 + 2 * t*it*y1 + t * t*y2; dist2 = (px - sx)*(px - sx) + (py - sy)*(py - sy); if (dist2 < min_dist * min_dist) min_dist = (float)STBTT_sqrt(dist2); } if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { t = res[1], it = 1.0f - t; - px = it*it*x0 + 2 * t*it*x1 + t*t*x2; - py = it*it*y0 + 2 * t*it*y1 + t*t*y2; + px = it * it*x0 + 2 * t*it*x1 + t * t*x2; + py = it * it*y0 + 2 * t*it*y1 + t * t*y2; dist2 = (px - sx)*(px - sx) + (py - sy)*(py - sy); if (dist2 < min_dist * min_dist) min_dist = (float)STBTT_sqrt(dist2); } if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { t = res[2], it = 1.0f - t; - px = it*it*x0 + 2 * t*it*x1 + t*t*x2; - py = it*it*y0 + 2 * t*it*y1 + t*t*y2; + px = it * it*x0 + 2 * t*it*x1 + t * t*x2; + py = it * it*y0 + 2 * t*it*y1 + t * t*y2; dist2 = (px - sx)*(px - sx) + (py - sy)*(py - sy); if (dist2 < min_dist * min_dist) min_dist = (float)STBTT_sqrt(dist2); @@ -4516,6 +4821,9 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const // FULL VERSION HISTORY // +// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix // 1.16 (2017-07-12) SDF support // 1.15 (2017-03-03) make more arguments const // 1.14 (2017-01-16) num-fonts-in-TTC function @@ -4608,4 +4916,4 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ -*/ +*/
\ No newline at end of file diff --git a/src/libjin/Audio/Audio.cpp b/src/libjin/Audio/Audio.cpp deleted file mode 100644 index 5fb10da..0000000 --- a/src/libjin/Audio/Audio.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include "SDL2/SDL.h" -#include "audio.h" - -namespace jin -{ -namespace audio -{ - -} -} - -#endif // JIN_MODULES_AUDIO
\ No newline at end of file diff --git a/src/libjin/Audio/Audio.h b/src/libjin/Audio/Audio.h deleted file mode 100644 index 6c3468e..0000000 --- a/src/libjin/Audio/Audio.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __JIN_AUDIO_H -#define __JIN_AUDIO_H -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -#include "../utils/macros.h" -#include "../common/Subsystem.hpp" - -namespace jin -{ -namespace audio -{ - class Source; - - template<class SubAudio> - class Audio : public Subsystem<SubAudio> - { - - public: - - enum State - { - PLAY , - STOP , - PAUSE, - }; - - virtual void play() = 0; - virtual void stop() = 0; - virtual void pause() = 0; - virtual void resume() = 0; - virtual void setVolume(float volume) = 0; - - protected: - - Audio() - : volume(1) - , state(State::PLAY) - {}; - virtual ~Audio() {}; - SINGLETON(Audio); - - float volume; - State state; - }; - -} -} - -#endif // JIN_MODULES_AUDIO -#endif // __JIN_AUDIO_H
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/SDLAudio.cpp b/src/libjin/Audio/SDL/SDLAudio.cpp deleted file mode 100644 index f7ca70d..0000000 --- a/src/libjin/Audio/SDL/SDLAudio.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include "../../modules.h" -#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO - -#include <iostream> -#include "SDLAudio.h" -#include "SDLSource.h" -#include "../../math/math.h" -#include "../../utils/log.h" - -namespace jin -{ -namespace audio -{ - - using namespace jin::math; - - /* עcallbackƵ̵߳ */ - static void defaultCallback(void *userdata, Uint8 *stream, int size) - { - static SDLAudio* audio = static_cast<SDLAudio*>(userdata); - if (!audio->goOnProcess()) - return; - audio->lock(); - audio->processCommands(); - audio->processSources(stream, size); - audio->processBuffer(stream, size); - audio->unlock(); - } - - onlyonce bool SDLAudio::initSystem(const SettingBase* s) - { -#if JIN_DEBUG - Loghelper::log(Loglevel::LV_INFO, "Init Audio System"); -#endif - - if (SDL_Init(SDL_INIT_AUDIO) < 0) - return false; - SDL_AudioSpec spec; - Setting* setting = (Setting*)s; - if (setting == nullptr) - return false; - - unsigned int samplerate = setting->samplerate; - unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate); - - spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz. - spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order - spec.channels = SDLAUDIO_CHANNELS; // - spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1 - spec.userdata = this; - spec.callback = defaultCallback; - - audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0); - if (audioDevice == 0) - return false; - /* start audio */ - SDL_PauseAudioDevice(audioDevice, 0); - return true; - } - - onlyonce void SDLAudio::quitSystem() - { - SDL_CloseAudio(); - } - - void SDLAudio::lock() - { - SDL_LockAudioDevice(audioDevice); - } - - void SDLAudio::unlock() - { - SDL_UnlockAudioDevice(audioDevice); - } - - bool SDLAudio::goOnProcess() - { - if (state == SDLAudio::State::STOP) - { - SDLSourceManager::get()->removeAllSource(); - pause(); - return false; - } - else if (state == SDLAudio::State::PAUSE) - return false; - else - return true; - } - - void SDLAudio::processCommands() - { - SDLSourceManager::get()->processCommands(); - } - - void SDLAudio::processSources(void* buffer, size_t len) - { - SDLSourceManager::get()->processSources(buffer, len); - } - - void SDLAudio::processBuffer(void* buff, size_t len) - { - short* buffer = (short*)buff; - int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ - const char L = 0, R = 1; - for (int i = 0; i < samples; ++i) - { - short* clip = buffer + (i << 1); - clip[L] *= volume; - clip[R] *= volume; - } - } - - void SDLAudio::play() - { - state = State::PLAY; - } - - void SDLAudio::stop() - { - state = State::STOP; - } - - void SDLAudio::pause() - { - state = State::PAUSE; - } - - void SDLAudio::resume() - { - state = State::PLAY; - } - - void SDLAudio::setVolume(float volume) - { - this->volume = clamp(volume, 0.0f, 1.0f); - } - -} -} - -#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/SDLAudio.h b/src/libjin/Audio/SDL/SDLAudio.h deleted file mode 100644 index f2a4fab..0000000 --- a/src/libjin/Audio/SDL/SDLAudio.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __JIN_AUDIO_SDL_H -#define __JIN_AUDIO_SDL_H -#include "../../modules.h" -#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO - -#include "SDLSource.h" -#include <vector> -#include "../audio.h" - -namespace jin -{ -namespace audio -{ - -#define SDLAUDIO_BITDEPTH 16 -#define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3) -#define SDLAUDIO_CHANNELS 2 - - class SDLAudio : public Audio<SDLAudio> - { - - public: - - struct Setting : SettingBase - { - public: - int samplerate; // Ƶ - int samples; // sample<=samplerate - }; - - /* IAudio interface */ - void play() override; - void stop() override; - void pause() override; - void resume() override; - void setVolume(float volume) override; - - /* process functions*/ - void processCommands(); - void processSources(void* buffer, size_t len); - void processBuffer(void* buffer, size_t len); - bool goOnProcess(); - - void lock(); - void unlock(); - - private: - - SDLAudio() {}; - ~SDLAudio() {}; - - SINGLETON(SDLAudio); - - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - - unsigned int audioDevice; - - }; - -} -} - -#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO -#endif // __JIN_AUDIO_SDL_H
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/SDLSource.cpp b/src/libjin/Audio/SDL/SDLSource.cpp deleted file mode 100644 index c868df5..0000000 --- a/src/libjin/Audio/SDL/SDLSource.cpp +++ /dev/null @@ -1,399 +0,0 @@ -#include "../../modules.h" -#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO - -#include <exception> -#include <fstream> -#include <climits> -#include "../../math/math.h" -#include "../../utils/macros.h" -#include "SDLSource.h" -#include "../../3rdparty/wav/wav.h" -#define STB_VORBIS_HEADER_ONLY -#include "../../3rdparty/stb/stb_vorbis.c" -#include "SDLAudio.h" - -namespace jin -{ -namespace audio -{ - - using namespace jin::math; - -#define BITS 8 - - typedef struct SDLSourceCommand - { - typedef enum Action - { - Nothing = 0, - Play, - Stop, - Pause, - Resume, - Rewind, - SetVolume, - SetLoop, - SetRate, - }; - Action action; - union { - int _integer; - float _float; - bool _boolean; - const char* _string; - } parameter; - - SDLSource* source; - }; - - typedef enum CHANNEL - { - MONO = 1, // - STEREO = 2, // - }; - - typedef MASK enum STATUS - { - PLAYING = 1, - PAUSED = 2, - STOPPED = 4 - }; - -#define Command SDLSourceCommand -#define Action Command::Action -#define Manager SDLSourceManager - - //shared std::queue<Command*> Manager::commands; - //shared std::stack<Command*> Manager::commandsPool; - //shared std::vector<SDLSource*> Manager::sources; - shared Manager* Manager::manager = nullptr; - - SDLSource* SDLSource::createSource(const char* file) - { - std::ifstream fs; - fs.open(file, std::ios::binary); - if (!fs.is_open()) - { - fs.close(); - return nullptr; - } - fs.seekg(0,std::ios::end); - int size = fs.tellg(); - fs.seekg(0, std::ios::beg); - char* buffer = (char*)malloc(size); - memset(buffer, 0, size); - fs.read(buffer, size); - fs.close(); - SDLSource* source = createSource(buffer, size); - free(buffer); - return source; - } - - SDLSource* SDLSource::createSource(void* mem, size_t size) - { - if (mem == nullptr) - return nullptr; - SDLSource* source = new SDLSource(); - try - { - SourceType format = getType(mem, size); - switch (format) - { - case OGG: source->decode_ogg(mem, size); break; - case WAV: source->decode_wav(mem, size); break; - } - } - catch (SourceException& exp) - { - delete source; - return nullptr; - }; - return source; - } - - SDLSource::SDLSource() - { - memset(&status, 0, sizeof(status)); - memset(&raw, 0, sizeof(raw)); - status.volume = 1; - } - - SDLSource::~SDLSource() - { - delete raw.data; - raw.end = 0; - raw.data = 0; - } - - void SDLSource::decode_wav(void* mem, int size) - { - wav_t wav; - if (wav_read(&wav, mem, size) == 0) - { - raw.data = wav.data; - raw.length = wav.length * wav.channels * wav.bitdepth / 8; - raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO); - raw.end = (char*)raw.data + raw.length; - raw.samplerate = wav.samplerate; - raw.bitdepth = wav.bitdepth; - raw.samples = wav.length; - } - else - throw SourceException(); - } - - void SDLSource::decode_ogg(void* _mem, int size) - { - unsigned char* mem = (unsigned char*)_mem; - int channels; - int samplerate; - short* data = (short*)raw.data; - int samples = stb_vorbis_decode_memory( - mem, - size, - &channels, - &samplerate, - &data - ); - const int bitdepth = sizeof(short) * BITS; - raw.channels = channels; - raw.samplerate = samplerate; - raw.data = data; - raw.samples = samples; // һsample - raw.length = samples * channels * sizeof(short); // һsample - raw.bitdepth = bitdepth; - raw.end = (char*)data + raw.length; - } - -#define ActionNone(T)\ -do{\ -Command* cmd = Manager::get()->getCommand();\ -cmd->action = Action::T; \ -cmd->source = this; \ -Manager::get()->pushCommand(cmd); \ -} while (0) - -#define ActionArg(T, ARGT, ARG)\ -do{\ -Command* cmd = Manager::get()->getCommand();\ -cmd->action = Action::T; \ -cmd->parameter.ARGT = ARG; \ -cmd->source = this; \ -Manager::get()->pushCommand(cmd); \ -}while(0) - -#define ActionInt(T, INT) ActionArg(T, _integer, INT) -#define ActionFloat(T, FLT) ActionArg(T, _float, FLT) -#define ActionString(T, STR) ActionArg(T, _string, STR) -#define ActionBool(T, BOL) ActionArg(T, _boolean, BOL) - - void SDLSource::play() - { - ActionNone(Play); - } - - void SDLSource::stop() - { - ActionNone(Stop); - } - - void SDLSource::pause() - { - ActionNone(Pause); - } - - void SDLSource::resume() - { - ActionNone(Resume); - } - - void SDLSource::rewind() - { - ActionNone(Rewind); - } - - inline bool SDLSource::isStopped() const - { - return is(STOPPED); - } - - bool SDLSource::isPaused() const - { - return is(PAUSED); - } - - void SDLSource::setPitch(float pitch) - { - } - - void SDLSource::setVolume(float volume) - { - ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f)); - } - - bool SDLSource::setLoop(bool loop) - { - ActionBool(SetLoop, loop); - return false; - } - - void SDLSource::setRate(float rate) - { - ActionFloat(SetRate, rate); - } - - inline void SDLSource::handle( - SDLSourceManager* manager, - SDLSourceCommand* cmd - ) - { - switch (cmd->action) - { - case Command::Action::Play: - manager->removeSource(this); - manager->pushSource(this); - status.state = PLAYING; - status.pos = 0; // rewind - break; - case Command::Action::Stop: - manager->removeSource(this); - status.state = STOPPED; - status.pos = 0; // rewind - break; - case Command::Action::Pause: - manager->removeSource(this); - status.state = PAUSED; - break; - case Command::Action::Resume: - manager->removeSource(this); - manager->pushSource(this); - status.state = PLAYING; - break; - case Command::Action::Rewind: - status.state = PLAYING; - status.pos = 0; - break; - case Command::Action::SetVolume: - status.volume = cmd->parameter._float; - break; - case Command::Action::SetLoop: - status.loop = cmd->parameter._boolean; - break; - } - } - - inline void SDLSource::process(void* buf, size_t size) - { - short* buffer = (short*)buf; // AUDIO_S16SYS - int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ - const char L = 0, R = 1; - for (int i = 0; i < samples; ++i) - { - char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels; - short left = 0; - short right = 0; - if (raw.bitdepth == 16) - { - left = ((short*)source)[L] * status.volume; - right = ((short*)source)[L + raw.channels - 1] * status.volume; - } - else if (raw.bitdepth == 8) - { - left = source[L] << 8; // << 8 Ŵ16bits - right = source[L + raw.channels - 1] << 8; - } - short* sample = buffer + (i << 1); - sample[L] = clamp(sample[L] + left, SHRT_MIN, SHRT_MAX); // - sample[R] = clamp(sample[R] + right, SHRT_MIN, SHRT_MAX); // - ++status.pos; - if (status.pos > raw.samples && status.loop) - status.pos = 0; // rewind - else if (status.pos > raw.samples && !status.loop) - break; - } - } - - Manager* Manager::get() - { - return (manager == nullptr ? manager = new Manager() : manager); - } - - void Manager::processCommands() - { - Command* cmd = nullptr; - SDLSource* source = nullptr; - while (!commands.empty()) - { - cmd = commands.front(); - if (cmd != nullptr) - { - source = cmd->source; - if (source != nullptr) - source->handle(manager, cmd); - } - commands.pop(); - } - } - - /* AUDIO_S16SYS[size>>1] buffer */ - void Manager::processSources(void* buf, size_t size) - { - /* clear render buffer */ - memset(buf, 0, size); - SDLSource* src = nullptr; - std::vector<SDLSource*>::iterator it = sources.begin(); - for (; it != sources.end();) - { - src = *it; - if (src != nullptr) - src->process(buf, size); - ++it; - } - } - - void Manager::removeSource(SDLSource* source) - { - std::vector<SDLSource*>::iterator it = sources.begin(); - for (it = sources.begin(); it != sources.end(); ) - { - if (*it == source) - { - it = sources.erase(it); - return; - } - ++it; - } - } - - void Manager::removeAllSource() - { - sources.clear(); - } - - void Manager::pushSource(SDLSource* source) - { - if(source != nullptr) - sources.push_back(source); - } - - void Manager::pushCommand(SDLSourceCommand* cmd) - { - commands.push(cmd); - } - - Command* Manager::getCommand() - { - if (!commandsPool.empty()) - { - Command* cmd = commandsPool.top(); - commandsPool.pop(); - return cmd; - } - return new Command(); - } - - -} -} - -#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/SDLSource.h b/src/libjin/Audio/SDL/SDLSource.h deleted file mode 100644 index dd792c7..0000000 --- a/src/libjin/Audio/SDL/SDLSource.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef __JIN_SOURCE_SDL_H -#define __JIN_SOURCE_SDL_H -#include "../../modules.h" -#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO - -#include <vector> -#include <queue> -#include <stack> -#include <exception> - -#include "../source.h" - -namespace jin -{ -namespace audio -{ - - typedef struct SDLSourceCommand; - class SDLSourceManager; - - class SDLSource : public Source - { - - public: - - ~SDLSource(); - - static SDLSource* createSource(const char* file); - static SDLSource* createSource(void* mem, size_t size); - - /* ISource interface */ - void play() override; - void stop() override; - void pause() override; - void resume() override; - void rewind() override; - bool isStopped() const override; - bool isPaused() const override; - void setPitch(float pitch) override; - // Ͻ - void setVolume(float volume) override; - bool setLoop(bool loop) override; - void setRate(float rate) override; - - inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd); - inline void process(void* buffer, size_t size); - - protected: - - SDLSource(); - - void decode_wav(void* mem, int size); - void decode_ogg(void* mem, int size); - - inline bool is(int state) const { return (status.state & state) == state; } - - struct - { - const void* data; // Ƶ - int length; // dataֽڳ - const void* end; // dataβ = (unsigned char*)data + size - int samplerate; // Ƶ - unsigned char bitdepth; // ÿsampleıس - int samples; // sample = size / (bitdepth / 8) - unsigned char channels; // channel1(mono)2(stereo) - } raw; - - /* Procedure controller variable */ - struct - { - int pos; // ǰŵsample - int pitch; // pitch - int state; // ǰ״̬ - bool loop; // loop or not - float volume; // - } status; - - }; - - class SDLSourceManager - { - - public: - - static SDLSourceManager* get(); - - /* Process function */ - void processCommands(); - void processSources(void* buffer, size_t size); - - void removeAllSource(); - void removeSource(SDLSource* source); - void pushSource(SDLSource* source); - SDLSourceCommand* getCommand(); - void pushCommand(SDLSourceCommand* cmd); - - private : - - std::queue<SDLSourceCommand*> commands; - std::stack<SDLSourceCommand*> commandsPool; - std::vector<SDLSource*> sources; // processing sources - static SDLSourceManager* manager; - - }; - - class SourceException : public std::exception - { - const char * what() const throw () - { - return "Load Source Exception"; - } - }; - -} -} - -#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO -#endif // __JIN_SOURCE_SDL_H
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/je_sdl_audio.cpp b/src/libjin/Audio/SDL/je_sdl_audio.cpp new file mode 100644 index 0000000..96df17f --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_audio.cpp @@ -0,0 +1,143 @@ +#include "../../core/je_configuration.h" +#if defined(jin_audio) && (jin_audio == jin_audio_sdl) + +#include <iostream> + +#include "../../math/je_math.h" +#include "../../utils/je_log.h" + +#include "je_sdl_audio.h" +#include "je_sdl_source.h" + +namespace JinEngine +{ + namespace Audio + { + + using namespace JinEngine::Math; + + /* עcallbackƵ̵߳ */ + static void defaultCallback(void *userdata, Uint8 *stream, int size) + { + static SDLAudio* audio = static_cast<SDLAudio*>(userdata); + if (!audio->goOnProcess()) + return; + audio->lock(); + audio->processCommands(); + audio->processSources(stream, size); + audio->processBuffer(stream, size); + audio->unlock(); + } + + /*call only once*/ bool SDLAudio::initSystem(const SettingBase* s) + { + #if defined(jin_debug) + Loghelper::log(Loglevel::LV_INFO, "Init AudioManager System"); + #endif + + if (SDL_Init(SDL_INIT_AUDIO) < 0) + return false; + SDL_AudioSpec spec; + Setting* setting = (Setting*)s; + if (setting == nullptr) + return false; + + unsigned int samplerate = setting->samplerate; + unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate); + + spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz. + spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order + spec.channels = SDLAUDIO_CHANNELS; // + spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1 + spec.userdata = this; + spec.callback = defaultCallback; + + audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0); + if (audioDevice == 0) + return false; + /* start audio */ + SDL_PauseAudioDevice(audioDevice, 0); + return true; + } + + /*call only once*/ void SDLAudio::quitSystem() + { + SDL_CloseAudio(); + } + + void SDLAudio::lock() + { + SDL_LockAudioDevice(audioDevice); + } + + void SDLAudio::unlock() + { + SDL_UnlockAudioDevice(audioDevice); + } + + bool SDLAudio::goOnProcess() + { + if (state == SDLAudio::State::STOP) + { + SDLSourceManager::get()->removeAllSource(); + pause(); + return false; + } + else if (state == SDLAudio::State::PAUSE) + return false; + else + return true; + } + + void SDLAudio::processCommands() + { + SDLSourceManager::get()->processCommands(); + } + + void SDLAudio::processSources(void* buffer, size_t len) + { + SDLSourceManager::get()->processSources(buffer, len); + } + + void SDLAudio::processBuffer(void* buff, size_t len) + { + short* buffer = (short*)buff; + int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ + const char L = 0, R = 1; + for (int i = 0; i < samples; ++i) + { + short* clip = buffer + (i << 1); + clip[L] *= volume; + clip[R] *= volume; + } + } + + void SDLAudio::play() + { + state = State::PLAY; + } + + void SDLAudio::stop() + { + state = State::STOP; + } + + void SDLAudio::pause() + { + state = State::PAUSE; + } + + void SDLAudio::resume() + { + state = State::PLAY; + } + + void SDLAudio::setVolume(float volume) + { + this->volume = clamp(volume, 0.0f, 1.0f); + } + + } // namespace Audio +} // namespace JinEngine + +#endif // (jin_audio) && (jin_audio == jin_audio_sdl)
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/je_sdl_audio.h b/src/libjin/Audio/SDL/je_sdl_audio.h new file mode 100644 index 0000000..57fee5b --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_audio.h @@ -0,0 +1,135 @@ +#ifndef __JE_AUDIO_SDL_H +#define __JE_AUDIO_SDL_H +#include "../../core/je_configuration.h" +#if defined(jin_audio) && (jin_audio == jin_audio_sdl) + +#include <vector> + +#include "../je_audio_manager.h" + +#include "je_sdl_source.h" + +namespace JinEngine +{ + namespace Audio + { + + #define SDLAUDIO_BITDEPTH 16 + #define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3) + #define SDLAUDIO_CHANNELS 2 + + /// + /// Audio system SDL implementation. + /// + class SDLAudio : public AudioManager<SDLAudio> + { + public: + /// + /// SDL audio setting. + /// + struct Setting : SettingBase + { + public: + int samplerate; // Ƶ + int samples; // sample<=samplerate + }; + + /// + /// Play all sources whose state is playing. + /// + void play() override; + + /// + /// Stop and remove all sources from the queue. + /// + void stop() override; + + /// + /// Pause audio. + /// + void pause() override; + + /// + /// Resume audio. + /// + void resume() override; + + /// + /// Set global audio volume. + /// + void setVolume(float volume) override; + + /// + /// Process all commands in the queue. + /// + void processCommands(); + + /// + /// Process all sources. + /// + /// @param buffer Source buffer. + /// @param len Source length. + /// + void processSources(void* buffer, size_t len); + + /// + /// Process audio buffer. + /// + /// @param buffer Audio stream buffer. + /// @param len Length of stream buffer. + /// + void processBuffer(void* buffer, size_t len); + + /// + /// Goon process. + /// + /// @return True if sucessful, otherwise return false. + /// + bool goOnProcess(); + + /// + /// Lock audio device. + /// + void lock(); + + /// + /// Unlock audio device. + /// + void unlock(); + + private: + singleton(SDLAudio); + + /// + /// SDL audio constructor. + /// + SDLAudio() {}; + + /// + /// SDL audio destructor. + /// + ~SDLAudio() {}; + + /// + /// Initialize audio system. + /// + /// @param setting Audio setting. + /// + bool initSystem(const SettingBase* setting) override; + + /// + /// Quit audio system. + /// + void quitSystem() override; + + // Audio device id. + unsigned int audioDevice; + + }; + + } // namespace Audio +} // namespace JinEngine + +#endif // (jin_audio) && (jin_audio == jin_audio_sdl) + +#endif // __JE_AUDIO_SDL_H
\ No newline at end of file diff --git a/src/libjin/Audio/SDL/je_sdl_source.cpp b/src/libjin/Audio/SDL/je_sdl_source.cpp new file mode 100644 index 0000000..72607dd --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_source.cpp @@ -0,0 +1,400 @@ +#include "../../core/je_configuration.h" +#if defined(jin_audio) && (jin_audio == jin_audio_sdl) + +#include <exception> +#include <fstream> +#include <climits> + +#define STB_VORBIS_HEADER_ONLY +#include "../../3rdparty/stb/stb_vorbis.c" +#include "../../math/je_math.h" +#include "../../utils/je_macros.h" +#include "../../3rdparty/wav/wav.h" + +#include "je_sdl_audio.h" +#include "je_sdl_source.h" + +namespace JinEngine +{ + namespace Audio + { + + using namespace JinEngine::Math; + + #define BITS 8 + + typedef struct SDLSourceCommand + { + typedef enum Action + { + Nothing = 0, + Play, + Stop, + Pause, + Resume, + Rewind, + SetVolume, + SetLoop, + SetRate, + }; + Action action; + union { + int _integer; + float _float; + bool _boolean; + const char* _string; + } parameter; + + SDLSource* source; + }; + + typedef enum CHANNEL + { + MONO = 1, // + STEREO = 2, // + }; + + typedef /*mask*/ enum STATUS + { + PLAYING = 1, + PAUSED = 2, + STOPPED = 4 + }; + + #define Command SDLSourceCommand + #define Action Command::Action + #define Manager SDLSourceManager + + ///*class member*/ std::queue<Command*> Manager::commands; + ///*class member*/ std::stack<Command*> Manager::commandsPool; + ///*class member*/ std::vector<SDLSource*> Manager::sources; + /*class member*/ Manager* Manager::manager = nullptr; + + SDLSource* SDLSource::createSource(const char* file) + { + std::ifstream fs; + fs.open(file, std::ios::binary); + if (!fs.is_open()) + { + fs.close(); + return nullptr; + } + fs.seekg(0,std::ios::end); + int size = fs.tellg(); + fs.seekg(0, std::ios::beg); + char* buffer = (char*)malloc(size); + memset(buffer, 0, size); + fs.read(buffer, size); + fs.close(); + SDLSource* source = createSource(buffer, size); + free(buffer); + return source; + } + + SDLSource* SDLSource::createSource(void* mem, size_t size) + { + if (mem == nullptr) + return nullptr; + SDLSource* source = new SDLSource(); + try + { + SourceType format = getType(mem, size); + switch (format) + { + case OGG: source->decode_ogg(mem, size); break; + case WAV: source->decode_wav(mem, size); break; + } + } + catch (SourceException& exp) + { + delete source; + return nullptr; + }; + return source; + } + + SDLSource::SDLSource() + { + memset(&status, 0, sizeof(status)); + memset(&raw, 0, sizeof(raw)); + status.volume = 1; + } + + SDLSource::~SDLSource() + { + delete raw.data; + raw.end = 0; + raw.data = 0; + } + + void SDLSource::decode_wav(void* mem, int size) + { + wav_t wav; + if (wav_read(&wav, mem, size) == 0) + { + raw.data = wav.data; + raw.length = wav.length * wav.channels * wav.bitdepth / 8; + raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO); + raw.end = (char*)raw.data + raw.length; + raw.samplerate = wav.samplerate; + raw.bitdepth = wav.bitdepth; + raw.samples = wav.length; + } + else + throw SourceException(); + } + + void SDLSource::decode_ogg(void* _mem, int size) + { + unsigned char* mem = (unsigned char*)_mem; + int channels; + int samplerate; + short* data = (short*)raw.data; + int samples = stb_vorbis_decode_memory( + mem, + size, + &channels, + &samplerate, + &data + ); + const int bitdepth = sizeof(short) * BITS; + raw.channels = channels; + raw.samplerate = samplerate; + raw.data = data; + raw.samples = samples; // һsample + raw.length = samples * channels * sizeof(short); // һsample + raw.bitdepth = bitdepth; + raw.end = (char*)data + raw.length; + } + + #define ActionNone(T)\ + do{\ + Command* cmd = Manager::get()->getCommand();\ + cmd->action = Action::T; \ + cmd->source = this; \ + Manager::get()->pushCommand(cmd); \ + } while (0) + + #define ActionArg(T, ARGT, ARG)\ + do{\ + Command* cmd = Manager::get()->getCommand();\ + cmd->action = Action::T; \ + cmd->parameter.ARGT = ARG; \ + cmd->source = this; \ + Manager::get()->pushCommand(cmd); \ + }while(0) + + #define ActionInt(T, INT) ActionArg(T, _integer, INT) + #define ActionFloat(T, FLT) ActionArg(T, _float, FLT) + #define ActionString(T, STR) ActionArg(T, _string, STR) + #define ActionBool(T, BOL) ActionArg(T, _boolean, BOL) + + void SDLSource::play() + { + ActionNone(Play); + } + + void SDLSource::stop() + { + ActionNone(Stop); + } + + void SDLSource::pause() + { + ActionNone(Pause); + } + + void SDLSource::resume() + { + ActionNone(Resume); + } + + void SDLSource::rewind() + { + ActionNone(Rewind); + } + + inline bool SDLSource::isStopped() const + { + return is(STOPPED); + } + + bool SDLSource::isPaused() const + { + return is(PAUSED); + } + + void SDLSource::setPitch(float pitch) + { + } + + void SDLSource::setVolume(float volume) + { + ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f)); + } + + void SDLSource::setLoop(bool loop) + { + ActionBool(SetLoop, loop); + } + + void SDLSource::setRate(float rate) + { + ActionFloat(SetRate, rate); + } + + inline void SDLSource::handle( + SDLSourceManager* manager, + SDLSourceCommand* cmd + ) + { + switch (cmd->action) + { + case Command::Action::Play: + manager->removeSource(this); + manager->pushSource(this); + status.state = PLAYING; + status.pos = 0; // rewind + break; + case Command::Action::Stop: + manager->removeSource(this); + status.state = STOPPED; + status.pos = 0; // rewind + break; + case Command::Action::Pause: + manager->removeSource(this); + status.state = PAUSED; + break; + case Command::Action::Resume: + manager->removeSource(this); + manager->pushSource(this); + status.state = PLAYING; + break; + case Command::Action::Rewind: + status.state = PLAYING; + status.pos = 0; + break; + case Command::Action::SetVolume: + status.volume = cmd->parameter._float; + break; + case Command::Action::SetLoop: + status.loop = cmd->parameter._boolean; + break; + } + } + + inline void SDLSource::process(void* buf, size_t size) + { + short* buffer = (short*)buf; // AUDIO_S16SYS + int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫ + const char L = 0, R = 1; + for (int i = 0; i < samples; ++i) + { + char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels; + short l = 0; + short r = 0; + if (raw.bitdepth == 16) + { + l = ((short*)source)[L] * status.volume; + r = ((short*)source)[L + raw.channels - 1] * status.volume; + } + else if (raw.bitdepth == 8) + { + l = source[L] << 8; // << 8 Ŵ16bits + r = source[L + raw.channels - 1] << 8; + } + short* sample = buffer + (i << 1); + sample[L] = clamp(sample[L] + l, SHRT_MIN, SHRT_MAX); // + sample[R] = clamp(sample[R] + r, SHRT_MIN, SHRT_MAX); // + ++status.pos; + if (status.pos > raw.samples && status.loop) + status.pos = 0; // rewind + else if (status.pos > raw.samples && !status.loop) + break; + } + } + + Manager* Manager::get() + { + return (manager == nullptr ? manager = new Manager() : manager); + } + + void Manager::processCommands() + { + Command* cmd = nullptr; + SDLSource* source = nullptr; + while (!commands.empty()) + { + cmd = commands.front(); + if (cmd != nullptr) + { + source = cmd->source; + if (source != nullptr) + source->handle(manager, cmd); + } + commands.pop(); + } + } + + /* AUDIO_S16SYS[size>>1] buffer */ + void Manager::processSources(void* buf, size_t size) + { + /* clear render buffer */ + memset(buf, 0, size); + SDLSource* src = nullptr; + std::vector<SDLSource*>::iterator it = sources.begin(); + for (; it != sources.end();) + { + src = *it; + if (src != nullptr) + src->process(buf, size); + ++it; + } + } + + void Manager::removeSource(SDLSource* source) + { + std::vector<SDLSource*>::iterator it = sources.begin(); + for (it = sources.begin(); it != sources.end(); ) + { + if (*it == source) + { + it = sources.erase(it); + return; + } + ++it; + } + } + + void Manager::removeAllSource() + { + sources.clear(); + } + + void Manager::pushSource(SDLSource* source) + { + if(source != nullptr) + sources.push_back(source); + } + + void Manager::pushCommand(SDLSourceCommand* cmd) + { + commands.push(cmd); + } + + Command* Manager::getCommand() + { + if (!commandsPool.empty()) + { + Command* cmd = commandsPool.top(); + commandsPool.pop(); + return cmd; + } + return new Command(); + } + + + } // namespace Audio +} // namespace JinEngine + +#endif // (jin_audio) && (jin_audio == jin_audio_sdl) diff --git a/src/libjin/Audio/SDL/je_sdl_source.h b/src/libjin/Audio/SDL/je_sdl_source.h new file mode 100644 index 0000000..78cae80 --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_source.h @@ -0,0 +1,269 @@ +#ifndef __JE_SOURCE_SDL_H +#define __JE_SOURCE_SDL_H +#include "../../core/je_configuration.h" +#if defined(jin_audio) && (jin_audio == jin_audio_sdl) + +#include <vector> +#include <queue> +#include <stack> +#include <exception> + +#include "../je_source.h" + +namespace JinEngine +{ + namespace Audio + { + + typedef struct SDLSourceCommand; + + class SDLSourceManager; + + /// + /// Audio source SDL implementation. + /// + class SDLSource : public Source + { + public: + /// + /// Create source from raw source data file. + /// + /// @param file Audio source file. + /// @return Return source if create successful, otherwise return null. + /// + static SDLSource* createSource(const char* file); + + /// + /// Create source from raw source data. + /// + /// @param mem Source data. + /// @param size Source data size. + /// @return Return source if create successful, otherwise return null. + /// + static SDLSource* createSource(void* mem, size_t size); + + /// + /// Source destructor. + /// + ~SDLSource(); + + /// + /// Play source. + /// + void play() override; + + /// + /// Stop source. + /// + void stop() override; + + /// + /// Pause source. + /// + void pause() override; + + /// + /// Resume source. + /// + void resume() override; + + /// + /// Rewind source. + /// + void rewind() override; + + /// + /// Return if the source is stopped. + /// + /// @return True if the source is stopped, otherwise return false. + /// + bool isStopped() const override; + + /// + /// Return if the source is paused. + /// + /// @return True if the source is paused(, otherwise return false. + /// + bool isPaused() const override; + + /// + /// Set pitch. + /// + /// @param pitch Pitch of source. + /// + void setPitch(float pitch) override; + + /// + /// Set volume. + /// + /// @param volume Volume of source. + /// + void setVolume(float volume) override; + + /// + /// Set source loop. + /// + /// @param loop Looping or not. + /// + void setLoop(bool loop) override; + + /// + /// Set source rate. + /// + /// @param rate Rate of source. + /// + void setRate(float rate) override; + + /// + /// Handle a specific command. + /// + /// @param manager Audio manager. + /// @param cmd Source commad. + /// + inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd); + + /// + /// Process decoded source data. + /// + /// @param buffer Source data. + /// @param size Data size. + /// + inline void process(void* buffer, size_t size); + + protected: + /// + /// Source constructor. + /// + SDLSource(); + + /// + /// Decode wav file. + /// + /// @param mem Wav file data. + /// @param size Wav data size. + /// + void decode_wav(void* mem, int size); + + /// + /// Decode ogg file. + /// + /// @param mem ogg file data. + /// @param size ogg data size. + /// + void decode_ogg(void* mem, int size); + + /// + /// Check source state. + /// + /// @param state State to be checked. + /// @return True if state is given state, otherwise return false. + /// + inline bool is(int state) const + { + return (status.state & state) == state; + } + + // Source data. + struct{ + const void* data; // Ƶ + int length; // dataֽڳ + const void* end; // dataβ = (unsigned char*)data + size + int samplerate; // Ƶ + unsigned char bitdepth; // ÿsampleıس + int samples; // sample = size / (bitdepth / 8) + unsigned char channels; // channel1(mono)2(stereo) + } raw; + // Procedure controller variable. + struct{ + int pos; // ǰŵsample + int pitch; // pitch + int state; // ǰ״̬ + bool loop; // loop or not + float volume; // + } status; + + }; + + /// + /// Source manager. + /// + class SDLSourceManager + { + public: + /// + /// Get manager singleton. + /// + /// @return Singleton of SDL source manager. + /// + static SDLSourceManager* get(); + + /// + /// Process commands. + /// + void processCommands(); + + /// + /// Process sources. + /// + /// @param buffer Source data. + /// @param size Size of source data. + /// + void processSources(void* buffer, size_t size); + + /// + /// Clear source queue. + /// + /// This function will stop all sources. + /// + void removeAllSource(); + + /// + /// Remove specific source. + /// + /// @param source SDL audio source. + /// + void removeSource(SDLSource* source); + + /// + /// Push specific source into queue. + /// + /// @param source SDL audio source. + /// + void pushSource(SDLSource* source); + + /// + /// Get command from queue. + /// + /// @return Command at first place. + /// + SDLSourceCommand* getCommand(); + + /// + /// Push command. + /// + /// @param cmd Spcific command. + /// + void pushCommand(SDLSourceCommand* cmd); + + private: + std::queue<SDLSourceCommand*> commands; + std::stack<SDLSourceCommand*> commandsPool; + std::vector<SDLSource*> sources; // processing sources + static SDLSourceManager* manager; + + }; + + class SourceException : public std::exception + { + const char* what() const throw () + { + return "Load Source Exception"; + } + }; + + } // namespace Audio +} // namespace JinEngine + +#endif // (jin_audio) && (jin_audio == jin_audio_sdl) + +#endif // __JE_SOURCE_SDL_H
\ No newline at end of file diff --git a/src/libjin/Audio/Source.cpp b/src/libjin/Audio/Source.cpp deleted file mode 100644 index 61f4055..0000000 --- a/src/libjin/Audio/Source.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include <cstring> -#include "source.h" - -namespace jin -{ -namespace audio -{ - - static int check_header(const void *data, int size, const char *str, int offset) { - int len = strlen(str); - return (size >= offset + len) && !memcmp((char*)data + offset, str, len); - } - - SourceType Source::getType(const void* mem, int size) - { - if(check_header(mem, size, "WAVE", 8)) - return SourceType::WAV; - if(check_header(mem, size, "OggS", 0)) - return SourceType::OGG; - return SourceType::INVALID; - } - -} -} -#endif // JIN_MODULES_AUDIO
\ No newline at end of file diff --git a/src/libjin/Audio/Source.h b/src/libjin/Audio/Source.h deleted file mode 100644 index 3abe7de..0000000 --- a/src/libjin/Audio/Source.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __JIN_AUDIO_SOURCE_H -#define __JIN_AUDIO_SOURCE_H -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -namespace jin -{ -namespace audio -{ - - enum SourceType - { - INVALID = 0, - WAV, - OGG, - }; - - class Source - { - - public: - - Source() {}; - virtual ~Source() {}; - - /* interface */ - virtual void play() = 0; - virtual void stop() = 0; - virtual void pause() = 0; - virtual void resume() = 0; - virtual void rewind() = 0; - virtual bool isStopped() const = 0; - virtual bool isPaused() const = 0; - virtual void setPitch(float pitch) = 0; - virtual void setVolume(float volume) = 0; - virtual bool setLoop(bool loop) = 0; - virtual void setRate(float rate) = 0; - - protected: - - static SourceType getType(const void* mem, int size); - - }; - -} -} - -#endif // JIN_MODULES_AUDIO -#endif // __JIN_AUDIO_SOURCE_H
\ No newline at end of file diff --git a/src/libjin/Audio/je_audio_manager.cpp b/src/libjin/Audio/je_audio_manager.cpp new file mode 100644 index 0000000..e451aa3 --- /dev/null +++ b/src/libjin/Audio/je_audio_manager.cpp @@ -0,0 +1,15 @@ +#include "../core/je_configuration.h" +#if jin_audio + +#include "SDL2/SDL.h" +#include "je_audio_manager.h" + +namespace JinEngine +{ + namespace Audio + { + + } // namespace Audio +} // namespace JinEngine + +#endif // jin_audio diff --git a/src/libjin/Audio/je_audio_manager.h b/src/libjin/Audio/je_audio_manager.h new file mode 100644 index 0000000..00b531a --- /dev/null +++ b/src/libjin/Audio/je_audio_manager.h @@ -0,0 +1,87 @@ +#ifndef __JE_AUDIO_H +#define __JE_AUDIO_H + +#include "../core/je_configuration.h" +#if defined(jin_audio) + +#include "../utils/je_macros.h" +#include "../common/je_subsystem.hpp" + +#include "SDL2/SDL.h" + +namespace JinEngine +{ + namespace Audio + { + + class Source; + + /// + /// Audio manager. + /// + template<class SubAudio> + class AudioManager : public Subsystem<SubAudio> + { + public: + /// + /// Audio state. + /// + enum State + { + PLAY , + STOP , + PAUSE, + }; + + /// + /// Play all sources whose state is playing. + /// + virtual void play() = 0; + + /// + /// Stop and remove all sources from the queue. + /// + virtual void stop() = 0; + + /// + /// Pause audio. + /// + virtual void pause() = 0; + + /// + /// Resume audio. + /// + virtual void resume() = 0; + + /// + /// Set global audio volume. + /// + virtual void setVolume(float volume) = 0; + + protected: + singleton(AudioManager); + + /// + /// AudioManager constructor. + /// + AudioManager() + : volume(1) + , state(State::PLAY) + {}; + + /// + /// AudioManager destructor. + /// + virtual ~AudioManager() {}; + + float volume; + State state; + + }; + + } // namespace Audio +} // namespace JinEngine + +#endif // jin_audio + +#endif // __JE_AUDIO_H
\ No newline at end of file diff --git a/src/libjin/Audio/je_source.cpp b/src/libjin/Audio/je_source.cpp new file mode 100644 index 0000000..6bc1f4f --- /dev/null +++ b/src/libjin/Audio/je_source.cpp @@ -0,0 +1,30 @@ +#include "../core/je_configuration.h" +#if defined(jin_audio) + +#include <cstring> + +#include "je_source.h" + +namespace JinEngine +{ + namespace Audio + { + + static int check_header(const void *data, int size, const char *str, int offset) { + int len = strlen(str); + return (size >= offset + len) && !memcmp((char*)data + offset, str, len); + } + + SourceType Source::getType(const void* mem, int size) + { + if(check_header(mem, size, "WAVE", 8)) + return SourceType::WAV; + if(check_header(mem, size, "OggS", 0)) + return SourceType::OGG; + return SourceType::INVALID; + } + + } // namespace Audio +} // namespace JinEngine + +#endif // jin_audio diff --git a/src/libjin/Audio/je_source.h b/src/libjin/Audio/je_source.h new file mode 100644 index 0000000..519d39f --- /dev/null +++ b/src/libjin/Audio/je_source.h @@ -0,0 +1,116 @@ +#ifndef __JE_AUDIO_SOURCE_H +#define __JE_AUDIO_SOURCE_H +#include "../core/je_configuration.h" +#if defined(jin_audio) + +#include "SDL2/SDL.h" + +namespace JinEngine +{ + namespace Audio + { + + /// + /// Audio source encoding type. + /// + enum SourceType + { + INVALID = 0, + WAV, + OGG, + }; + + /// + /// Audio source. + /// + class Source + { + public: + /// + /// Source constructor. + /// + Source() {}; + + /// + /// Source destructor. + /// + virtual ~Source() {}; + + /// + /// Start playing source. + /// + virtual void play() = 0; + + /// + /// Stop playing source. + /// + virtual void stop() = 0; + + /// + /// Pause source. + /// + virtual void pause() = 0; + + /// + /// Resume source. + /// + virtual void resume() = 0; + + /// + /// Rewind source. + /// + virtual void rewind() = 0; + + /// + /// Whether the source is playing or not. + /// + virtual bool isStopped() const = 0; + + /// + /// Whether the source is paused or not. + /// + virtual bool isPaused() const = 0; + + /// + /// Set source pitch. + /// + /// @param pitch Pitch of source. + /// + virtual void setPitch(float pitch) = 0; + + /// + /// Set volume of source. + /// + /// @param volume Volume of source. + /// + virtual void setVolume(float volume) = 0; + + /// + /// Set source loop. + /// + /// @param loop Looping or not. + /// + virtual void setLoop(bool loop) = 0; + + /// + /// Set source rate. + /// + /// @param rate Rate of source. + /// + virtual void setRate(float rate) = 0; + + protected: + + /// + /// Get type of source data. + /// + static SourceType getType(const void* mem, int size); + + }; + + } // namespace Audio +} // namespace JinEngine + +#endif // jin_audio + +#endif // __JE_AUDIO_SOURCE_H
\ No newline at end of file diff --git a/src/libjin/Audio/source.cpp b/src/libjin/Audio/source.cpp deleted file mode 100644 index 61f4055..0000000 --- a/src/libjin/Audio/source.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include <cstring> -#include "source.h" - -namespace jin -{ -namespace audio -{ - - static int check_header(const void *data, int size, const char *str, int offset) { - int len = strlen(str); - return (size >= offset + len) && !memcmp((char*)data + offset, str, len); - } - - SourceType Source::getType(const void* mem, int size) - { - if(check_header(mem, size, "WAVE", 8)) - return SourceType::WAV; - if(check_header(mem, size, "OggS", 0)) - return SourceType::OGG; - return SourceType::INVALID; - } - -} -} -#endif // JIN_MODULES_AUDIO
\ No newline at end of file diff --git a/src/libjin/Common/Data.h b/src/libjin/Common/Data.h deleted file mode 100644 index 4b0f1ba..0000000 --- a/src/libjin/Common/Data.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __JIN_COMMON_DATA_H -#define __JIN_COMMON_DATA_H - - - -namespace jin -{ - - class DataBuffer - { - public: - DataBuffer(int n) - : len(n) - { - buffer = new char[len]; - memset(buffer, 0, len); - } - ~DataBuffer() - { - delete[] buffer; - } - char* operator&() - { - return buffer; - } - - private: - char* buffer; - int len; - }; - -} // jin - -#endif
\ No newline at end of file diff --git a/src/libjin/Common/Object.cpp b/src/libjin/Common/Object.cpp deleted file mode 100644 index 6c3b667..0000000 --- a/src/libjin/Common/Object.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// LOVE -#include "Object.h" - -namespace jin -{ - - Object::Object() - : count(1) - { - } - - Object::~Object() - { - } - - int Object::getReferenceCount() const - { - return count; - } - - void Object::retain() - { - ++count; - } - - void Object::release() - { - if (--count <= 0) - delete this; - } - -} // love diff --git a/src/libjin/Common/Object.h b/src/libjin/Common/Object.h deleted file mode 100644 index 9ac1b5a..0000000 --- a/src/libjin/Common/Object.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __JIN_COMMON_OBJECT_H -#define __JIN_COMMON_OBJECT_H - -namespace jin -{ - - class Object - { - private: - - // The reference count. - int count; - - public: - - /** - * Constructor. Sets reference count to one. - **/ - Object(); - - /** - * Destructor. - **/ - virtual ~Object() = 0; - - /** - * Gets the reference count of this Object. - * @returns The reference count. - **/ - int getReferenceCount() const; - - /** - * Retains the Object, i.e. increases the - * reference count by one. - **/ - void retain(); - - /** - * Releases one reference to the Object, i.e. decrements the - * reference count by one, and potentially deletes the Object - * if there are no more references. - **/ - void release(); - - }; // Object - -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Common/Singleton.hpp b/src/libjin/Common/Singleton.hpp deleted file mode 100644 index 48cd5bc..0000000 --- a/src/libjin/Common/Singleton.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __JIN_SINGLETON_H -#define __JIN_SINGLETON_H - -namespace jin -{ - - template<class T> - class Singleton - { - public: - static T* get() - { - if (_instance == nullptr) - _instance = new T; - return _instance; - } - static void destroy() - { - delete _instance; - _instance = nullptr; - } - protected: - Singleton() {}; - virtual ~Singleton() {}; - static T* _instance; - private: - Singleton(const Singleton&); - Singleton& operator = (const Singleton&); - }; - - template<class T> T* Singleton<T>::_instance = nullptr; - -#define SINGLETON(T) \ - friend Singleton<T> - -} // jin - -#endif // __JIN_SINGLETON_H
\ No newline at end of file diff --git a/src/libjin/Common/Subsystem.hpp b/src/libjin/Common/Subsystem.hpp deleted file mode 100644 index 1374ad1..0000000 --- a/src/libjin/Common/Subsystem.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __JIN_COMMON_SUBSYSTEM_H -#define __JIN_COMMON_SUBSYSTEM_H - -#include "singleton.hpp" -#include "../utils/macros.h" - -namespace jin -{ - - template<class System> - class Subsystem : public Singleton<System> - { - public: - struct Setting {}; - typedef Setting SettingBase; - - bool init(const SettingBase* setting = nullptr) - { - static bool success = initSystem(setting); - return success; - } - - void quit() - { - CALLONCE(quitSystem()); - Singleton<System>::destroy(); - } - - protected: - - Subsystem() {}; - virtual ~Subsystem() {}; - - SINGLETON(System); - - /*onlyonce*/ virtual bool initSystem(const Setting* setting) = 0; - /*onlyonce*/ virtual void quitSystem() = 0; - - }; - -} // jin - -#endif
\ No newline at end of file diff --git a/src/libjin/Common/data.h b/src/libjin/Common/data.h deleted file mode 100644 index 4b0f1ba..0000000 --- a/src/libjin/Common/data.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __JIN_COMMON_DATA_H -#define __JIN_COMMON_DATA_H - - - -namespace jin -{ - - class DataBuffer - { - public: - DataBuffer(int n) - : len(n) - { - buffer = new char[len]; - memset(buffer, 0, len); - } - ~DataBuffer() - { - delete[] buffer; - } - char* operator&() - { - return buffer; - } - - private: - char* buffer; - int len; - }; - -} // jin - -#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_array.hpp b/src/libjin/Common/je_array.hpp new file mode 100644 index 0000000..361f1f0 --- /dev/null +++ b/src/libjin/Common/je_array.hpp @@ -0,0 +1,123 @@ +#ifndef __JE_COMMON_ARRAY_H +#define __JE_COMMON_ARRAY_H + +namespace JinEngine +{ + + /// + /// A array created on heap. + /// + template<typename T> + class Array + { + public: + /// + /// Array constructor. + /// + Array() + : length(0) + , data(nullptr) + { + } + + /// + /// Array constructor. + /// + /// @param l Length of array. + /// + Array(int l) + { + length = l; + data = new T[l]; + } + + /// + /// Array destructor. + /// + ~Array() + { + delete[] data; + length = 0; + } + + /// + /// Get address of data. + /// + /// @return Address of data. + /// + T* operator &() + { + return data; + } + + /// + /// Get specific element of array. + /// + /// @return Element of array. + /// + T& operator[](int index) + { + return data[index]; + } + + /// + /// Bind data with given data. + /// + /// @param data Data pointer. + /// @param length Length of data. + /// + void bind(T* data, int length) + { + if (data != nullptr) + delete data; + this->data = data; + this->length = length; + } + + /// + /// Add an element. + /// + /// @param v Value of element. + /// + void add(T value) + { + int len = length + 1; + T* d = new T[len]; + memcpy(d, data, size()); + d[length] = value; + bind(d, len); + } + + /// + /// Get size of data in byte. + /// + /// @return Size of data in byte. + /// + int size() + { + return sizeof(T) * length; + } + + /// + /// Get length of data. + /// + /// @return Count of data. + /// + int count() + { + return length; + } + + private: + // Disable new and delete. + void* operator new(size_t t); + void operator delete(void* ptr); + + T * data; + unsigned int length; + + }; + +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_common.h b/src/libjin/Common/je_common.h new file mode 100644 index 0000000..0dfa79a --- /dev/null +++ b/src/libjin/Common/je_common.h @@ -0,0 +1,6 @@ +#ifndef __JE_COMMON_H +#define __JE_COMMON_H + +#include "je_array.hpp" + +#endif
\ No newline at end of file diff --git a/src/libjin/Audio/OpenAL/ALAudio.cpp b/src/libjin/Common/je_exception.cpp index e69de29..e69de29 100644 --- a/src/libjin/Audio/OpenAL/ALAudio.cpp +++ b/src/libjin/Common/je_exception.cpp diff --git a/src/libjin/Common/je_exception.h b/src/libjin/Common/je_exception.h new file mode 100644 index 0000000..7c66af8 --- /dev/null +++ b/src/libjin/Common/je_exception.h @@ -0,0 +1,22 @@ +#ifndef __JE_EXCEPTION_H +#define __JE_EXCEPTION_H + +#include <exception> + +namespace JinEngine +{ + + /// + /// Built-in exception class. + /// + class JinException : public std::exception + { + public: + JinException(); + const char* what() const throw(); + + }; + +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_noncopyable.h b/src/libjin/Common/je_noncopyable.h new file mode 100644 index 0000000..89a3e68 --- /dev/null +++ b/src/libjin/Common/je_noncopyable.h @@ -0,0 +1,24 @@ +#ifndef __JE_NONCOPYABLE_H +#define __JE_NONCOPYABLE_H + +namespace JinEngine +{ + + /// + /// Class inherites this could not be copied. + /// + class Noncopyable + { + public: + Noncopyable(void) { } + virtual ~Noncopyable(void) { } + + private: + Noncopyable(const Noncopyable& other); + Noncopyable& operator=(const Noncopyable& other); + + }; + +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_object.h b/src/libjin/Common/je_object.h new file mode 100644 index 0000000..c256879 --- /dev/null +++ b/src/libjin/Common/je_object.h @@ -0,0 +1,16 @@ +#ifndef __JE_OBJECT_H +#define __JE_OBJECT_H + +namespace JinEngine +{ + + /// + /// Base class of all objects in Jin. + /// + class Object + { + }; + +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_pool.hpp b/src/libjin/Common/je_pool.hpp new file mode 100644 index 0000000..1107fd5 --- /dev/null +++ b/src/libjin/Common/je_pool.hpp @@ -0,0 +1,11 @@ +#ifndef __JE_POOL_H +#define __JE_POOL_H + +namespace JinEngine +{ + + + +} + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_singleton.hpp b/src/libjin/Common/je_singleton.hpp new file mode 100644 index 0000000..e981e7a --- /dev/null +++ b/src/libjin/Common/je_singleton.hpp @@ -0,0 +1,80 @@ +#ifndef __JE_SINGLETON_H +#define __JE_SINGLETON_H + +namespace JinEngine +{ + + /// + /// Singleton base class. + /// + template<class T> + class Singleton + { + public: + /// + /// Get singleton. + /// + /// @param Singleton instance of class. + /// + static T* get() + { + if (_instance == nullptr) + _instance = new T; + return _instance; + } + + /// + /// Destroy instance of singleton. + /// + static void destroy() + { + delete _instance; + _instance = nullptr; + } + + protected: + /// + /// Singleton constructor. + /// + Singleton() {}; + + /// + /// Singleton destructor. + /// + virtual ~Singleton() {}; + + /// + /// Singleton instance. + /// + static T* _instance; + + private: + /// + /// Singleton copy constructor. + /// + /// @param singleton Singleton of class. + /// + Singleton(const Singleton& singleton); + + /// + /// Singleton assignment. + /// + /// @param singleton Singleton of class. + /// + Singleton& operator = (const Singleton& singleton); + + }; + + /// + /// Singleton instance. + /// + template<class T> T* Singleton<T>::_instance = nullptr; + + /// + /// Singleton notation. + /// + #define singleton(T) friend Singleton<T> + +} // namespace JinEngine + +#endif // __JE_SINGLETON_H
\ No newline at end of file diff --git a/src/libjin/Common/StringMap.hpp b/src/libjin/Common/je_stringmap.hpp index bebd94d..43e3e9b 100644 --- a/src/libjin/Common/StringMap.hpp +++ b/src/libjin/Common/je_stringmap.hpp @@ -1,7 +1,7 @@ -#ifndef __JIN_COMMON_SREINGMAP_H -#define __JIN_COMMON_SREINGMAP_H +#ifndef __JE_COMMON_SREINGMAP_H +#define __JE_COMMON_SREINGMAP_H -namespace jin +namespace JinEngine { template<typename T, unsigned SIZE> @@ -138,6 +138,6 @@ namespace jin }; // StringMap -} +} // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/libjin/Common/je_subsystem.hpp b/src/libjin/Common/je_subsystem.hpp new file mode 100644 index 0000000..d8e106d --- /dev/null +++ b/src/libjin/Common/je_subsystem.hpp @@ -0,0 +1,78 @@ +#ifndef __JE_COMMON_SUBSYSTEM_H +#define __JE_COMMON_SUBSYSTEM_H + +#include "../utils/je_macros.h" + +#include "je_singleton.hpp" + +namespace JinEngine +{ + + /// + /// Subsystem class. + /// + template<class System> + class Subsystem : public Singleton<System> + { + public: + /// + /// Subsystem setting. + /// + struct Setting + { + }; + + typedef Setting SettingBase; + + /// + /// Initialize subsystem. + /// + /// @param setting Subsystem setting. + /// @return True if initialize sucessful, otherwise return false. + /// + bool init(const SettingBase* setting = nullptr) + { + static bool success = initSystem(setting); + return success; + } + + /// + /// Quit subsystem. + /// + void quit() + { + // Call only once. + static char __dummy__ = (quitSystem(), 1); + Singleton<System>::destroy(); + } + + protected: + singleton(System); + + /// + /// Subsystem constructor. + /// + Subsystem() {}; + + /// + /// Subsystem destructor. + /// + virtual ~Subsystem() + { + }; + + /// + /// Initializer callback. + /// + virtual bool initSystem(const Setting* setting) = 0; + + /// + /// Quit subsystem callback. + /// + virtual void quitSystem() = 0; + + }; + +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_temporary.h b/src/libjin/Common/je_temporary.h new file mode 100644 index 0000000..5af8704 --- /dev/null +++ b/src/libjin/Common/je_temporary.h @@ -0,0 +1,31 @@ +#ifndef __JE_ON_STACK_H +#define __JE_ON_STACK_H + +namespace JinEngine +{ + + /// + /// Class inherites this clound only be created on stack or static zone. + /// + class Temporary + { + public: + Temporary() {}; + virtual ~Temporary() {}; +/* + protected: + void operator delete(void* t) + { + if(t != nullptr) + free(t); + } +*/ + private: + // Disable new operands. + void* operator new(size_t); + + }; + +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/je_types.h b/src/libjin/Common/je_types.h new file mode 100644 index 0000000..446c413 --- /dev/null +++ b/src/libjin/Common/je_types.h @@ -0,0 +1,23 @@ +#ifndef __JE_TYPES_H +#define __JE_TYPES_H +#include <stdint.h> + +namespace JinEngine +{ + + typedef int8_t int8; ///< Signed integer with a size of 8 bits. Supports values from -128 to 127 + typedef uint8_t uint8; ///< Unsigned integer with a size of 8 bits. Supports values from 0 to 255. + typedef uint8 byte; ///< Unsigned integer with 8 bits (1 byte). Supports 256 values from 0 to 255. + typedef int16_t int16; ///< Signed integer with a size of 16 bits. Supports values from -32768 to 32767 + typedef uint16_t uint16; ///< Unsigned integer with a size of 16 bits. Supports values from 0 to 65535. + typedef int32_t int32; ///< Signed integer with a size of 32 bits. Supports values from -2147483648 to 2147483647. + typedef uint32_t uint32; ///< Unsigned integer with a size of 32 bits. Supports values from 0 to 4294967295, (2^32 - 1). + typedef int64_t int64; ///< Signed integer with a size of 64 bits. Supports values from -(2^63) to (2^63 - 1). + typedef uint64_t uint64; ///< Unsigned integer with a size of 64 bits, Supports values from 0 to (2^64 - 1). + + typedef uint32_t uint; + typedef int32_t sint; + +} + +#endif
\ No newline at end of file diff --git a/src/libjin/Common/utf8.cpp b/src/libjin/Common/je_utf8.cpp index bef6c85..bd7ce94 100644 --- a/src/libjin/Common/utf8.cpp +++ b/src/libjin/Common/je_utf8.cpp @@ -1,9 +1,9 @@ -#include "../modules.h" -#if JIN_OS == JIN_WINDOWS +#include "../core/je_configuration.h" +#if jin_os == jin_os_windows -#include "utf8.h" +#include "je_utf8.h" -namespace jin +namespace JinEngine { std::string to_utf8(LPCWSTR wstr) @@ -37,6 +37,6 @@ namespace jin } } -} // jin +} // namespace JinEngine -#endif // JIN_OS == JIN_WINDOWS
\ No newline at end of file +#endif // jin_os == jin_os_windows
\ No newline at end of file diff --git a/src/libjin/Common/je_utf8.h b/src/libjin/Common/je_utf8.h new file mode 100644 index 0000000..a11850c --- /dev/null +++ b/src/libjin/Common/je_utf8.h @@ -0,0 +1,34 @@ +#ifndef __JE_COMMON_UTF8_H +#define __JE_COMMON_UTF8_H + +#include "../core/je_configuration.h" +#if jin_os == jin_os_windows + +#include <string> +#include <windows.h> + +namespace JinEngine +{ + + /// + /// Convert the wide string to a UTF-8 encoded string. + /// + /// @param wstr The wide-char string. + /// @return A UTF-8 string. + /// + std::string to_utf8(LPCWSTR wstr); + + /// + /// Replace all occurences of 'find' with 'replace' in a string. + /// + /// @param str The string to modify. + /// @param find The character to match. + /// @param replace The character to replace matches. + /// + void replace_char(std::string & str, char find, char replace); + +} // namespace JinEngine + +#endif // jin_os == jin_os_windows + +#endif // __JE_COMMON_UTF8_H
\ No newline at end of file diff --git a/src/libjin/Common/utf8.h b/src/libjin/Common/utf8.h deleted file mode 100644 index 7f26841..0000000 --- a/src/libjin/Common/utf8.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __JIN_COMMON_UTF8_H -#define __JIN_COMMON_UTF8_H - -#include "../modules.h" -#if JIN_OS == JIN_WINDOWS - -#include <string> -#include <windows.h> - -namespace jin -{ - - /** - * Convert the wide string to a UTF-8 encoded string. - * @param wstr The wide-char string. - * @return A UTF-8 string. - **/ - std::string to_utf8(LPCWSTR wstr); - - /** - * Replace all occurences of 'find' with 'replace' in a string. - * @param str The string to modify. - * @param find The character to match. - * @param replace The character to replace matches. - **/ - void replace_char(std::string & str, char find, char replace); - -} - -#endif // JIN_OS == JIN_WINDOWS -#endif // __JIN_COMMON_UTF8_H
\ No newline at end of file diff --git a/src/libjin/Core/Core.h b/src/libjin/Core/Core.h deleted file mode 100644 index dd902b4..0000000 --- a/src/libjin/Core/Core.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __JIN_CORE_H -#define __JIN_CORE_H - -#include "game.h" - -#endif
\ No newline at end of file diff --git a/src/libjin/Core/Game.cpp b/src/libjin/Core/Game.cpp deleted file mode 100644 index b480b12..0000000 --- a/src/libjin/Core/Game.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "game.h" -#include "../Time/Timer.h" -#include "../input/Event.h" -#include "../Graphics/Window.h" -#include "../Math/Math.h" -#include <iostream> - -namespace jin -{ -namespace core -{ - - using namespace jin::graphics; - using namespace jin::input; - using namespace jin::time; - using namespace jin::math; - - Game::Game() :_running(true) {}; - - void Game::run() - { - SAFECALL(_onLoad); - Window* wnd = Window::get(); - const int FPS = wnd ? wnd->getFPS() : 60; - const int MS_PER_UPDATE = 1000.0f / FPS; - _running = true; - Event e; - int previous = getMilliSecond(); - int dt = MS_PER_UPDATE; - while (_running) - { - while (jin::input::pollEvent(&e)) - { - SAFECALL(_onEvent, &e); - if (!_running) goto quitloop; - } - SAFECALL(_onUpdate, dt); - SAFECALL(_onDraw); - wnd->swapBuffers(); - const int current = getMilliSecond(); - dt = current - previous; - const int wait = MS_PER_UPDATE - (current - previous); - previous += MS_PER_UPDATE; - if (wait > 0) - { - sleep(wait); - dt = MS_PER_UPDATE; - } - else - previous = current; - } - quitloop:; - } - - bool Game::initSystem(const SettingBase* setting) - { - if (setting == nullptr) - return false; - Game::Setting* s = (Game::Setting*) setting; - _onEvent = s->eventHandler; - _onUpdate = s->updater; - _onDraw = s->drawer; - _onLoad = s->loader; - return true; - } - - void Game::quitSystem() - { - } - -} // core -} // jin
\ No newline at end of file diff --git a/src/libjin/Core/Game.h b/src/libjin/Core/Game.h deleted file mode 100644 index 31f32d8..0000000 --- a/src/libjin/Core/Game.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __JIN_CORE_GAME_H -#define __JIN_CORE_GAME_H - -#include "SDL2/SDL.h" - -#include "../Common/Subsystem.hpp" -#include "../utils/macros.h" -#include "../Input/Event.h" - -namespace jin -{ -namespace core -{ - - class Game : public Subsystem<Game> - { - public: - - typedef void(*onLoad)(); - typedef void(*onEvent)(jin::input::Event* e); - typedef void(*onUpdate)(int dt); - typedef void(*onDraw)(); - - struct Setting : SettingBase - { - onEvent eventHandler; - onUpdate updater; - onDraw drawer; - onLoad loader; - }; - - void run(); - inline void stop() { _running = false; }; - inline bool running() { return _running; }; - - private: - - Game(); - ~Game() {}; - - SINGLETON(Game); - - onEvent _onEvent; - onUpdate _onUpdate; - onDraw _onDraw; - onLoad _onLoad; - - bool _running; - - bool initSystem(const SettingBase* setting); - void quitSystem(); - - }; - -} // core -} // jin - -#endif // __JIN_CORE_GAME_H
\ No newline at end of file diff --git a/src/libjin/Core/README.md b/src/libjin/Core/README.md new file mode 100644 index 0000000..b393007 --- /dev/null +++ b/src/libjin/Core/README.md @@ -0,0 +1 @@ +ļµļƱṩһЩ汾Ϣ
\ No newline at end of file diff --git a/src/libjin/Core/je_configuration.h b/src/libjin/Core/je_configuration.h new file mode 100644 index 0000000..34c3a74 --- /dev/null +++ b/src/libjin/Core/je_configuration.h @@ -0,0 +1,53 @@ +#ifndef __JE_COMMON_MODULES_H +#define __JE_COMMON_MODULES_H + +#define jin_undefined 0x00 + +#define jin_debug + +#define jin_os_windows 0x01 +#define jin_os_mac 0x02 +#define jin_os_linux 0x03 +#define jin_os jin_os_windows + +#define jin_graphics_font 0x02 +#define jin_graphics_shader 0x04 +#define jin_graphics_particle 0x08 +#define jin_graphics_animation 0x10 +#define jin_graphics (jin_graphics_font|jin_graphics_shader) + +#define jin_audio_sdl 0x01 +#define jin_audio_openal 0x02 +#define jin_audio jin_audio_sdl + +#define jin_filesystem_smount 0x01 +#define jin_filesystem jin_filesystem_smount + +#define jin_game + +#define jin_core + +#define jin_input_sdl 0x01 +#define jin_input jin_input_sdl + +#define jin_math + +#define jin_net_tekcos 0x01 +#define jin_net jin_net_tekcos + +#define jin_physics_newton 0x01 +#define jin_physics_box2d 0x02 +//#define jin_physics jin_physics_newton + +#define jin_thread_sdl 0x01 +#define jin_thread_cpp 0x02 +#define jin_thread_pthread 0x03 +#define jin_thread jin_thread_sdl + +#define jin_time_sdl 0x01 +#define jin_time_cpp 0x02 +#define jin_time jin_time_sdl + +#define jin_ai + +#endif // __JE_COMMON_MODULES_H
\ No newline at end of file diff --git a/src/libjin/Core/je_version.h b/src/libjin/Core/je_version.h new file mode 100644 index 0000000..77302c6 --- /dev/null +++ b/src/libjin/Core/je_version.h @@ -0,0 +1,52 @@ +#ifndef __JE_CORE_VERSION_H +#define __JE_CORE_VERSION_H + +namespace JinEngine +{ + namespace Core + { + + /// + /// Get version of Jin. + /// + /// @return Version of Jin. + /// + const char* getVersion() + { + return "Jin 0.1"; + } + + /// + /// Get author of Jin. + /// + /// @return Author of Jin. + /// + const char* getAuthor() + { + return "Chai"; + } + + /// + /// Get release of Jin. + /// + /// @return release string of Jin. + /// + const char* getRelease() + { + return "Jin 0.1.1"; + } + + /// + /// Get release of Jin. + /// + /// @return Revision of Jin. + /// + int getRevision() + { + return 101; + } + + } // namespace Core +} // namespace JinEngine + +#endif // __JE_CORE_VERSION_H
\ No newline at end of file diff --git a/src/libjin/Debug/Debug.h b/src/libjin/Debug/Debug.h deleted file mode 100644 index 9fa9fe1..0000000 --- a/src/libjin/Debug/Debug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __JIN_DEBUG_H -#define __JIN_DEBUG_H - - - -#endif
\ No newline at end of file diff --git a/src/libjin/Debug/Log.h b/src/libjin/Debug/Log.h deleted file mode 100644 index e1624f5..0000000 --- a/src/libjin/Debug/Log.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __JIN_LOG_H -#define __JIN_LOG_H - -namespace jin -{ -namespace debug -{ - - const char* err; - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Filesystem/Buffer.h b/src/libjin/Filesystem/Buffer.h deleted file mode 100644 index 1d72083..0000000 --- a/src/libjin/Filesystem/Buffer.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __JIN_BUFFER_H -#define __JIN_BUFFER_H - -#include <string.h> - -namespace jin -{ -namespace filesystem -{ - - class Buffer - { - public: - - inline Buffer(): data(0), size(0) - { - } - - inline Buffer(const Buffer& src) - { - delete data; - size = src.size; - data = new char[size]; - memcpy(data, src.data, size); - } - - inline Buffer(void* d, int s) - { - data = new char(size); - memcpy(data, d, size); - size = s; - } - - inline ~Buffer() - { - size = 0; - delete[] data; - } - - public: - - // data position in memory - void* data; - - // data buffer size - unsigned int size; - - }; - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Filesystem/Filesystem.cpp b/src/libjin/Filesystem/Filesystem.cpp deleted file mode 100644 index e9b05e3..0000000 --- a/src/libjin/Filesystem/Filesystem.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "filesystem.h" -#include <string.h> -#include <stdlib.h> -#include <stdio.h> /* defines FILENAME_MAX */ - -namespace jin -{ -namespace filesystem -{ - - Filesystem* Filesystem::fs = 0; - - Filesystem::Filesystem() - { - S = smtnewshared(); - } - - Filesystem* Filesystem::get() - { - return fs ? fs : (fs = new Filesystem()); - } - - /** - * r is relative path - */ - void Filesystem::mount(const char * path) - { - int err = smtmount(S, path); - if (err) - { - printf("%s mounted path %s", smterrstr(err), path); - exit(1); - } - } - - /** - * - */ - int Filesystem::read(const char* path, Buffer* buffer) - { - buffer->data = smtread(S, path, &buffer->size); - if (buffer->data == 0) - return 0; - return 1; - } - - const char* Filesystem::getFull(const char* path) - { - return smtfullpath(S, path); - } - - bool Filesystem::isDir(const char* path) - { - return smtisdir(S, path); - } - - bool Filesystem::isFile(const char* path) - { - return smtisreg(S, path); - } - - bool Filesystem::exists(const char* path) - { - return smtexists(S, path) == 0; - } - -} -}
\ No newline at end of file diff --git a/src/libjin/Filesystem/Filesystem.h b/src/libjin/Filesystem/Filesystem.h deleted file mode 100644 index ba0fdc5..0000000 --- a/src/libjin/Filesystem/Filesystem.h +++ /dev/null @@ -1,56 +0,0 @@ -#include "buffer.h" -#include "../3rdparty/smount/smount.h" - -namespace jin -{ -namespace filesystem -{ - - class Filesystem - { - public: - - Filesystem(); - - static Filesystem* get(); - - /** - * is a path a directroy or a single file - */ - bool isDir(const char* path); - - /** - * is a path a directroy or a single file - */ - bool isFile(const char* path); - - /** - * is path a valid path - */ - bool exists(const char* path); - - /** - * read a file and return data buffer - */ - int read(const char* path, Buffer* buffer); - - /** - * set root directory, can only mount once. - */ - void mount(const char* root); - - /** - * convret relative path to absolute path - */ - const char* getFull(const char* path); - - private: - - static Filesystem* fs; - - smtShared* S; - - }; - -} -}
\ No newline at end of file diff --git a/src/libjin/Filesystem/je_asset_database.cpp b/src/libjin/Filesystem/je_asset_database.cpp new file mode 100644 index 0000000..ac547f0 --- /dev/null +++ b/src/libjin/Filesystem/je_asset_database.cpp @@ -0,0 +1,85 @@ +#include "../core/je_configuration.h" +#if defined(jin_filesystem) + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> /* defines FILENAME_MAX */ + +#include "je_asset_database.h" + +namespace JinEngine +{ + namespace Filesystem + { + + AssetDatabase* AssetDatabase::mAssetDatabase = 0; + + AssetDatabase::AssetDatabase() + { + mSmt = smtnewshared(); + } + + AssetDatabase* AssetDatabase::get() + { + return mAssetDatabase ? mAssetDatabase : (mAssetDatabase = new AssetDatabase()); + } + + void AssetDatabase::mount(const char * path) + { + int err = smtmount(mSmt, path); + if (err) + { + printf("%s mounted path %s", smterrstr(err), path); + exit(1); + } + } + + bool AssetDatabase::read(const char* path, Buffer& buffer) + { + size_t size; + byte* data = (byte*)smtread(mSmt, path, &size); + if (data == nullptr) + return false; + buffer.bind(data, size); + return true; + } + + Buffer* read(const char* path) + { + return nullptr; + } + + void* AssetDatabase::read(const char* path, unsigned int* len) + { + return smtread(mSmt, path, len); + } + + const char* AssetDatabase::getFull(const char* path) + { + return smtfullpath(mSmt, path); + } + + bool AssetDatabase::isDir(const char* path) + { + return smtisdir(mSmt, path); + } + + bool AssetDatabase::isFile(const char* path) + { + return smtisreg(mSmt, path); + } + + bool AssetDatabase::exists(const char* path) + { + return smtexists(mSmt, path) == 0; + } + + std::vector<std::string> AssetDatabase::getFiles(const char* path, bool recursive) + { + + } + + } // namespace Filesystem +} // namespace JinEngine + +#endif // jin_filesystem
\ No newline at end of file diff --git a/src/libjin/Filesystem/je_asset_database.h b/src/libjin/Filesystem/je_asset_database.h new file mode 100644 index 0000000..8c30fc1 --- /dev/null +++ b/src/libjin/Filesystem/je_asset_database.h @@ -0,0 +1,114 @@ +#ifndef __JE_ASSET_DATABASE_H +#define __JE_ASSET_DATABASE_H + +#include "../core/je_configuration.h" +#if defined(jin_filesystem) + +#include <vector> + +#include "../3rdparty/smount/smount.h" + +#include "je_buffer.h" + +namespace JinEngine +{ + namespace Filesystem + { + + /// + /// Assets managment. + /// + class AssetDatabase + { + public: + /// + /// Get asset database singleton. + /// + /// @param Singleton of asset database. + /// + static AssetDatabase* get(); + + /// + /// Asset database constructor. + /// + AssetDatabase(); + + /// + /// Set asset root folder. + /// + /// @param root Root folder of assets. + /// + void mount(const char* root); + + /// + /// Check if the path is directory. + /// + /// @param path Path under asset folder. + /// @return True if the given path is directory, otherwise return false. + /// + bool isDir(const char* path); + + /// + /// Check if the path is file. + /// + /// @param path Path under asset folder. + /// @return True if the given path is file, otherwise return false. + /// + bool isFile(const char* path); + + /// + /// Check if the path exists. + /// @param path Given path. + /// @return True if path exists, otherwise return false. + /// + bool exists(const char* path); + + /// + /// Read file into a buffer. + /// + /// @param path Path of file. + /// @param buffer Buffer to fill. + /// @return True if read sucessful, otherwise return false. + /// + bool read(const char* path, Buffer& buffer); + + /// + /// Read file and return data content. + /// + /// @param path Path of file. + /// @param length Length of data. + /// @return Data if read sucessful, otherwise return null. + /// + void* read(const char* path, unsigned int* length); + + /// + /// Get files under given directory. + /// + /// @param path Path of directory. + /// @param recursive Recursivily search folder. + /// @return File list under given directory. + /// + std::vector<std::string> getFiles(const char* path, bool recursive); + + /// + /// Get full path of asset. + /// + /// @param path Path of asset. + /// @return Full path of asset. + /// + const char* getFull(const char* path); + + private: + static AssetDatabase* mAssetDatabase; +#if jin_filesystem == jin_filesystem_smount + smtShared* mSmt; +#endif + + }; + + } // namespace Filesystem +} // namespace JinEngine + +#endif // jin_filesystem + +#endif
\ No newline at end of file diff --git a/src/libjin/Filesystem/je_buffer.h b/src/libjin/Filesystem/je_buffer.h new file mode 100644 index 0000000..0726e1d --- /dev/null +++ b/src/libjin/Filesystem/je_buffer.h @@ -0,0 +1,169 @@ +#ifndef __JE_BUFFER_H +#define __JE_BUFFER_H + +#include "../core/je_configuration.h" +#if defined(jin_filesystem) + +#include <string.h> +#include <stdlib.h> + +#include "../common/je_temporary.h" +#include "../common/je_types.h" + +namespace JinEngine +{ + namespace Filesystem + { + + /// + /// Data buffer allocated on heap. + /// + class Buffer : public Temporary + { + public: + /// + /// Buffer constructor. + /// + Buffer() + : mData(0) + , mSize(0) + { + } + + /// + /// Copy constructor. + /// + /// @param src Buffer source. + /// + Buffer(const Buffer& src) + { + delete[] mData; + mSize = src.mSize; + mData = new byte[mSize]; + memcpy(mData, src.mData, mSize); + } + + /// + /// Buffer constructor. + /// + /// @param data Buffer data. + /// @param size Size of buffer. + /// + Buffer(void* data, int size) + { + mSize = size; + mData = new byte[mSize]; + memcpy(mData, data, mSize); + } + + /// + /// Buffer constructor. + /// + /// @param size Size of data. + /// + Buffer(size_t size) + { + mData = new byte[size]; + memset(mData, 0, size); + mSize = size; + } + + /// + /// Buffer destructor. + /// + ~Buffer() + { + delete[] mData; + mSize = 0; + } + + /// + /// Set buffer data. + /// + /// @param data Buffer data. + /// @param size Size of data. + /// + void set(byte* data, size_t size) + { + if (data == nullptr) + return; + if (mSize != size) + { + delete mData; + mData = new byte[size]; + } + mSize = size; + memcpy(mData, data, size); + } + + /// + /// Bind buffer data. + /// + /// @param data Buffer data. + /// @param size Size of buffer. + /// + void bind(byte* data, size_t size) + { + if (mData != nullptr) + delete mData; + mSize = size; + mData = data; + } + + /// + /// Buffer assignment. + /// + /// @param buffer Buffer to copy. + /// + void operator = (const Buffer& buffer) + { + delete[] mData; + mSize = buffer.mSize; + mData = new byte[mSize]; + memcpy(mData, buffer.mData, mSize); + } + + /// + /// Get data addresss. + /// + /// @return Data address. + /// + const byte* operator &() + { + return mData; + } + + /// + /// Get data size. + /// + /// @return Size of data. + /// + const inline size_t size() + { + return mSize; + } + + /// + /// Clear data. + /// + void clear() + { + if (mData == nullptr) + return; + delete mData; + mData = nullptr; + mSize = 0; + } + + private: + byte* mData; + size_t mSize; + + }; + + } // namespace Filesystem +} // namespace JinEngine + +#endif // jin_filesystem + +#endif
\ No newline at end of file diff --git a/src/libjin/Game/je_entity.cpp b/src/libjin/Game/je_entity.cpp new file mode 100644 index 0000000..1396518 --- /dev/null +++ b/src/libjin/Game/je_entity.cpp @@ -0,0 +1,11 @@ +#include "je_entity.h" + +namespace JinEngine +{ + namespace Game + { + + + + } // namespace Game +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Game/je_entity.h b/src/libjin/Game/je_entity.h new file mode 100644 index 0000000..4a252da --- /dev/null +++ b/src/libjin/Game/je_entity.h @@ -0,0 +1,75 @@ +#ifndef __JE_GAME_OBJECT_H +#define __JE_GAME_OBJECT_H + +#include "../core/je_configuration.h" +#if defined(jin_game) + +#include <list> +#include <map> +#include <set> + +#include "../common/je_object.h" +#include "../common/je_types.h" + +namespace JinEngine +{ + namespace Game + { + + /// + /// Game object base class. + /// + class Entity : public Object + { + public: + + /// + /// + /// + virtual ~Entity(); + + /// + /// + /// + void lifecycle(); + + /// + /// + /// + void setVisible(bool isVisible); + + /// + /// + /// + void setActive(bool isActive); + + protected: + virtual void onAlive(); + virtual void onUpdate(float dt); + virtual void onDraw(); + virtual void onDie(); + + uint32 layer; // layer where entity belongs + uint32 index; // render index in layer + uint64 tag; // tag of entity, 64 now + bool mIsVisible; // if the entity is visible or not + bool mIsActive; // if the entity is joined into the logic + + }; + + /// + /// Entity list. For quickly adding and removing entities. + /// + typedef std::list<Entity*> EntityList; + + /// + /// Entity set. For searching and keeps entities unique and sorted. + /// + typedef std::set<Entity*> EntitySet; + + } // namespace Game +} // namespace JinEngine + +#endif // jin_game + +#endif
\ No newline at end of file diff --git a/src/libjin/Game/je_game.cpp b/src/libjin/Game/je_game.cpp new file mode 100644 index 0000000..6eb1d3f --- /dev/null +++ b/src/libjin/Game/je_game.cpp @@ -0,0 +1,79 @@ +#include "../core/je_configuration.h" +#if defined(jin_game) + +#include <iostream> + +#include "../time/je_timer.h" +#include "../input/je_event.h" +#include "../graphics/je_window.h" +#include "../math/je_math.h" + +#include "je_game.h" + +namespace JinEngine +{ + namespace Core + { + + using namespace JinEngine::Graphics; + using namespace JinEngine::Input; + using namespace JinEngine::Time; + using namespace JinEngine::Math; + + Game::Game() :_running(true) {}; + + /* default game loop */ + void Game::run() + { + if (_onLoad != nullptr) + _onLoad(); + Window* wnd = Window::get(); + const int FPS = wnd ? wnd->getFPS() : 60; + const int MS_PER_UPDATE = 1000.0f / FPS; + _running = true; + Event e; + int current = getMilliSecond(); + int previous = current; + int dt = 0; + while (_running) + { + while (JinEngine::Input::pollEvent(&e)) + { + if (_onEvent != nullptr) + _onEvent(&e); + if (!_running) + goto quitloop; + } + previous = current; + current = getMilliSecond(); + dt = current - previous; + if (_onUpdate != nullptr) + _onUpdate(dt); + if (_onDraw != nullptr) + _onDraw(); + wnd->swapBuffers(); + sleep(1); + } + quitloop:; + } + + bool Game::initSystem(const SettingBase* setting) + { + if (setting == nullptr) + return false; + Game::Setting* s = (Game::Setting*) setting; + _onEvent = s->eventHandler; + _onUpdate = s->updater; + _onDraw = s->drawer; + _onLoad = s->loader; + return true; + } + + void Game::quitSystem() + { + } + + } // namespace Core +} // namespace JinEngine + +#endif // jin_game
\ No newline at end of file diff --git a/src/libjin/Game/je_game.h b/src/libjin/Game/je_game.h new file mode 100644 index 0000000..78c3385 --- /dev/null +++ b/src/libjin/Game/je_game.h @@ -0,0 +1,88 @@ +#ifndef __JE_CORE_GAME_H +#define __JE_CORE_GAME_H + +#include "../core/je_configuration.h" +#if defined(jin_game) + +#include "../common/je_subsystem.hpp" +#include "../utils/je_macros.h" +#include "../input/je_Event.h" + +#include "SDL2/SDL.h" + +namespace JinEngine +{ + namespace Core + { + + /// + /// Game class. + /// + class Game : public Subsystem<Game> + { + public: + + typedef void(*onLoad)(); + typedef void(*onEvent)(JinEngine::Input::Event* e); + typedef void(*onUpdate)(int dt); + typedef void(*onDraw)(); + + /// + /// Game setting. + /// + struct Setting : SettingBase + { + onEvent eventHandler; + onUpdate updater; + onDraw drawer; + onLoad loader; + }; + + /// + /// Main game loop. + /// + void run(); + + /// + /// Stop game. + /// + inline void stop() + { + _running = false; + }; + + /// + /// Return if game is running. + /// + /// @return True if game is running, otherwise return false. + /// + inline bool running() + { + return _running; + }; + + private: + + Game(); + ~Game() {}; + + singleton(Game); + + onEvent _onEvent; + onUpdate _onUpdate; + onDraw _onDraw; + onLoad _onLoad; + + bool _running; + + bool initSystem(const SettingBase* setting); + void quitSystem(); + + }; + + } // namespace Core +} // namespace JinEngine + +#endif // jin_game + +#endif // __JE_CORE_GAME_H
\ No newline at end of file diff --git a/src/libjin/Audio/OpenAL/ALAudio.h b/src/libjin/Game/je_scene.cpp index e69de29..e69de29 100644 --- a/src/libjin/Audio/OpenAL/ALAudio.h +++ b/src/libjin/Game/je_scene.cpp diff --git a/src/libjin/Game/je_scene.h b/src/libjin/Game/je_scene.h new file mode 100644 index 0000000..f510a1f --- /dev/null +++ b/src/libjin/Game/je_scene.h @@ -0,0 +1,73 @@ +#ifndef __JE_GAME_SCENE_H +#define __JE_GAME_SCENE_H + +#include "../core/je_configuration.h" +#if defined(jin_game) + +#include <map> +#include <list> + +#include "je_entity.h" + +namespace JinEngine +{ + namespace Game + { + + /// + /// Handle all entities. + /// + class Scene + { + public: + /// + /// + /// + void addEntity(Entity* entity); + + /// + /// + /// + EntityList& getEntitiesByTag(uint64 tag); + + /// + /// + /// + EntityList& getEntitiesByLayer(uint32 layer); + + /// + /// + /// + void setEntitiesActiveByTag(uint64 tag); + + /// + /// + /// + void setEntitiesActiveByLayer(uint32 layer); + + /// + /// + /// + void removeEntitiesByLayer(uint32 layer); + + /// + /// + /// + void removeEntitiesByTag(uint64 tag); + + protected: + // all entities + EntitySet entities; + // all entities grouped by layer, render order + std::map<uint32, EntityList> layers; + // all entities grouped by tag + std::map<uint64, EntityList> tags; + + }; + + } // namespace Game +} // namespace JinEngine + +#endif // jin_game + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Canvas.cpp b/src/libjin/Graphics/Canvas.cpp deleted file mode 100644 index f5bd09f..0000000 --- a/src/libjin/Graphics/Canvas.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "../utils/macros.h" -#include "canvas.h" -#include "window.h" - -namespace jin -{ -namespace graphics -{ - - shared Canvas* Canvas::createCanvas(int w, int h) - { - return new Canvas(w, h); - } - - Canvas::Canvas(int w, int h) - : Drawable(w, h) - { - init(); - } - - Canvas::~Canvas() - { - } - - shared GLint Canvas::cur = -1; - - bool Canvas::init() - { - setVertices( - new float [DRAWABLE_V_SIZE] { - 0, 0, - 0, (float)height, - (float)width, (float)height, - (float)width, 0, - }, - new float [DRAWABLE_V_SIZE] { - 0, 1, - 0, 0, - 1, 0, - 1, 1 - } - ); - - GLint current_fbo; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - - // generate a new render buffer object - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - // generate texture save target - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - // unbind framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, current_fbo); - - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) - return false; - return true; - } - - bool Canvas::hasbind(GLint fbo) - { - return cur == fbo; - } - - /** - * bind to canvas - */ - void Canvas::bind() - { - if (hasbind(fbo)) return; - - cur = fbo; - - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glViewport(0, 0, width, height); - glOrtho(0, width, height, 0, -1, 1); - - // Switch back to modelview matrix - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - } - - /** - * bind to default screen render buffer. - */ - shared void Canvas::unbind() - { - if (hasbind(0)) return; - - cur = 0; - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - Window* wnd = Window::get(); - int ww = wnd->getW(), - wh = wnd->getH(); - - glViewport(0, 0, ww, wh); - - // load back to normal - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - // set viewport matrix - glOrtho(0, ww, wh, 0, -1, 1); - - // switch to model matrix - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - } - -} // render -} // jin - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Canvas.h b/src/libjin/Graphics/Canvas.h deleted file mode 100644 index 0d5635e..0000000 --- a/src/libjin/Graphics/Canvas.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __JIN_CANVAS_H -#define __JIN_CANVAS_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "drawable.h" -namespace jin -{ -namespace graphics -{ - class Canvas: public Drawable - { - public: - - static Canvas* createCanvas(int w, int h); - - ~Canvas(); - - void bind(); - - static void unbind(); - - static bool hasbind(GLint fbo); - - protected: - - Canvas(int w, int h); - - GLuint fbo; - - // current binded fbo - static GLint cur; - - bool init(); - }; -} // render -} // jin - -#endif // JIN_MODULES_RENDER -#endif // __JIN_CANVAS_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Color.h b/src/libjin/Graphics/Color.h deleted file mode 100644 index a78234e..0000000 --- a/src/libjin/Graphics/Color.h +++ /dev/null @@ -1,31 +0,0 @@ -/** -* Some color operating here. -*/ -#ifndef __JIN_COLOR_H -#define __JIN_COLOR_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "../utils/endian.h" - -namespace jin -{ -namespace graphics -{ - - union color { - struct { -#if JIN_BYTEORDER == JIN_BIG_ENDIAN - unsigned char r, g, b, a; -#else - unsigned char a, b, g, r; -#endif - }rgba; - int word; - }; - -} // render -} // jin - -#endif // JIN_MODULES_RENDER -#endif // __JIN_COLOR_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Drawable.cpp b/src/libjin/Graphics/Drawable.cpp deleted file mode 100644 index cab6c50..0000000 --- a/src/libjin/Graphics/Drawable.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "drawable.h" -#include "../math/matrix.h" -#include <stdlib.h> - -namespace jin -{ -namespace graphics -{ - Drawable::Drawable(int w, int h):texture(0), width(w), height(h), ancx(0), ancy(0), textCoord(0), vertCoord(0) - { - } - - Drawable::~Drawable() - { - glDeleteTextures(1, &texture); - delete[] vertCoord; - delete[] textCoord; - } - - void Drawable::setVertices(float* v, float* t) - { - // render area - if (vertCoord) - delete[] vertCoord; - vertCoord = v; - - // textrue - if (textCoord) - delete[] textCoord; - textCoord = t; - } - - void Drawable::setAnchor(int x, int y) - { - ancx = x; - ancy = y; - } - - void Drawable::draw(int x, int y, float sx, float sy, float r) - { - // Must set textCoord and vertCoord before renderring - if (! textCoord||! vertCoord) return; - - static jin::math::Matrix t; - t.setTransformation(x, y, r, sx, sy, ancx, ancy); - - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, texture); - - // push modle matrix - glPushMatrix(); - glMultMatrixf((const GLfloat*)t.getElements()); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, textCoord); - glVertexPointer(2, GL_FLOAT, 0, vertCoord); - glDrawArrays(GL_QUADS, 0, 4); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - // pop the model matrix - glPopMatrix(); - - // bind texture to default screen - glBindTexture(GL_TEXTURE_2D, 0); - - glDisable(GL_TEXTURE_2D); - } -} // render -} // jin - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Drawable.h b/src/libjin/Graphics/Drawable.h deleted file mode 100644 index e04ac6b..0000000 --- a/src/libjin/Graphics/Drawable.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __JIN_DRAWABLE -#define __JIN_DRAWABLE -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "../3rdparty/GLee/GLee.h" -namespace jin -{ -namespace graphics -{ - - class Drawable - { - public: - Drawable(int w = 0, int h = 0); - virtual ~Drawable(); - - void setAnchor(int x, int y); - - void draw(int x, int y, float sx, float sy, float r); - - inline int getWidth() const - { - return width; - } - - inline int getHeight() const - { - return height; - } - - inline GLuint getTexture() const - { - return texture; - }; - - protected: - - const int DRAWABLE_V_SIZE = 8; - - void setVertices(float* v, float* t); - - GLuint texture; - - int width, height; - - /* anchor point */ - int ancx, ancy; - - // render coords - float* textCoord; - float* vertCoord; - - }; - -} // render -} // jin - -#endif // JIN_MODULES_RENDER -#endif // __JIN_DRAWABLE
\ No newline at end of file diff --git a/src/libjin/Graphics/Font.cpp b/src/libjin/Graphics/Font.cpp deleted file mode 100644 index a107613..0000000 --- a/src/libjin/Graphics/Font.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "font.h" -#include <stdio.h> -#define STB_TRUETYPE_IMPLEMENTATION -#include "../3rdparty/stb/stb_truetype.h" -#include "color.h" - -namespace jin -{ -namespace graphics -{ - - using namespace jin::math; - - const int BITMAP_WIDTH = 512; - const int BITMAP_HEIGHT = 512; - const int PIXEL_HEIGHT = 32; - - Font::Font():Drawable() - { - } - - // ttf file read buffer - static unsigned char ttf_buffer[1 << 20]; - - // bitmap for saving font data - static unsigned char temp_bitmap[BITMAP_WIDTH * BITMAP_HEIGHT]; - - void Font::loadf(const char* path) - { - fread(ttf_buffer, 1, 1 << 20, fopen(path, "rb")); - - loadb(ttf_buffer); - } - - /** - * load from memory - */ - void Font::loadb(const unsigned char* data) - { - stbtt_BakeFontBitmap(data, 0, PIXEL_HEIGHT, temp_bitmap, BITMAP_WIDTH, BITMAP_HEIGHT, 32, 96, cdata); - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_WIDTH, - BITMAP_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glBindTexture(GL_TEXTURE_2D, 0); - } - - /** - * get texture quad - */ - static Quad getCharQuad(const stbtt_bakedchar* chardata, int pw, int ph, int char_index) - { - float ipw = 1.0f / pw, iph = 1.0f / ph; - const stbtt_bakedchar *b = chardata + char_index; - Quad q; - q.x = b->x0 * ipw; - q.y = b->y0 * iph; - q.w = b->x1 * ipw - b->x0 * ipw; - q.h = b->y1 * iph - b->y0 * iph; - return q; - } - - /** - * render function draw mutiple times - * in loop - */ - void Font::render( - const char* text, // rendered text - float x, float y, // render position - int fheight, // font height - int spacing, // font spacing - int lheight) // line height - { - float _x = x, - _y = y; - - int len = strlen(text); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // for saving clip quad - stbtt_aligned_quad q; - - // render every given character - int xc = x; - int yc = y; - - float factor = fheight / (float)PIXEL_HEIGHT; - - for (int i = 0; i < len; ++i) - { - char c = text[i]; - if (c == '\n') - { - xc = x; - yc += lheight; - continue; - } - - // only support ASCII - Quad q = getCharQuad(cdata, 512, 512, c - 32); - float s0 = q.x, - s1 = q.x + q.w, - t0 = q.y, - t1 = q.y + q.h; - - // texture quad - float tc[] = { - s0, t1, - s1, t1, - s1, t0, - s0, t0 - }; - - // character bound box - stbtt_bakedchar box = cdata[c - 32]; - - float width = factor * (box.x1 - box.x0); - float height = factor * (box.y1 - box.y0); - float xoffset = factor * box.xoff; - // I don't know why add PIXEL_HEIGHT to box.yoff, but - // it works. - float yoffset = factor * (box.yoff + PIXEL_HEIGHT); - float xadvance = factor * box.xadvance; - - // render quad - float vc[] = { - xc + xoffset, yc + height + yoffset, - xc + width + xoffset, yc + height + yoffset, - xc + width + xoffset, yc + yoffset, - xc + xoffset, yc + yoffset - }; - - // forward to next character - xc += xadvance + spacing; - - glTexCoordPointer(2, GL_FLOAT, 0, tc); - glVertexPointer(2, GL_FLOAT, 0, vc); - glDrawArrays(GL_QUADS, 0, 4); - } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - } - - void Font::box(const char* str, int fheight, int spacing, int lheight, int* w, int * h) - { - int len = strlen(str); - - float xc = 0; - int yc = len ? lheight: 0; - int maxX = 0; - - float factor = fheight / (float)PIXEL_HEIGHT; - - for (int i = 0; i < len; ++i) - { - char c = str[i]; - if (c == '\n') - { - yc += lheight; - xc = 0; - continue; - } - stbtt_bakedchar box = cdata[c - 32]; - - xc += factor * box.xadvance + spacing; - if (xc > maxX) maxX = xc; - } - - *w = maxX; - *h = yc; - } - -} -} - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Font.h b/src/libjin/Graphics/Font.h deleted file mode 100644 index 7fc96e2..0000000 --- a/src/libjin/Graphics/Font.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __JIN_FONT_H -#define __JIN_FONT_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "drawable.h" -#include "../3rdparty/stb/stb_truetype.h" -#include "../math/quad.h" - -namespace jin -{ -namespace graphics -{ - /** - * Usage of stb_truetype.h here might be a little - * bit dummy. Implementation of Font is referring - * to stb_truetype.h L243~284. I basicly copy it:) - */ - class Font: public Drawable - { - public: - - Font(); - - /** - * load ttf font data from .ttf - */ - void loadf(const char* file); - - /** - * load ttf font data from memory - */ - void loadb(const unsigned char* data); - - /** - * render text to screen - */ - void render( - const char* str, // rendered text - float x, float y, // render position - int fheight, // font size - int spacing, // font spacing - int lheight // line height - ); - - void box(const char* str, int fheight, int spacing, int lheight, int* w, int * h); - - private: - - /** - * ASCII 32(space)..126(~) is 95 glyphs - */ - stbtt_bakedchar cdata[96]; - - }; - -} -} - -#endif // JIN_MODULES_RENDER -#endif // __JIN_FONT_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_decoder.cpp b/src/libjin/Graphics/Font/je_decoder.cpp new file mode 100644 index 0000000..01e1990 --- /dev/null +++ b/src/libjin/Graphics/Font/je_decoder.cpp @@ -0,0 +1,93 @@ +#include <stdlib.h> +#include <string.h> +#include "je_decoder.h" + +namespace JinEngine +{ + namespace Graphics + { + + /* utf8 byte string to unicode codepoint */ + static const char *utf8toCodepoint(const char *p, unsigned *res) { + return nullptr; + + } + + ///////////////////////////////////////////////////////////////////////////// + // decoders + ///////////////////////////////////////////////////////////////////////////// + + const void* Utf8::decode(const void* data, Codepoint* res) const + { + const char* p = (char*)data; + unsigned x, mask, shift; + switch (*p & 0xf0) { + case 0xf0: mask = 0x07; shift = 18; break; + case 0xe0: mask = 0x0f; shift = 12; break; + case 0xc0: + case 0xd0: mask = 0x1f; shift = 6; break; + default: + *res = *p; + return p + 1; + } + x = (*p & mask) << shift; + do { + if (*(++p) == '\0') { + *res = x; + return p; + } + shift -= 6; + x |= (*p & 0x3f) << shift; + } while (shift); + *res = x; + return p + 1; + } + + const void* Utf8::next(const void* data) const + { + const char* p = (char*)data; + unsigned x, mask, shift; + switch (*p & 0xf0) { + case 0xf0: mask = 0x07; shift = 18; break; + case 0xe0: mask = 0x0f; shift = 12; break; + case 0xc0: + case 0xd0: mask = 0x1f; shift = 6; break; + default: + return p + 1; + } + x = (*p & mask) << shift; + do { + if (*(++p) == '\0') { + return p; + } + shift -= 6; + x |= (*p & 0x3f) << shift; + } while (shift); + return p + 1; + } + /* + const void* Utf16::decode(const void* data, Codepoint* res) const + { + return nullptr; + } + + const void* Utf16::next(const void* data) const + { + return nullptr; + } + */ + const void* Ascii::decode(const void* data, Codepoint* res) const + { + const char* p = (char*)data; + *res = *p; + return p + 1; + } + + const void* Ascii::next(const void* data) const + { + const char* p = (char*)data; + return p + 1; + } + + } // namespace Graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_decoder.h b/src/libjin/Graphics/Font/je_decoder.h new file mode 100644 index 0000000..36cbda7 --- /dev/null +++ b/src/libjin/Graphics/Font/je_decoder.h @@ -0,0 +1,94 @@ +#ifndef __JE_UTF8_H +#define __JE_UTF8_H + +#include <vector> + +#include "je_text.h" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// Text decoder. + /// + class Decoder + { + public: + + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + virtual const void* decode(const void* data, Codepoint* codepoint) const = 0 ; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + virtual const void* next(const void* data) const = 0; + + }; + + /// + /// Utf-8 decoder. + /// + class Utf8 : public Decoder + { + public: + + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + const void* decode(const void* data, Codepoint* codepoint) const override; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + const void* next(const void* data) const override; + + }; + + /// + /// Ascii decoder. + /// + class Ascii : public Decoder + { + public: + + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + const void* decode(const void* data, Codepoint* codepoint) const override; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + const void* next(const void* data) const override; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_font.h b/src/libjin/Graphics/Font/je_font.h new file mode 100644 index 0000000..4529902 --- /dev/null +++ b/src/libjin/Graphics/Font/je_font.h @@ -0,0 +1,100 @@ +#ifndef __JE_FONT_H +#define __JE_FONT_H + +#include <vector> +#include "je_text.h" + +namespace JinEngine +{ + namespace Graphics + { + + struct Page; + + /// + /// Base Font class. + /// + class Font + { + public: + /// + /// Font constructor. + /// + Font(unsigned fontsize) + : mFontSize(fontsize) + { + } + + /// + /// Font destructor. + /// + virtual ~Font() {}; + + /// + /// Create page with given text. + /// + /// @param text Text to be typesetted. + /// @param lineheight Line height of text. + /// @param spacing Spacing between characters. 0 by default. + /// @return Page if created successfully, otherwise return null. + /// + virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; + + /// + /// Create page with given unicode codepoints. + /// + /// @param content Unicode codepoints to be typesetted. + /// @param lineheight Line height of text. + /// @param spacing Spacing between characters. 0 by default. + /// @return Page if created successfully, otherwise return null. + /// + virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0; + + /// + /// Render page to given position. + /// + /// @param page Page to be rendered. + /// @param x X value of the position. + /// @param y Y value of the position. + /// + virtual void print(const Page* page, int x, int y) = 0; + + /// + /// Render unicode codepoints to given position. + /// + /// @param content Unicode codepoints to be typesetted. + /// @param x X value of the position. + /// @param y Y value of the position. + /// @param lineheight Line height of the content. + /// @param spacing Spacing between characters. + /// + virtual void print(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0; + + /// + /// Render text to given position. + /// + /// @param text Text to be rendered. + /// @param x X value of the position. + /// @param y Y value of the position. + /// @param lineheight Line height of the text. + /// @param spacing Spacing between characters. + /// + virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; + + /// + /// Get font size. + /// + /// @return Font size. + /// + inline unsigned getFontSize() { return mFontSize; }; + + protected: + + unsigned mFontSize; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // __JE_FONT_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_page.h b/src/libjin/Graphics/Font/je_page.h new file mode 100644 index 0000000..fbc297e --- /dev/null +++ b/src/libjin/Graphics/Font/je_page.h @@ -0,0 +1,51 @@ +#ifndef __JE_PAGE_H +#define __JE_PAGE_H + +#include "../../math/je_vector2.hpp" + +#include "je_font.h" + +namespace JinEngine +{ + namespace Graphics + { + + class Font; + + /// + /// Glyphs data to be rendered. + /// + struct GlyphVertex + { + int x, y; ///< screen coordinates + float u, v; ///< normalized texture uv + }; + + /// + /// Glyphs info for reducing draw call. + /// + struct GlyphArrayDrawInfo + { + GLuint texture; ///< atlas + unsigned int start; ///< glyph vertex indecies + unsigned int count; ///< glyph vertex count + }; + + /// + /// Page to be rendered. + /// + /// A page is a pre-rendered text struct for reducing draw call. Each page + /// keeps a font pointer which should not be changed. + /// + struct Page + { + Font* font; + std::vector<GlyphArrayDrawInfo> glyphinfolist; + std::vector<GlyphVertex> glyphvertices; + Math::Vector2<int> size; + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // __JE_PAGE_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_text.cpp b/src/libjin/Graphics/Font/je_text.cpp new file mode 100644 index 0000000..75dfc7b --- /dev/null +++ b/src/libjin/Graphics/Font/je_text.cpp @@ -0,0 +1,154 @@ +#include <cstring> + +#include "je_text.h" +#include "je_decoder.h" + +namespace JinEngine +{ + namespace Graphics + { + + ///////////////////////////////////////////////////////////////////////////// + // iterator + ///////////////////////////////////////////////////////////////////////////// + + Text::Iterator::Iterator(const Iterator& itor) + : data(itor.data) + , p(itor.p) + , encode(itor.encode) + , length(itor.length) + { + switch (encode) + { + case Encode::UTF8: decoder = new Utf8(); break; + case Encode::ASCII: decoder = new Ascii(); break; + } + } + + Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length) + : data(_data) + , p(_data) + , encode(_encode) + , length(_length) + { + switch (encode) + { + case Encode::UTF8: decoder = new Utf8(); break; + case Encode::ASCII: decoder = new Ascii(); break; + } + } + + Text::Iterator::~Iterator() + { + delete decoder; + } + + Codepoint Text::Iterator::get() + { + Codepoint codepoint; + decoder->decode(p, &codepoint); + return codepoint; + } + + Codepoint Text::Iterator::operator*() + { + return get(); + } + /* + Text::Iterator Text::Iterator::begin() + { + Iterator itor(encode, data, length); + itor.toBegin(); + return itor; + } + + Text::Iterator Text::Iterator::end() + { + Iterator itor(encode, data, length); + itor.toEnd(); + return itor; + } + */ + void Text::Iterator::toBegin() + { + p = (const unsigned char*)data; + } + + void Text::Iterator::toEnd() + { + p = (const unsigned char*)data + length; + } + + Text::Iterator& Text::Iterator::operator ++() + { + p = decoder->next(p); + return *this; + } + + Text::Iterator Text::Iterator::operator ++(int) + { + p = decoder->next(p); + Iterator itor(encode, data, length); + itor.p = p; + return itor; + } + + bool Text::Iterator::operator !=(const Iterator& itor) + { + return !(data == itor.data + && p == itor.p + && length == itor.length + && encode == itor.encode); + } + + bool Text::Iterator::operator ==(const Iterator& itor) + { + return data == itor.data + && p == itor.p + && length == itor.length + && encode == itor.encode; + } + + ///////////////////////////////////////////////////////////////////////////// + // text + ///////////////////////////////////////////////////////////////////////////// + + Text::Text(Encode encode, const void* data) + { + unsigned length = strlen((const char*)data); + Iterator end = Iterator(encode, data, length); + end.toEnd(); + Iterator it = Iterator(encode, data, length); + for (; it != end; ++it) + { + content.push_back(*it); + } + } + + Text::Text(Encode encode, const void* data, unsigned length) + { + Iterator end = Iterator(encode, data, length); + end.toEnd(); + Iterator it = Iterator(encode, data, length); + for (; it != end; ++it) + { + content.push_back(*it); + } + } + + Text::~Text() + { + } + + const Content& Text::getContent() const + { + return content; + } + + const Content& Text::operator*() const + { + return content; + } + + } // namespace Graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_text.h b/src/libjin/Graphics/Font/je_text.h new file mode 100644 index 0000000..7436875 --- /dev/null +++ b/src/libjin/Graphics/Font/je_text.h @@ -0,0 +1,169 @@ +#ifndef __JE_TEXT_H +#define __JE_TEXT_H + +#include <vector> + +namespace JinEngine +{ + namespace Graphics + { + + typedef unsigned int Codepoint; + + typedef std::vector<Codepoint> Content; + + class Text; + + class Decoder; + + /// + /// Supported text encoding. + /// + enum Encode + { + UTF8, ///< utf-8 + ASCII, ///< ASCII + }; + + /// + /// Decoded text. Saved as unicode codepoints. + /// + class Text + { + public: + /// + /// + /// + Text(Encode encode, const void* data); + + /// + /// + /// + Text(Encode encode, const void* data, unsigned int length); + + /// + /// + /// + ~Text(); + + /// + /// + /// + const Content& getContent() const; + + /// + /// + /// + const Content& operator*() const; + + private: + /// + /// + /// + class Iterator + { + public: + + /// + /// + /// + Iterator(const Iterator& itor); + + /// + /// + /// + Iterator(const Encode& encode, const void* data, unsigned int length); + + /// + /// + /// + ~Iterator(); + + /// + /// + /// + Codepoint get(); + + //Iterator begin(); + //Iterator end(); + + /// + /// + /// + void toBegin(); + + /// + /// + /// + void toEnd(); + + /// + /// + /// + Codepoint operator *(); + + /// + /// + /// + Iterator& operator ++(); + + /// + /// + /// + Iterator operator ++(int); + + /// + /// + /// + bool operator !=(const Iterator& itor); + + /// + /// + /// + bool operator ==(const Iterator& itor); + + private: + + /// + /// + /// + void operator = (const Iterator&); + + /// + /// + /// + const Encode encode; + + /// + /// + /// + const Decoder* decoder; + + /// + /// + /// + const void* p; + + /// + /// + /// + const void* const data; + + /// + /// + /// + unsigned int length; + + }; + + /// + /// + /// + Content content; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_texture_font.cpp b/src/libjin/Graphics/Font/je_texture_font.cpp new file mode 100644 index 0000000..9651c1a --- /dev/null +++ b/src/libjin/Graphics/Font/je_texture_font.cpp @@ -0,0 +1,318 @@ +#include <vector> + +#include "../../math/je_vector2.hpp" + +#include "../shader/je_shader.h" + +#include "je_texture_font.h" + +namespace JinEngine +{ + namespace Graphics + { + + using namespace std; + using namespace Math; + + TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, codepoints, cellw, cellh); + return tf; + } + + TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, int cellw, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, *codepoints, cellw, cellh); + return tf; + } + + TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, codepoints, mask, cellh); + return tf; + } + + TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, Color mask, int cellh) + { + TextureFont* tf = new TextureFont(bitmap, *codepoints, mask, cellh); + return tf; + } + + TextureFont::~TextureFont() + { + } + + const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const + { + auto it = glyphs.find(codepoint); + if (it != glyphs.end()) + { + return &it->second; + } + else + return nullptr; + } + + Page* TextureFont::typeset(const Content& text, int lineheight, int spacing) + { + Page* page = new Page(); + page->font = this; + vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + vector<GlyphVertex>& glyphvertices = page->glyphvertices; + int texture = -1; + const TextureGlyph* glyph = nullptr; + GlyphVertex vertex; + Vector2<int> p(0, 0); + int i = 0; + + #define glyphvertices_push(_x, _y, _u, _v) \ + vertex.x = _x; vertex.y = _y;\ + vertex.u = _u; vertex.v = _v;\ + glyphvertices.push_back(vertex);\ + + for (Codepoint c : text) + { + // return + if (c == 0x0D) continue; + // newline + if (c == 0x0A) + { + p.y += lineheight; + p.x = 0; + continue; + } + if (c == 0x09) + { + // tab = 4*space + unsigned cw = getCharWidth(0x20); + p.x += cw * 4; + continue; + } + glyph = findGlyph(c); + if (glyph == nullptr) continue; + if (texture != mTexture) + { + texture = mTexture; + GlyphArrayDrawInfo info; + info.start = i; + info.count = 0; + info.texture = texture; + glyphinfolist.push_back(info); + } + glyphinfolist[glyphinfolist.size() - 1].count += 4; + // normalized + float w = getWidth(), h = getHeight(); + float nx = glyph->x / w, ny = glyph->y / h; + float nw = glyph->w / w, nh = glyph->h / h; + glyphvertices_push(p.x, p.y, nx, ny); + glyphvertices_push(p.x, p.y + glyph->h, nx, ny + nh); + glyphvertices_push(p.x + glyph->w, p.y + glyph->h, nx + nw, ny + nh); + glyphvertices_push(p.x + glyph->w, p.y, nx + nw, ny); + p.x += glyph->w + spacing; + i += 4; + } + getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing); + return page; + } + + int TextureFont::getCharWidth(int c) + { + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.w; + } + return 0; + } + + int TextureFont::getCharHeight(int c) + { + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.h; + } + return 0; + } + + int TextureFont::getTextWidth(const Content& t, int spacing) + { + int res = 0; + int tmp = 0; + for (Codepoint c : t) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + continue; + } + if (c == 0x09) + { + // tab = 4*space + unsigned cw = getCharWidth(0x20); + tmp += cw * 4; + if (tmp > res) res = tmp; + continue; + } + tmp += getCharWidth(c) + spacing; + if (tmp > res) res = tmp; + } + return res; + } + + int TextureFont::getTextHeight(const Content& t, int lineheight) + { + int res = 0; + bool newline = true; + for (Codepoint c : t) + { + if (c == 0x0A) + newline = true; + else if (c == 0x0D); + else if (newline) + { + newline = false; + res += lineheight; + } + } + return res; + } + + void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing) + { + *w = 0; + *h = 0; + int tmp = 0; + bool newline = true; + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + newline = true; + continue; + } + else if (newline) + { + newline = false; + *h += lineheight; + } + tmp += getCharWidth(c) + spacing; + if (tmp > *w) + *w = tmp; + } + } + + Page* TextureFont::typeset(const Text& text, int lineheight, int spacing) + { + return typeset(*text, lineheight, spacing); + } + + void TextureFont::print(const Page* page, int x, int y) + { + Shader* shader = Shader::getCurrentShader(); + const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + const vector<GlyphVertex>& glyphvertices = page->glyphvertices; + gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + for (int i = 0; i < glyphinfolist.size(); ++i) + { + const GlyphArrayDrawInfo& info = glyphinfolist[i]; + shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); + shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); + gl.bindTexture(info.texture); + gl.drawArrays(GL_QUADS, 0, info.count); + gl.bindTexture(0); + } + } + + void TextureFont::print(const Content& text, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(text, lineheight, spacing); + print(page, x, y); + delete page; + } + + void TextureFont::print(const Text& text, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(text, lineheight, spacing); + print(page, x, y); + delete page; + } + + TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh) + : Graphic(bitmap) + , Font(cellh) + { + TextureGlyph glyph; + Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh); + glyph.w = cellw; + glyph.h = cellh; + for (int y = 0; y < count.row; ++y) + { + glyph.y = y * cellh; + for (int x = 0; x < count.colum; ++x) + { + glyph.x = x * cellw; + if (x + y * count.colum >= codepoints.size()) + return; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum], glyph)); + } + } + } + + TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh) + : Graphic(bitmap) + , Font(cellh) + { + TextureGlyph glyph; + glyph.h = cellh; + int w = bitmap->getWidth(); + int h = bitmap->getHeight(); + int i = 0; + for (int y = 0; y < h; y += cellh) + { + glyph.y = y; + bool newc = false; + for (int x = 0; x <= w; ++x) + { + if (x == w && newc) + { + glyph.w = x - glyph.x; + if (i >= codepoints.size()) + return; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); + ++i; + newc = false; + break; + } + Color c = bitmap->getPixels()[x + y * w]; + if (!newc && c != mask) + { + glyph.x = x; + newc = true; + } + else if (newc && c == mask) + { + glyph.w = x - glyph.x; + if (i >= codepoints.size()) + return; + glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph)); + if (codepoints[i] == 't') + { + int a = 10; + } + ++i; + newc = false; + } + } + } + } + + } +}
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_texture_font.h b/src/libjin/Graphics/Font/je_texture_font.h new file mode 100644 index 0000000..6276350 --- /dev/null +++ b/src/libjin/Graphics/Font/je_texture_font.h @@ -0,0 +1,140 @@ +#ifndef __JE_TEXTURE_FONT_H +#define __JE_TEXTURE_FONT_H + +#include <map> +#include <vector> + +#include "../../math/je_vector4.hpp" + +#include "../je_graphic.h" +#include "../je_bitmap.h" + +#include "je_page.h" +#include "je_font.h" +#include "je_text.h" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// + /// + class TextureFont : public Font + , public Graphic + { + public: + + /// + /// + /// + static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh); + + /// + /// + /// + static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh); + + /// + /// + /// + static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); + + /// + /// + /// + static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh); + + /// + /// + /// + ~TextureFont(); + + /// + /// + /// + Page* typeset(const Text& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + Page* typeset(const Content& text, int lineheight, int spacing = 0) override ; + + /// + /// + /// + void print(const Page* page, int x, int y) override; + + /// + /// + /// + void print(const Content& text, int x, int y, int linehgiht, int spacing = 0) override; + + /// + /// + /// + void print(const Text& text, int x, int y, int lineheight, int spacing = 0)override; + + private: + + /// + /// + /// + struct TextureGlyph + { + float x, y, w, h; + }; + + /// + /// + /// + TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh); + + /// + /// + /// + TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh); + + /// + /// + /// + int getCharWidth(int c); + + /// + /// + /// + int getCharHeight(int c); + + /// + /// + /// + int getTextWidth(const Content& text, int spacing = 0); + + /// + /// + /// + int getTextHeight(const Content& text, int lineheight); + + /// + /// + /// + void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0); + + /// + /// + /// + const TextureGlyph* findGlyph(Codepoint codepoint) const; + + + /// + /// + /// + std::map<Codepoint, TextureGlyph> glyphs; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_ttf.cpp b/src/libjin/Graphics/Font/je_ttf.cpp new file mode 100644 index 0000000..a11efb0 --- /dev/null +++ b/src/libjin/Graphics/Font/je_ttf.cpp @@ -0,0 +1,463 @@ +#include "../../core/je_configuration.h" +#if defined(jin_graphics) + +#include <stdio.h> + +#include "../../common/je_array.hpp" + +#include "../je_gl.h" +#include "../je_color.h" +#include "../shader/je_shader.h" + +#include "je_ttf.h" +#include "je_page.h" + +#define STB_TRUETYPE_IMPLEMENTATION +#include "../../3rdparty/stb/stb_truetype.h" + +namespace JinEngine +{ + namespace Graphics + { + + ///////////////////////////////////////////////////////////////////////////// + // TTFData + ///////////////////////////////////////////////////////////////////////////// + + TTFData* TTFData::createTTFData(const unsigned char* data, unsigned int size) + { + TTFData* ttf = nullptr; + try + { + ttf = new TTFData(data, size); + return ttf; + } + catch (...) + { + return nullptr; + } + } + + TTFData::TTFData(const unsigned char* d, unsigned int s) + { + raw.size = s; + raw.data = (unsigned char*)malloc(s); + memcpy(raw.data, d, s); + if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0)) + { + delete raw.data; + throw 0; + } + /* push default fontsize */ + pushTTFsize(FONT_SIZE); + } + + TTFData::~TTFData() + { + free(raw.data); + } + + TTF* TTFData::createTTF(unsigned fontSize) + { + TTF* ttf; + try + { + ttf = new TTF(this, fontSize); + } + catch (...) + { + return nullptr; + } + return ttf; + } + + /* + * (0, 0) + * +--------------+ ascent + * | +--------+ | + * | | | | + * | | bitmap | | + * +--|--------|--+ baseline + * | +--------+ | + * +--|-----------+ decent + * | | + * leftSideBearing | + * advanceWidth + */ + void TTFData::getVMetrics(int* baseline, int* descent) + { + float scale = scales.back(); + int ascent; + stbtt_GetFontVMetrics(&info, &ascent, descent, 0); + *baseline = (int)(ascent*scale) + 1; // slight adjustment + *descent = *baseline - (int)(*descent*scale) + 1; + } + + void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing) + { + float scale = scales.back(); + int adw, lsb; + stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb); + *advanceWidth = (int)(adw*scale); + *leftSideBearing = (int)(lsb*scale); + } + + void TTFData::pushTTFsize(unsigned int fs) + { + float sc = stbtt_ScaleForPixelHeight(&info, fs); + scales.push_back(sc); + } + + void TTFData::popTTFsize() + { + /* always keep default ttf size on the bottom of stack */ + if (scales.size() > 1) + scales.pop_back(); + } + + Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const + { + float scale = scales.back(); + Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff); + return bitmap; + } + + Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const + { + float scale = scales.back(); + Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff); + int w = *width, h = *height; + //int xo = *xoff, yo = *yoff; + Color* bitmap32 = new Color[w*h]; + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]); + } + } + free(bitmap); + return bitmap32; + } + + ///////////////////////////////////////////////////////////////////////////// + // TTF + ///////////////////////////////////////////////////////////////////////////// + + #include "../shader/je_font.shader.h" + + using namespace std; + using namespace JinEngine::Math; + + const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 }; + const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 }; + + /* little endian unicode */ + static const char* unicodeLittleEndian(const char* p, unsigned* res) + { + } + + ///*static*/ TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie) + //{ + // TTF* ttf; + // try + // { + // ttf = new TTF(fontData, fontSzie); + // } + // catch (...) + // { + // return nullptr; + // } + // return ttf; + //} + + TTF::TTF(TTFData* f, unsigned int fontSize) + : Font(fontSize) + , cursor(0, 0) + , ttf(f) + { + ttf->pushTTFsize(fontSize); + ttf->getVMetrics(&baseline, &descent); + estimateSize(); + ttf->popTTFsize(); + /* create a default texture */ + createAtlas(); + } + + /* estimate the size of atlas texture */ + void TTF::estimateSize() + { + for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level) + { + if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level]) + { + textureWidth = TEXTURE_WIDTHS[level]; + textureHeight = TEXTURE_HEIGHTS[level]; + break; + } + } + } + + TTF::~TTF() + { + } + + GLuint TTF::createAtlas() + { + GLuint t; + gl.flushError(); + t = gl.genTexture(); + gl.bindTexture(t); + gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE); + if (glGetError() != GL_NO_ERROR) + { + glDeleteTextures(1, &t); + gl.bindTexture(0); + return 0; + } + atlases.push_back(t); + gl.bindTexture(0); + return t; + } + + void TTF::print(const Content& t, int x, int y, int lineheight, int spacing) + { + Page* page = typeset(t, lineheight, spacing); + print(page, x, y); + delete page; + } + + Page* TTF::typeset(const Content& text, int lineheight, int spacing) + { + Page* page = new Page(); + page->font = this; + vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + vector<GlyphVertex>& glyphvertices = page->glyphvertices; + int texture = -1; + TTFGlyph* glyph = nullptr; + GlyphVertex vertex; + Vector2<int> p(0, 0); + int i = 0; + + #define glyphvertices_push(_x, _y, _u, _v) \ + vertex.x = _x; vertex.y = _y;\ + vertex.u = _u; vertex.v = _v;\ + glyphvertices.push_back(vertex); + + #define glyphlize(c)\ + do{\ + glyph = &findGlyph(c); \ + if (texture != glyph->atlas) \ + { \ + GlyphArrayDrawInfo info; \ + info.start = i; \ + info.count = 0; \ + info.texture = glyph->atlas; \ + texture = glyph->atlas; \ + glyphinfolist.push_back(info); \ + } \ + glyphinfolist[glyphinfolist.size() - 1].count += 4; \ + TTFGlyph::Bbox& bbox = glyph->bbox; \ + glyphvertices_push(p.x, p.y, bbox.x, bbox.y); \ + glyphvertices_push(p.x, p.y + glyph->height, bbox.x, bbox.y + bbox.h); \ + glyphvertices_push(p.x + glyph->width, p.y + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \ + glyphvertices_push(p.x + glyph->width, p.y, bbox.x + bbox.w, bbox.y); \ + }while(0) + + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + /* new line */ + p.y += lineheight; + p.x = 0; + continue; + } + if (c == 0x09) + { + // tab = 4*space + unsigned cw = getCharWidth(0x20); + p.x += cw * 4; + continue; + } + glyphlize(c); + p.x += glyph->width + spacing; + i += 4; + } + getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing); + return page; + } + + Page* TTF::typeset(const Text& text, int lineheight, int spacing) + { + return typeset(*text, lineheight, spacing); + } + + void TTF::print(const Page* page, int x, int y) + { + Shader* shader = Shader::getCurrentShader(); + const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; + const vector<GlyphVertex>& glyphvertices = page->glyphvertices; + gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + for (int i = 0; i < glyphinfolist.size(); ++i) + { + const GlyphArrayDrawInfo& info = glyphinfolist[i]; + shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); + shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); + gl.bindTexture(info.texture); + gl.drawArrays(GL_QUADS, 0, info.count); + gl.bindTexture(0); + } + } + + void TTF::print(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */) + { + print(*text, x, y, lineheight, spacing); + } + + int TTF::getCharWidth(int c) + { + int adw, lsb; + ttf->pushTTFsize(mFontSize); + ttf->getHMetrics(c, &adw, &lsb); + ttf->popTTFsize(); + return adw; + } + + int TTF::getCharHeight(int c) + { + return descent; + } + + int TTF::getTextWidth(const Content& t, int spacing) + { + ttf->pushTTFsize(mFontSize); + int res = 0; + int tmp = 0; + for (Codepoint c : t) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + continue; + } + tmp += getCharWidth(c) + spacing; + if (tmp > res) + res = tmp; + } + ttf->popTTFsize(); + return res; + } + + int TTF::getTextHeight(const Content& t, int lineheight) + { + ttf->pushTTFsize(mFontSize); + int res = 0; + bool newline = true; + for (Codepoint c : t) + { + if (c == 0x0A) + newline = true; + else if (c == 0x0D); + else if (newline) + { + newline = false; + res += lineheight; + } + } + ttf->popTTFsize(); + return res; + } + + void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing) + { + ttf->pushTTFsize(mFontSize); + *w = 0; + *h = 0; + int tmp = 0; + bool newline = true; + for (Codepoint c : text) + { + if (c == 0x0D) + continue; + if (c == 0x0A) + { + tmp = 0; + newline = true; + continue; + } + else if (newline) + { + newline = false; + *h += lineheight; + } + tmp += getCharWidth(c) + spacing; + if (tmp > *w) + *w = tmp; + } + ttf->popTTFsize(); + } + + TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character) + { + int w, h, xoff, yoff; + ttf->pushTTFsize(mFontSize); + GLuint atlas = atlases.back(); + const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff); + int adw, lsb; + { + /* bake glyph */ + ttf->getHMetrics(character, &adw, &lsb); + ttf->popTTFsize(); + if (cursor.x + adw > textureWidth ) + { + cursor.x = 0; + cursor.y += descent; + if (cursor.y + descent * 2 > textureHeight) + { + /* create new atlas */ + atlas = createAtlas(); + cursor.y = 0; + } + } + gl.bindTexture(atlas); + gl.texSubImage(cursor.x + xoff, cursor.y + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); + gl.bindTexture(); + delete[] bitmap; + } + TTFGlyph glyph; + glyph.atlas = atlas; + glyph.bbox.x = cursor.x / (float)textureWidth; + glyph.bbox.y = cursor.y / (float)textureHeight; + glyph.bbox.w = adw / (float)textureWidth; + glyph.bbox.h = descent / (float)textureHeight; + glyph.width = adw; + glyph.height = descent; + glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph)); + cursor.x += adw; + return glyphs[character]; + } + + TTF::TTFGlyph& TTF::findGlyph(unsigned int character) + { + map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character); + if (it != glyphs.end()) + return it->second; + else + return bakeGlyph(character); + } + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_ttf.h b/src/libjin/Graphics/Font/je_ttf.h new file mode 100644 index 0000000..e3d63b2 --- /dev/null +++ b/src/libjin/Graphics/Font/je_ttf.h @@ -0,0 +1,288 @@ +#ifndef __JETTF_H +#define __JE_TTF_H +#include "../../core/je_configuration.h" +#if defined(jin_graphics) + +#include <vector> +#include <map> + +#include "../../3rdparty/stb/stb_truetype.h" +#include "../../math/je_quad.h" + +#include "../je_color.h" +#include "../je_graphic.h" + +#include "je_page.h" +#include "je_font.h" +#include "je_text.h" + +namespace JinEngine +{ + namespace Graphics + { + + class TTF; + + // + // TTFData + // |- TTF(14px) + // |- TTF(15px) + // . + // . + // . + // + class TTFData + { + public: + + /// + /// + /// + static TTFData* createTTFData(const unsigned char* data, unsigned int size); + + /// + /// + /// + ~TTFData(); + + /// + /// + /// + TTF* createTTF(unsigned ttfsize); + + /// + /// + /// + void pushTTFsize(unsigned ttfsize); + + /// + /// + /// + void popTTFsize(); + + /// + /// + /// + Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const; + + /// + /// + /// + Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const; + + /// + /// + /// + void getVMetrics(int* baseline, int* descent); + + /// + /// + /// + void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing); + + private: + + /// + /// + /// + static const unsigned int FONT_SIZE = 12; + + /// + /// + /// + TTFData(const unsigned char* data, unsigned int size); + + /// + /// + /// + stbtt_fontinfo info; + + /// + /// + /// + struct + { + unsigned char* data; + unsigned int size; + } raw; + + /// + /// + /// + std::vector<float> scales; + + }; + + class TTF : public Font + { + public: + //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie); + + /// + /// + /// + Page* typeset(const Text& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + Page* typeset(const Content& text, int lineheight, int spacing = 0) override; + + /// + /// + /// + void print(const Text& text, int x, int y, int lineheight, int spacing = 0) override; + + /// + /// + /// + void print(const Content& text, int x, int y, int lineheight, int spacing = 0) override; + + /// + /// + /// + void print(const Page* page, int x, int y) override; + + /// + /// + /// + ~TTF(); + + private: + + friend class TTFData; + + /// + /// + /// + struct TTFGlyph + { + GLuint atlas; + // normalized coordinates + struct Bbox + { + float x, y; + float w, h; + } bbox; + // glyph size in pixel + unsigned int width, height; + }; + + /// + /// + /// + static const int TEXTURE_SIZE_LEVELS_COUNT = 7; + + /// + /// + /// + static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1; + + /// + /// + /// + static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT]; + + /// + /// + /// + static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT]; + + /// + /// + /// + TTF(TTFData* ttf, Codepoint ttfSize); + + /// + /// + /// + void estimateSize(); + + /// + /// + /// + GLuint createAtlas(); + + /// + /// + /// + TTFGlyph& bakeGlyph(Codepoint character); + + /// + /// + /// + TTFGlyph& findGlyph(Codepoint character); + + /// + /// + /// + int getCharWidth(int c); + + /// + /// + /// + int getCharHeight(int c); + + /// + /// + /// + int getTextWidth(const Content& text, int spacing = 0); + + /// + /// + /// + int getTextHeight(const Content& text, int lineheight); + + /// + /// + /// + void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0); + + /// + /// + /// + int textureWidth; + + /// + /// + /// + int textureHeight; + + /// + /// + /// + std::vector<GLuint> atlases; + + /// + /// + /// + std::map<Codepoint, TTFGlyph> glyphs; + + /// + /// + /// + TTFData* ttf; + + /// + /// + /// + int baseline; + + /// + /// + /// + int descent; + + /// + /// + /// + Math::Vector2<float> cursor; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics) + +#endif // __JE_FONT_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Graphics.h b/src/libjin/Graphics/Graphics.h deleted file mode 100644 index 210dadf..0000000 --- a/src/libjin/Graphics/Graphics.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __JIN_GRAPHICS_H -#define __JIN_GRAPHICS_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "canvas.h" -#include "color.h" -#include "font.h" -#include "Shapes.h" -#include "texture.h" -#include "jsl.h" -#include "window.h" - -#endif // JIN_MODULES_RENDER -#endif // __JIN_GRAPHICS_H
\ No newline at end of file diff --git a/src/libjin/Graphics/JSL.cpp b/src/libjin/Graphics/JSL.cpp deleted file mode 100644 index 2ab7ceb..0000000 --- a/src/libjin/Graphics/JSL.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "../utils/macros.h" -#include "jsl.h" -namespace jin -{ -namespace graphics -{ - //vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) - static const char* base_f = " " - //"#version 120 \n" - "#define number float \n" - "#define Image sampler2D \n" - "#define Canvas sampler2D \n" - "#define Color vec4 \n" - "#define Texel texture2D \n" - "#define extern uniform \n" - "uniform Image _tex0_; \n" - "%s \n" - "void main(){ \n" - " gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);\n" - "}\0"; - - /*static*/ JSLProgram* JSLProgram::currentJSLProgram = nullptr; - - JSLProgram* JSLProgram::createJSLProgram(const char* program) - { - return new JSLProgram(program); - } - - JSLProgram::JSLProgram(const char* program) - : currentTextureUnit(0) - { - initialize(program); - } - - JSLProgram::~JSLProgram() - { - destroy(); - } - - inline void JSLProgram::destroy() - { - if (currentJSLProgram == this) - unuse(); - } - - inline void JSLProgram::initialize(const char* program) - { - char* fs = (char*)alloca(strlen(program) + strlen(base_f)); - sprintf(fs, base_f, program); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, (const GLchar**)&fs, NULL); - glCompileShader(fragmentShader); - - pid = glCreateProgram(); - glAttachShader(pid, fragmentShader); - glLinkProgram(pid); - } - - static inline GLint getMaxTextureUnits() - { - GLint maxTextureUnits = 0; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - return maxTextureUnits; - } - - GLint JSLProgram::getTextureUnit(const std::string& name) - { - std::map<std::string, GLint>::iterator texture_unit = texturePool.find(name); - if (texture_unit != texturePool.end()) - return texture_unit->second; - static GLint maxTextureUnits = getMaxTextureUnits(); - if (++currentTextureUnit >= maxTextureUnits) - return 0; - texturePool[name] = currentTextureUnit; - return currentTextureUnit; - } - -#define checkJSL() if (currentJSLProgram != this) return - - void JSLProgram::sendFloat(const char* variable, float number) - { - checkJSL(); - - int loc = glGetUniformLocation(pid, variable); - glUniform1f(loc, number); - } - - void JSLProgram::sendTexture(const char* variable, const Texture* tex) - { - checkJSL(); - - GLint location = glGetUniformLocation(pid, variable); - if (location == -1) - return; - GLint texture_unit = getTextureUnit(variable); - glUniform1i(location, texture_unit); - glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, tex->getTexture()); - glActiveTexture(GL_TEXTURE0); - } - - void JSLProgram::sendCanvas(const char* variable, const Canvas* canvas) - { - checkJSL(); - - GLint location = glGetUniformLocation(pid, variable); - if (location == -1) - return; - GLint texture_unit = getTextureUnit(variable); - glUniform1i(location, texture_unit); - glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, canvas->getTexture()); - glActiveTexture(GL_TEXTURE0); - } - - void JSLProgram::sendVec2(const char* name, float x, float y) - { - checkJSL(); - - int loc = glGetUniformLocation(pid, name); - glUniform2f(loc, x, y); - } - - void JSLProgram::sendVec3(const char* name, float x, float y, float z) - { - checkJSL(); - - int loc = glGetUniformLocation(pid, name); - glUniform3f(loc, x, y, z); - } - - void JSLProgram::sendVec4(const char* name, float x, float y, float z, float w) - { - checkJSL(); - - int loc = glGetUniformLocation(pid, name); - glUniform4f(loc, x, y, z, w); - } - - void JSLProgram::sendColor(const char* name, const color* col) - { - checkJSL(); - - int loc = glGetUniformLocation(pid, name); - glUniform4f(loc, - col->rgba.r / 255.f, - col->rgba.g / 255.f, - col->rgba.b / 255.f, - col->rgba.a / 255.f - ); - } - -} -} - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/JSL.h b/src/libjin/Graphics/JSL.h deleted file mode 100644 index 8d4712b..0000000 --- a/src/libjin/Graphics/JSL.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __JIN_JSL_H -#define __JIN_JSL_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include <string> -#include <map> -#include "color.h" -#include "texture.h" -#include "canvas.h" -#include "../3rdparty/GLee/GLee.h" - -namespace jin -{ -namespace graphics -{ - - class JSLProgram - { - - public: - - static JSLProgram* createJSLProgram(const char* program); - - virtual ~JSLProgram(); - - inline void use() - { - glUseProgram(pid); - currentJSLProgram = this; - } - - static inline void unuse() - { - glUseProgram(0); - currentJSLProgram = nullptr; - } - - void sendFloat(const char* name, float number); - void sendTexture(const char* name, const Texture* image); - void sendVec2(const char* name, float x, float y); - void sendVec3(const char* name, float x, float y, float z); - void sendVec4(const char* name, float x, float y, float z, float w); - void sendCanvas(const char* name, const Canvas* canvas); - void sendColor(const char* name, const color* col); - - static inline JSLProgram* getCurrentJSL() - { - return currentJSLProgram; - } - - protected: - - JSLProgram(const char* program); - - static JSLProgram* currentJSLProgram; - - GLuint pid; - - std::map<std::string, GLint> texturePool; - - GLint currentTextureUnit; - GLint getTextureUnit(const std::string& name); - - inline void initialize(const char* program); - inline void destroy(); - - }; - -} -} - -#endif // JIN_MODULES_RENDER -#endif // __JIN_JSL_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_base.shader.h b/src/libjin/Graphics/Shader/je_base.shader.h new file mode 100644 index 0000000..d6f9d7b --- /dev/null +++ b/src/libjin/Graphics/Shader/je_base.shader.h @@ -0,0 +1,88 @@ +#ifndef __JE_BASE_SHADER_H +#define __JE_BASE_SHADER_H + +static const char* base_shared = R"( +#define Number float +#define Texture sampler2D +#define Canvas sampler2D +#define Color vec4 +#define Vec2 vec2 +#define Vec3 vec3 +#define Vec4 vec4 + +#define texel texture2D + +struct Vertex +{ + vec2 xy; + vec2 uv; +}; + +)"; + +static const int BASE_SHARED_SIZE = strlen(base_shared); + +static const char* base_vertex = R"( +#version 130 core + +%s + +uniform mat4 jin_ProjectionMatrix; +uniform mat4 jin_ModelMatrix; + +in vec2 jin_VertexCoords; +in vec2 jin_TextureCoords; + +out vec4 jin_Color; +out vec2 jin_XY; +out vec2 jin_UV; + +%s + +void main() +{ + vec4 v = jin_ModelMatrix * vec4(jin_VertexCoords, 0, 1.0); + Vertex _v = vert(Vertex(v.xy, jin_TextureCoords)); + gl_Position = jin_ProjectionMatrix * vec4(_v.xy, 0, 1.0f); + jin_Color = gl_Color; + jin_XY = _v.xy; + jin_UV = _v.uv; +} +)"; + +static const int BASE_VERTEX_SHADER_SIZE = strlen(base_vertex) + BASE_SHARED_SIZE; + +#define formatVertexShader(buf, program) sprintf(buf,base_vertex, base_shared, program) + +static const char* base_fragment = R"( +#version 130 core + +%s + +uniform Texture jin_MainTexture; + +in vec4 jin_Color; +in vec2 jin_XY; +in vec2 jin_UV; + +out vec4 jin_OutColor; + +%s + +void main() +{ + jin_OutColor = frag(jin_Color, jin_MainTexture, Vertex(jin_XY, jin_UV)); +} +)"; + +static const int BASE_FRAGMENT_SHADER_SIZE = strlen(base_fragment) + BASE_SHARED_SIZE; + +#define formatFragmentShader(buf, program) sprintf(buf, base_fragment, base_shared, program) + +static const char* SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; +static const char* SHADER_MODEL_MATRIX = "jin_ModelMatrix"; +static const char* SHADER_MAIN_TEXTURE = "jin_MainTexture"; +static const char* SHADER_VERTEX_COORDS = "jin_VertexCoords"; +static const char* SHADER_TEXTURE_COORDS = "jin_TextureCoords"; + +#endif // __JE_BASE_SHADER_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_default.shader.h b/src/libjin/Graphics/Shader/je_default.shader.h new file mode 100644 index 0000000..3f57c44 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_default.shader.h @@ -0,0 +1,21 @@ +// Ĭshader +static const char* default_shader = R"( + +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return col * texel(tex, v.uv); +} + +#END_FRAGMENT_SHADER +)";
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_font.shader.h b/src/libjin/Graphics/Shader/je_font.shader.h new file mode 100644 index 0000000..e04c225 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_font.shader.h @@ -0,0 +1,21 @@ +// shader +static const char* font_shader = R"( + +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return Color(col.rgb, texel(tex, v.uv).a); +} + +#END_FRAGMENT_SHADER +)";
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_jsl_compiler.cpp b/src/libjin/Graphics/Shader/je_jsl_compiler.cpp new file mode 100644 index 0000000..81b14e8 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_jsl_compiler.cpp @@ -0,0 +1,54 @@ +#include "../../core/je_configuration.h" +#if defined(jin_graphics) && (jin_graphics & jin_graphics_shader) + +#include "../../Filesystem/je_buffer.h" + +#include "je_jsl_compiler.h" + +using namespace std; +using namespace JinEngine::Filesystem; + +namespace JinEngine +{ + namespace Graphics + { + +#include "je_base.shader.h" + + bool JSLCompiler::compile(const string& jsl, string* vertex_shader, string* fragment_shader) + { + // parse shader source, need some optimizations + int loc_VERTEX_SHADER = jsl.find("#VERTEX_SHADER"); + int loc_END_VERTEX_SHADER = jsl.find("#END_VERTEX_SHADER"); + int loc_FRAGMENT_SHADER = jsl.find("#FRAGMENT_SHADER"); + int loc_END_FRAGMENT_SHADER = jsl.find("#END_FRAGMENT_SHADER"); + if (loc_VERTEX_SHADER == string::npos + || loc_END_VERTEX_SHADER == string::npos + || loc_FRAGMENT_SHADER == string::npos + || loc_END_FRAGMENT_SHADER == string::npos + ) + return false; + // Load vertex and fragment shader source into buffers. + { + // Compile JSL vertex program. + int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); + *vertex_shader = jsl.substr(start, loc_END_VERTEX_SHADER - start); + Buffer vbuffer = Buffer(vertex_shader->length() + BASE_VERTEX_SHADER_SIZE); + formatVertexShader((char*)&vbuffer, vertex_shader->c_str()); + vertex_shader->assign((char*)&vbuffer); + } + { + // Compile JSL fragment program. + int start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); + *fragment_shader = jsl.substr(start, loc_END_FRAGMENT_SHADER - start); + Buffer fbuffer = Buffer(fragment_shader->length() + BASE_FRAGMENT_SHADER_SIZE); + formatFragmentShader((char*)&fbuffer, fragment_shader->c_str()); + fragment_shader->assign((char*)&fbuffer); + } + return true; + } + + } // namespace Graphics +} // namespace JinEngine + +#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_jsl_compiler.h b/src/libjin/Graphics/Shader/je_jsl_compiler.h new file mode 100644 index 0000000..29129e1 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_jsl_compiler.h @@ -0,0 +1,42 @@ +#ifndef __JE_JSL_COMPILER_H +#define __JE_JSL_COMPILER_H + +#include "../../core/je_configuration.h" +#if defined(jin_graphics) && (jin_graphics & jin_graphics_shader) + +#include <string> + +#include "../../common/je_singleton.hpp" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// Compile JSL into GLSL. + /// + class JSLCompiler : public Singleton<JSLCompiler> + { + public: + /// + /// Compile JSL shader source into GLSL. + /// + /// @param jsl JSL shader source. + /// @param glsl_vertex Output of vertex glsl shader source. + /// @param glsl_fragment Output of fragment glsl shader source. + /// @return True if compile successful, otherwise return false. + /// + bool compile(const std::string& jsl, std::string* glsl_vertex, std::string* glsl_fragment); + + private: + singleton(JSLCompiler); + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader) + +#endif // __JE_JSL_COMPILER_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_shader.cpp b/src/libjin/Graphics/Shader/je_shader.cpp new file mode 100644 index 0000000..b0e7506 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_shader.cpp @@ -0,0 +1,278 @@ +#include "../../core/je_configuration.h" +#if defined(jin_graphics) && (jin_graphics & jin_graphics_shader) + +#include <iostream> + +#include "../../filesystem/je_buffer.h" +#include "../../utils/je_macros.h" + +#include "je_jsl_compiler.h" +#include "je_shader.h" + +namespace JinEngine +{ + namespace Graphics + { + + using namespace std; + using namespace JinEngine::Filesystem; + + // + // default_texture + // base_shader + // SHADER_FORMAT_SIZE + // formatShader + // + #include "je_default.shader.h" + + // + // https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value + // The default value of a sampler variable is 0. From the GLSL 3.30 spec, + // section "4.3.5 Uniforms": + // + // The link time initial value is either the value of the variable's + // initializer, if present, or 0 if no initializer is present.Sampler + // types cannot have initializers. + // + // Since a value of 0 means that it's sampling from texture unit 0, it will + // work without ever setting the value as long as you bind your textures to + // unit 0. This is well defined behavior. + // + // Since texture unit 0 is also the default until you call glActiveTexture() + // with a value other than GL_TEXTURE0, it's very common to always use unit + // 0 as long as shaders do not need more than one texture.Which means that + // often times, setting the sampler uniforms is redundant for simple + // applications. + // + // I would still prefer to always set the values.If nothing else, it makes + // it clear to anybody reading your code that you really mean to sample from + // texture unit 0, and did not just forget to set the value. + // + const int DEFAULT_TEXTURE_UNIT = 0; + + /*static*/ Shader* Shader::CurrentShader = nullptr; + + Shader* Shader::createShader(const string& program) + { + Shader* shader = nullptr; + try + { + shader = new Shader(program); + } + catch(...) + { + return nullptr; + } + return shader; + } + + Shader::Shader(const string& program) + : mCurrentTextureUnit(DEFAULT_TEXTURE_UNIT) + { + if (!compile(program)) + throw 0; + } + + Shader::~Shader() + { + if (CurrentShader == this) + unuse(); + // delete shader program + glDeleteShader(mPID); + } + + bool Shader::compile(const string& program) + { + string vertex_shader, fragment_shader; + // Compile JSL shader source into GLSL shader source. + JSLCompiler* compiler = JSLCompiler::get(); + if (!compiler->compile(program, &vertex_shader, &fragment_shader)) + { + return false; + } +#define glsl(SHADER_MODE, SHADER, SRC) \ +do{ \ +const GLchar* src = SRC.c_str(); \ +glShaderSource(SHADER, 1, &src, NULL); \ +glCompileShader(SHADER); \ +GLint success; \ +glGetShaderiv(SHADER, GL_COMPILE_STATUS, &success); \ +if (success == GL_FALSE) \ + return false; \ +}while(0) + // Compile vertex shader. + GLuint vid = glCreateShader(GL_VERTEX_SHADER); + glsl(GL_VERTEX_SHADER, vid, vertex_shader); + // Compile fragment shader. + GLuint fid = glCreateShader(GL_FRAGMENT_SHADER); + glsl(GL_FRAGMENT_SHADER, fid, fragment_shader); +#undef glsl + // Create OpenGL shader program. + mPID = glCreateProgram(); + glAttachShader(mPID, vid); + glAttachShader(mPID, fid); + glLinkProgram(mPID); + GLint success; + glGetProgramiv(mPID, GL_LINK_STATUS, &success); + if (success == GL_FALSE) + return false; + } + + static inline GLint getMaxTextureUnits() + { + GLint maxTextureUnits = 0; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + return maxTextureUnits; + } + + void Shader::use() + { + glUseProgram(mPID); + CurrentShader = this; + sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); + } + + /*static*/ void Shader::unuse() + { + glUseProgram(0); + CurrentShader = nullptr; + } + + GLint Shader::claimTextureUnit(const std::string& name) + { + std::map<std::string, GLint>::iterator unit = mTextureUnits.find(name); + if (unit != mTextureUnits.end()) + return unit->second; + static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); + if (++mCurrentTextureUnit >= MAX_TEXTURE_UNITS) + return 0; + mTextureUnits[name] = mCurrentTextureUnit; + return mCurrentTextureUnit; + } + + #define checkJSL() \ + if (CurrentShader != this) \ + return + + void Shader::sendInt(const char* name, int value) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform1i(loc, value); + } + + void Shader::sendFloat(const char* variable, float number) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, variable); + glUniform1f(loc, number); + } + + // + // https://www.douban.com/note/627332677/ + // struct TextureUnit + // { + // GLuint targetTexture1D; + // GLuint targetTexture2D; + // GLuint targetTexture3D; + // GLuint targetTextureCube; + // ... + // }; + // + // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] + // GLuint mCurrentTextureUnit = 0; + // + void Shader::sendTexture(const char* variable, const Texture* tex) + { + checkJSL(); + GLint location = glGetUniformLocation(mPID, variable); + if (location == -1) + return; + GLint unit = claimTextureUnit(variable); + if (unit == 0) + { + // TODO: 쳣 + return; + } + gl.activeTexUnit(unit); + glUniform1i(location, unit); + gl.bindTexture(tex->getTexture()); + gl.activeTexUnit(0); + } + + void Shader::sendCanvas(const char* variable, const Canvas* canvas) + { + checkJSL(); + GLint location = glGetUniformLocation(mPID, variable); + if (location == -1) + return; + GLint unit = claimTextureUnit(variable); + if (unit == 0) + { + // TODO: 쳣 + return; + } + glUniform1i(location, unit); + glActiveTexture(GL_TEXTURE0 + unit); + gl.bindTexture(canvas->getTexture()); + + glActiveTexture(GL_TEXTURE0); + } + + void Shader::sendVec2(const char* name, float x, float y) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform2f(loc, x, y); + } + + void Shader::sendVec3(const char* name, float x, float y, float z) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform3f(loc, x, y, z); + } + + void Shader::sendVec4(const char* name, float x, float y, float z, float w) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform4f(loc, x, y, z, w); + } + + void Shader::sendColor(const char* name, const Color* col) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform4f(loc, + col->r / 255.f, + col->g / 255.f, + col->b / 255.f, + col->a / 255.f + ); + } + + void Shader::sendMatrix4(const char* name, const Math::Matrix* mat4) + { + int loc = glGetUniformLocation(mPID, name); + glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); + } + + void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(mPID, SHADER_VERTEX_COORDS); + glEnableVertexAttribArray(0); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } + + void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(mPID, SHADER_TEXTURE_COORDS); + glEnableVertexAttribArray(1); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } + + } // namespace Graphics +} // namespace JinEngine + +#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_shader.h b/src/libjin/Graphics/Shader/je_shader.h new file mode 100644 index 0000000..928fb0a --- /dev/null +++ b/src/libjin/Graphics/Shader/je_shader.h @@ -0,0 +1,200 @@ +#ifndef __JE_SHADER_H +#define __JE_SHADER_H + +#include "../../core/je_configuration.h" +#if defined(jin_graphics) && (jin_graphics & jin_graphics_shader) + +#include <string> +#include <map> + +#include "../../3rdparty/GLee/GLee.h" + +#include "../je_color.h" +#include "../je_texture.h" +#include "../je_canvas.h" + +#include "je_base.shader.h" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// Built in shader program. + /// + /// Built in shader program written with custom shading language called JSL (jin + /// shading language). A JSL program is compiled into glsl, so most glsl built in + /// functions and structs are available in JSL. + /// + class Shader + { + public: + /// + /// Create shader program from source code. + /// + /// @param source The shader source code. + /// + static Shader* createShader(const std::string& source); + + /// + /// Get current shader. + /// + /// @return Current used shader program. + /// + static inline Shader* getCurrentShader() { return CurrentShader; } + + /// + /// Unuse current shader. + /// + static void unuse(); + + /// + /// Destructor of shader. + /// + virtual ~Shader(); + + /// + /// Use specific shader. + /// + void use(); + + /// + /// Send float value to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param number Value of uniform variable to be sent. + /// + void sendFloat(const char* name, float number); + + /// + /// Send texture to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param texture Texture to be sent. + /// + void sendTexture(const char* name, const Texture* texture); + + /// + /// Send integer value to shader + /// + /// @param name Name of the uniform variable to be assigned. + /// @param value Value to be sent. + /// + void sendInt(const char* name, int value); + + /// + /// Send 2D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// + void sendVec2(const char* name, float x, float y); + + /// + /// Send 3D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// @param z Z value of the vector to be sent. + /// + void sendVec3(const char* name, float x, float y, float z); + + /// + /// Send 4D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// @param z Z value of the vector to be sent. + /// @param w W value of the vector to be sent. + /// + void sendVec4(const char* name, float x, float y, float z, float w); + + /// + /// Send canvas to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param canvas Canvas to be sent. + /// + void sendCanvas(const char* name, const Canvas* canvas); + + /// + /// Send color to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param color Color to be sent. + /// + void sendColor(const char* name, const Color* color); + + /// + /// Send 4 by 4 matrix to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param mat4 Matrix to be sent. + /// + void sendMatrix4(const char* name, const Math::Matrix* mat4); + + /// + /// Set vertices value. + /// + /// @param n Number of vertices. + /// @param type Data type of each component in the array. + /// @param stride Byte offset between consecutive generic vertex attributes. + /// @param pointers Pointer to the first component of the first generic vertex + /// attribute in the array. + /// + void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); + + /// + /// Set texture UV coordinates. + /// + /// @param n Number of vertices. + /// @param type Data type of each component in the array. + /// @param stride Byte offset between consecutive generic vertex attributes. + /// @param pointers Pointer to the first component of the first generic vertex + /// attribute in the array. + /// + void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); + + protected: + /// + /// Reference of current used shader. + /// + static Shader* CurrentShader; + + /// + /// Get texture unit of the uniform texture. If not, assign one. + /// + /// @param name Name of the texture uniform variable. + /// @return Texture unit which texture variable be assigned. + /// + GLint claimTextureUnit(const std::string& name); + + /// + /// Shader constructor. + /// + Shader(const std::string& program); + + /// + /// Compile JSL program into GLSL source. + /// + /// @param program JSL source code. + /// @return Return true if compile successed, otherwise return false. + /// + bool compile(const std::string& program); + + GLuint mPID; + GLint mCurrentTextureUnit; + std::map<std::string, GLint> mTextureUnits; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader) + +#endif // __JE_SHADER_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_texture.shader.h b/src/libjin/Graphics/Shader/je_texture.shader.h new file mode 100644 index 0000000..d1fc86f --- /dev/null +++ b/src/libjin/Graphics/Shader/je_texture.shader.h @@ -0,0 +1,21 @@ +// ͼshader +static const char* texture_shader = R"( + +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return col * texel(tex, v.uv); +} + +#END_FRAGMENT_SHADER +)";
\ No newline at end of file diff --git a/src/libjin/Graphics/Shapes.cpp b/src/libjin/Graphics/Shapes.cpp deleted file mode 100644 index 4b136a1..0000000 --- a/src/libjin/Graphics/Shapes.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "Shapes.h" -#include "../math/matrix.h" -#include "../math/constant.h" -#include <string> - -namespace jin -{ -namespace graphics -{ - - void point(int x, int y) - { - float vers[] = { x + 0.5f , y + 0.5f }; - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, (GLvoid*)vers); - glDrawArrays(GL_POINTS, 0, 1); - glDisableClientState(GL_VERTEX_ARRAY); - } - - void points(int n, GLshort* p) - { - glEnableClientState(GL_VERTEX_ARRAY); - - glVertexPointer(2, GL_SHORT, 0, (GLvoid*)p); - glDrawArrays(GL_POINTS, 0, n); - - glDisableClientState(GL_VERTEX_ARRAY); - } - - void line(int x1, int y1, int x2, int y2) - { - glDisable(GL_TEXTURE_2D); - float verts[] = { - x1, y1, - x2, y2 - }; - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, (GLvoid*)verts); - glDrawArrays(GL_LINES, 0, 2); - glDisableClientState(GL_VERTEX_ARRAY); - } - - void circle(RENDER_MODE mode, int x, int y, int r) - { - r = r < 0 ? 0 : r; - - int points = 40; - float two_pi = static_cast<float>(PI * 2); - if (points <= 0) points = 1; - float angle_shift = (two_pi / points); - float phi = .0f; - - float *coords = new float[2 * (points + 1)]; - for (int i = 0; i < points; ++i, phi += angle_shift) - { - coords[2 * i] = x + r * cos(phi); - coords[2 * i + 1] = y + r * sin(phi); - } - - coords[2 * points] = coords[0]; - coords[2 * points + 1] = coords[1]; - - polygon(mode, coords, points); - - delete[] coords; - } - - void rect(RENDER_MODE mode, int x, int y, int w, int h) - { - float coords[] = { x, y, x + w, y, x + w, y + h, x, y + h }; - polygon(mode, coords, 4); - } - - void triangle(RENDER_MODE mode, int x1, int y1, int x2, int y2, int x3, int y3) - { - float coords[] = { x1, y1, x2, y2, x3, y3 }; - polygon(mode, coords, 3); - } - - void polygon_line(float* p, int count) - { - float* verts = new float[count * 4]; - for (int i = 0; i < count; ++i) - { - // each line has two point n,n+1 - verts[i * 4] = p[i * 2]; - verts[i * 4 + 1] = p[i * 2 + 1]; - verts[i * 4 + 2] = p[(i + 1) % count * 2]; - verts[i * 4 + 3] = p[(i + 1) % count * 2 + 1]; - } - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, (GLvoid*)verts); - glDrawArrays(GL_LINES, 0, count * 2); - glDisableClientState(GL_VERTEX_ARRAY); - - delete[] verts; - } - - void polygon(RENDER_MODE mode, float* p, int count) - { - if (mode == LINE) - { - polygon_line(p, count); - } - else if (mode == FILL) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, (const GLvoid*)p); - glDrawArrays(GL_POLYGON, 0, count); - glDisableClientState(GL_VERTEX_ARRAY); - } - } - -} -} - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Shapes.h b/src/libjin/Graphics/Shapes.h deleted file mode 100644 index 742345e..0000000 --- a/src/libjin/Graphics/Shapes.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __JIN_GRAPHICS_SHAPES_H -#define __JIN_GRAPHICS_SHAPES_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "color.h" -#include "canvas.h" -#include "texture.h" - -namespace jin -{ -namespace graphics -{ - - typedef enum { - NONE = 0, - FILL , - LINE - }RENDER_MODE; - - /** - * TODO: - * drawPixels(int n, points) - */ - extern void line(int x1, int y1, int x2, int y2); - - extern void rect(RENDER_MODE mode, int x, int y, int w, int h); - - extern void triangle(RENDER_MODE mode, int x1, int y1, int x2, int y2, int x3, int y3); - - extern void circle(RENDER_MODE mode, int x, int y, int r); - - extern void point(int x, int y); - - extern void points(int n, GLshort* p, GLubyte* c); - - extern void polygon(RENDER_MODE mode, float* p, int count); - -} -} - -#endif // JIN_MODULES_RENDER -#endif // __JIN_GEOMETRY_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Texture.cpp b/src/libjin/Graphics/Texture.cpp deleted file mode 100644 index 4c6707d..0000000 --- a/src/libjin/Graphics/Texture.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include <fstream> -#include "texture.h" -#include "../3rdparty/stb/stb_image.h" -#include "../utils/utils.h" -#include "../Math/Math.h" - -namespace jin -{ -namespace graphics -{ - - using namespace jin::math; - - Texture* Texture::createTexture(const char* file) - { - std::ifstream fs; - fs.open(file, std::ios::binary); - Texture* tex = nullptr; - if (fs.is_open()) - { - fs.seekg(0, std::ios::end); - int size = fs.tellg(); - fs.seekg(0, std::ios::beg); - char* buffer = (char*)malloc(size); - memset(buffer, 0, size); - fs.read(buffer, size); - tex = createTexture(buffer, size); - free(buffer); - } - fs.close(); - return tex; - } - - Texture* Texture::createTexture(const void* mem, size_t size) - { - Texture* tex = new Texture(); - if(!tex->loadb(mem, size)) - { - delete tex; - tex = nullptr; - } - return tex; - } - - Texture::Texture() - : Drawable(), pixels(0) - { - } - - Texture::~Texture() - { - stbi_image_free(pixels); - } - - color Texture::getPixel(int x, int y) - { - if (without(x, 0, width) || without(y, 0, height)) - { - return { 0 }; - } - return pixels[x + y * width]; - } - - bool Texture::loadb(const void* b, size_t size) - { - // ʹstbi_load_from_memory - unsigned char* textureData = stbi_load_from_memory((unsigned char *)b, size, &width, &height, NULL, STBI_rgb_alpha); - if (textureData == 0) return false; - pixels = (color*)textureData; - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, - height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData); - - // set render vertices - Drawable::setVertices( - new float [DRAWABLE_V_SIZE] { - 0, 0, - 0, (float)height, - (float)width, (float)height, - (float)width, 0, - }, - new float [DRAWABLE_V_SIZE] { - 0, 0, - 0, 1, - 1, 1, - 1, 0 - } - ); - - return true; - } -} -} - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Texture.h b/src/libjin/Graphics/Texture.h deleted file mode 100644 index 1fdb50d..0000000 --- a/src/libjin/Graphics/Texture.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __JIN_IMAGE_H -#define __JIN_IMAGE_H -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "../3rdparty/GLee/GLee.h" -#include "color.h" -#include "drawable.h" -namespace jin -{ -namespace graphics -{ - - class Texture: public Drawable - { - - public: - - static Texture* createTexture(const char* file); - static Texture* createTexture(const void* mem, size_t size); - - static void destroyTexture(Texture* tex); - - ~Texture(); - - color getPixel(int x, int y); - - private: - - Texture(); - - bool loadb(const void* buffer, size_t size); - - color* pixels; - - }; - -} -} - -#endif // JIN_MODULES_RENDER -#endif // __JIN_IMAGE_H
\ No newline at end of file diff --git a/src/libjin/Graphics/Window.cpp b/src/libjin/Graphics/Window.cpp deleted file mode 100644 index 708a30f..0000000 --- a/src/libjin/Graphics/Window.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include <iostream> -#include "window.h" -#include "../3rdparty/GLee/GLee.h" -#include "canvas.h" -#include "../utils/utils.h" -#include "../audio/sdl/SDLAudio.h" -#include "../utils/log.h" - -namespace jin -{ -namespace graphics -{ - - bool Window::initSystem(const SettingBase* s) - { -#if JIN_DEBUG - Loghelper::log(Loglevel::LV_INFO, "Init window system"); -#endif // JIN_DEBUG - - if (SDL_Init(SDL_INIT_VIDEO) < 0) - return false; - - const Setting* setting = (Setting*)s; - width = setting->width; - height = setting->height; - fps = setting->fps; - bool vsync = setting->vsync; - const char* title = setting->title; - - if (wnd) - { - SDL_DestroyWindow(wnd); - SDL_FlushEvent(SDL_WINDOWEVENT); - } - - SDL_GLContext ctx = NULL; - - if (ctx) - { - SDL_GL_DeleteContext(ctx); - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - int wx = SDL_WINDOWPOS_UNDEFINED, - wy = SDL_WINDOWPOS_UNDEFINED; - - int flag = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; - if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN; - if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE; - - wnd = SDL_CreateWindow(title, wx, wy, width, height, flag); - if (wnd == NULL) - return false; - ctx = SDL_GL_CreateContext(wnd); - if (ctx == NULL) - return false; - SDL_GL_SetSwapInterval(vsync ? 1 : 0); - SDL_GL_MakeCurrent(wnd, ctx); - glClearColor(0.f, 0.f, 0.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glColor4f(1, 1, 1, 1); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - Canvas::unbind(); - swapBuffers(); - return true; - } - - void Window::quitSystem() - { - SDL_DestroyWindow(wnd); - SDL_Quit(); - } - - inline void Window::swapBuffers() - { - if (wnd) - SDL_GL_SwapWindow(wnd); - } - -} // graphics -} // jin - -#endif // JIN_MODULES_RENDER
\ No newline at end of file diff --git a/src/libjin/Graphics/Window.h b/src/libjin/Graphics/Window.h deleted file mode 100644 index e09e9f9..0000000 --- a/src/libjin/Graphics/Window.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __JIN_RENDER_WINDOW -#define __JIN_RENDER_WINDOW -#include "../modules.h" -#if JIN_MODULES_RENDER - -#include "SDL2/SDL.h" -#include "../utils/utils.h" -#include "../common/Subsystem.hpp" - -namespace jin -{ -namespace graphics -{ - - class Window : public Subsystem<Window> - { - public: - - struct Setting : SettingBase - { - public: - const char* title; // - bool fullscreen; // ȫ - int width, height; // ڴС - bool vsync; // ֱͬ - int fps; // FPS - bool resizable; // resize - }; - - inline int getW(){ return width; } - inline int getH(){ return height; } - inline int getFPS(){ return fps; } - inline void swapBuffers(); - - private: - - Window() {}; - virtual ~Window() {}; - - SINGLETON(Window); - - SDL_Window* wnd; - - int width, height; - int fps; - - onlyonce bool initSystem(const SettingBase* setting) override; - onlyonce void quitSystem() override; - }; - -} // render -} // jin - -#endif // JIN_MODULES_RENDER -#endif // __JIN_RENDER_WINDOW
\ No newline at end of file diff --git a/src/libjin/Audio/OpenAL/ALSource.cpp b/src/libjin/Graphics/animation/je_animation.cpp index e69de29..e69de29 100644 --- a/src/libjin/Audio/OpenAL/ALSource.cpp +++ b/src/libjin/Graphics/animation/je_animation.cpp diff --git a/src/libjin/Graphics/animation/je_animation.h b/src/libjin/Graphics/animation/je_animation.h new file mode 100644 index 0000000..f330a0c --- /dev/null +++ b/src/libjin/Graphics/animation/je_animation.h @@ -0,0 +1,20 @@ +#ifndef __JE_ANIMATION_H +#define __JE_ANIMATION_H + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// + /// + class Animation + { + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Audio/OpenAL/ALSource.h b/src/libjin/Graphics/animation/je_clip.cpp index e69de29..e69de29 100644 --- a/src/libjin/Audio/OpenAL/ALSource.h +++ b/src/libjin/Graphics/animation/je_clip.cpp diff --git a/src/libjin/Graphics/animation/je_clip.h b/src/libjin/Graphics/animation/je_clip.h new file mode 100644 index 0000000..d6709dc --- /dev/null +++ b/src/libjin/Graphics/animation/je_clip.h @@ -0,0 +1,20 @@ +#ifndef __JE_CLIP_H +#define __JE_CLIP_H + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// Animation clip with key. + /// + class Clip + { + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/je_bitmap.cpp b/src/libjin/Graphics/je_bitmap.cpp new file mode 100644 index 0000000..0747f0b --- /dev/null +++ b/src/libjin/Graphics/je_bitmap.cpp @@ -0,0 +1,162 @@ +#define STB_IMAGE_IMPLEMENTATION +#include "../3rdparty/stb/stb_image.h" + +#include "../filesystem/je_asset_database.h" +#include "../math/je_math.h" + +#include "je_bitmap.h" + +using namespace JinEngine::Filesystem; +using namespace JinEngine::Math; + +namespace JinEngine +{ + namespace Graphics + { + + Bitmap* Bitmap::createBitmap(const char* path) + { + AssetDatabase* ad = AssetDatabase::get(); + Buffer buffer; + ad->read(path, buffer); + return createBitmap(&buffer, buffer.size()); + } + + /* pixelbitmap */ + Bitmap* Bitmap::createBitmap(const void* pixel, unsigned width, unsigned height) + { + Bitmap* bitmap = new Bitmap(width, height); + memcpy(bitmap->pixels, pixel, width*height * sizeof(Color)); + return bitmap; + } + + /*static*/ Bitmap* Bitmap::createBitmap(const void* imgData, size_t size) + { + if (imgData == nullptr) + return nullptr; + int w, h; + void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha); + if (data == nullptr) + return nullptr; + Bitmap* bitmap = new Bitmap(); + bitmap->pixels = (Color*)data; + bitmap->width = w; + bitmap->height = h; + return bitmap; + } + + /*static*/ Bitmap* Bitmap::createBitmap(int w, int h, Color color) + { + Bitmap* bitmap = new Bitmap(w, h); + if (color != Color::BLACK) + bitmap->setPixels(color); + return bitmap; + } + + /*static */ Bitmap* Bitmap::clone(const Bitmap* bitmap) + { + Bitmap* b = new Bitmap(); + int w = bitmap->getWidth(); + int h = bitmap->getHeight(); + b->resetPixels(bitmap->getPixels(), w, h); + return b; + } + + Bitmap::Bitmap() + : width(0) + , height(0) + , pixels(nullptr) + { + } + + Bitmap::Bitmap(unsigned w, unsigned h) + { + width = w; + height = h; + pixels = new Color[w*h]; + } + + Bitmap::~Bitmap() + { + stbi_image_free(pixels); + } + + void Bitmap::bind(Color* p, int w, int h) + { + if (pixels != nullptr) + delete[] pixels; + pixels = p; + width = w; + height = h; + } + + void Bitmap::resetPixels(const Color* p, int w, int h) + { + if (pixels != nullptr) + delete[] pixels; + pixels = new Color[w*h]; + size_t s = w * h * sizeof(Color); + memcpy(pixels, p, s); + width = w; + height = h; + } + + void Bitmap::setPixel(const Color& c, int x, int y) + { + if (pixels == nullptr) + return; + if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) + return; + pixels[x + y * width] = c; + } + + void Bitmap::resetPixels(const Color& c, int w, int h) + { + if (pixels != nullptr) + delete[] pixels; + pixels = new Color[w*h]; + size_t s = w * h * sizeof(Color); + width = w; + height = h; + for (int x = 0; x < w; ++x) + { + for (int y = 0; y < h; ++y) + { + pixels[x + y * w] = c; + } + } + } + + void Bitmap::setPixels(Color* p) + { + size_t s = width * height * sizeof(Color); + memcpy(pixels, p, s); + } + + void Bitmap::setPixels(Color c) + { + for (int x = 0; x < width; ++x) + { + for (int y = 0; y < height; ++y) + { + pixels[x + y * width] = c; + } + } + } + + Color Bitmap::getPixel(int x, int y) + { + if (pixels == nullptr) + return Color::BLACK; + if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1)) + return Color::BLACK; + return pixels[x + y * width]; + } + + const Color* Bitmap::getPixels() const + { + return pixels; + } + + } // namespace Graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Graphics/je_bitmap.h b/src/libjin/Graphics/je_bitmap.h new file mode 100644 index 0000000..ae97d0d --- /dev/null +++ b/src/libjin/Graphics/je_bitmap.h @@ -0,0 +1,184 @@ +#ifndef __JE_BITMAP_H +#define __JE_BITMAP_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "../3rdparty/GLee/GLee.h" +#include "../common/je_types.h" +#include "../math/je_vector2.hpp" + +#include "je_color.h" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// A RGBA32 bitmap. + /// + /// A bitmap keeps pixels and can't draw directly onto screen. To render bitmap, a texture is required. + /// + class Bitmap + { + public: + /// + /// Create bitmap from given file. + /// + /// @param path Path of image file. + /// @return Bitmap if create successful, otherwise retrun false. + /// + static Bitmap* createBitmap(const char* path); + + /// + /// Create bitmap by pixels data. + /// + /// @param pixels Pixels data. + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* createBitmap(const void* pixels, unsigned width, unsigned height); + + /// + /// Create bitmap from compressed image data. + /// + /// @param imgData Compressed image data. + /// @param size Size of image data. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* createBitmap(const void* imgData, size_t size); + + /// + /// Create bitmap with specific color and size. + /// + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// @param color Color of bitmap, black by default. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* createBitmap(int width, int height, Color color = Color::BLACK); + + /// + /// Create bitmap with another one. + /// + /// @param bitmap Bitmap be cloned. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* clone(const Bitmap* bitmap); + + /// + /// Destructor of bitmap + /// + virtual ~Bitmap(); + + /// + /// Directly bind pixels with given pixels data + /// + /// @param pixels Pixels to be binded. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void bind(Color* pixels, int width, int height); + + /// + /// Reset pixel data with given pixels data. + /// + /// @param pixels Pixels to be set. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void resetPixels(const Color* pixels, int width, int height); + + /// + /// Reset pixel data with given color. + /// + /// @param color Color to be set. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void resetPixels(const Color& color, int width, int height); + + /// + /// Set pixel with given color. + /// + /// @param color Color to be set. + /// @param x X value of pixel. + /// @param y Y value of pixel. + /// + void setPixel(const Color& color, int x, int y); + + /// + /// Set pixels with given color. + /// + /// @param color Color to be set. + /// + void setPixels(Color color); + + /// + /// Set pixels with given color data. + /// + /// @param colors New pixels' colors. + /// + void setPixels(Color* colors); + + /// + /// Get pixel in given position. + /// + /// @param x X value of position. + /// @param y Y value of position. + /// + Color getPixel(int x, int y); + + /// + /// Get pixels. + /// @return Colors of the bitmap. + /// + const Color* getPixels() const; + + /// + /// Get bitmap width. + /// + /// @return Width of bitmap. + /// + inline int getWidth() const { return width; } + + /// + /// Get bitmap height. + /// + /// @return Height of bitmap. + /// + inline int getHeight() const { return height; } + + /// + /// Get bitmap size. + /// + /// @return Size of bitmap. + /// + inline Math::Vector2<int> getSize() const { return Math::Vector2<int>(width, height); } + + protected: + /// + /// Constructor of bitmap. + /// + Bitmap(); + + /// + /// Constructor of bitmap. + /// + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// + Bitmap(unsigned w, unsigned h); + + Color * pixels; + unsigned width, height; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/je_canvas.cpp b/src/libjin/Graphics/je_canvas.cpp new file mode 100644 index 0000000..7e0858b --- /dev/null +++ b/src/libjin/Graphics/je_canvas.cpp @@ -0,0 +1,102 @@ +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "../utils/je_macros.h" +#include "je_canvas.h" +#include "je_window.h" + +namespace JinEngine +{ + namespace Graphics + { + + /*class member*/ const Canvas* Canvas::current = nullptr; + /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0); + + /*class member*/ Canvas* Canvas::createCanvas(int w, int h) + { + return new Canvas(w, h); + } + + Canvas::Canvas(GLuint n) + : fbo(n) + { + } + + Canvas::Canvas(int w, int h) + : Graphic(w, h) + { + GLint current_fbo; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + + // Generate a new render buffer object + fbo = gl.genFrameBuffer(); + gl.bindFrameBuffer(fbo); + + // Generate texture save target + mTexture = gl.genTexture(); + gl.bindTexture(mTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + gl.bindTexture(0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + // Unbind framebuffer + gl.bindFrameBuffer(current_fbo); + } + + Canvas::~Canvas() + { + } + + /*class member*/ bool Canvas::isBinded(const Canvas* cvs) + { + return current == cvs; + } + + /** + * bind to canvas + */ + /*class member*/ void Canvas::bind(Canvas* canvas) + { + if (isBinded(canvas)) return; + current = canvas; + gl.bindFrameBuffer(canvas->fbo); + int w = canvas->getWidth(); + int h = canvas->getHeight(); + // Set view port to canvas. + glViewport(0, 0, w, h); + gl.ProjectionMatrix.setOrtho(0, w, 0, h, -1, 1); + } + + /** + * bind to default screen render buffer. + * do some coordinates transform work + * https://blog.csdn.net/liji_digital/article/details/79370841 + * https://blog.csdn.net/lyx2007825/article/details/8792475 + */ + /*class member*/ void Canvas::unbind() + { + if (isBinded(DEFAULT_CANVAS)) return; + current = DEFAULT_CANVAS; + /* get window size as viewport */ + Window* wnd = Window::get(); + int w = wnd->getW(); + int h = wnd->getH(); + + glBindFramebuffer(GL_FRAMEBUFFER, DEFAULT_CANVAS->fbo); + + /* set viewport on screen */ + glViewport(0, 0, w, h); + + gl.ProjectionMatrix.setOrtho(0, w, h, 0, -1, 1); + + } + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/Graphics/je_canvas.h b/src/libjin/Graphics/je_canvas.h new file mode 100644 index 0000000..f39b0de --- /dev/null +++ b/src/libjin/Graphics/je_canvas.h @@ -0,0 +1,68 @@ +#ifndef __JE_CANVAS_H +#define __JE_CANVAS_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "je_graphic.h" + +namespace JinEngine +{ + namespace Graphics + { + /// + /// Renderable canvas. + /// + /// A canvas is a rendering target. + /// + class Canvas: public Graphic + { + public: + /// + /// + /// + static Canvas* createCanvas(int w, int h); + + /// + /// + /// + static void bind(Canvas*); + + /// + /// + /// + static void unbind(); + + /// + /// + /// + static bool isBinded(const Canvas*); + + /// + /// + /// + ~Canvas(); + + protected: + static const Canvas* const DEFAULT_CANVAS; + static const Canvas* current; + + /// + /// + /// + Canvas(int w, int h); + + /// + /// + /// + Canvas(GLuint n); + + GLuint fbo; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics) + +#endif // __JE_CANVAS_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_color.cpp b/src/libjin/Graphics/je_color.cpp new file mode 100644 index 0000000..da48162 --- /dev/null +++ b/src/libjin/Graphics/je_color.cpp @@ -0,0 +1,17 @@ +#include "je_color.h" + +namespace JinEngine +{ + namespace Graphics + { + + const Color Color::WHITE = Color(255, 255, 255); + const Color Color::BLACK = Color(0, 0, 0); + const Color Color::RED = Color(255, 0, 0); + const Color Color::GREEN = Color(0, 255, 0); + const Color Color::BLUE = Color(0, 0, 255); + const Color Color::MAGENTA = Color(255, 0, 255); + const Color Color::YELLOW = Color(255, 255, 0); + + } +}
\ No newline at end of file diff --git a/src/libjin/Graphics/je_color.h b/src/libjin/Graphics/je_color.h new file mode 100644 index 0000000..8fe7691 --- /dev/null +++ b/src/libjin/Graphics/je_color.h @@ -0,0 +1,93 @@ +/** +* Some color operating here. +*/ +#ifndef __JE_COLOR_H +#define __JE_COLOR_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "../common/je_types.h" +#include "../utils/je_endian.h" + +namespace JinEngine +{ + namespace Graphics + { + + typedef uint8 Channel; + + class Color + { + public: + // Built-in colors + static const Color WHITE; + static const Color BLACK; + static const Color RED; + static const Color GREEN; + static const Color BLUE; + static const Color MAGENTA; + static const Color YELLOW; + + /// + /// + /// + Color() { r = g = b = a = 0; }; + + /// + /// + /// + Color(unsigned char _r + , unsigned char _g + , unsigned char _b + , unsigned char _a = 255) + { + r = _r; + g = _g; + b = _b; + a = _a; + } + + Color(const Color& c) + { + r = c.r; + g = c.g; + b = c.b; + a = c.a; + } + + void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) + { + r = _r; + g = _g; + b = _b; + a = _a; + } + + void operator = (const Color& c) + { + r = c.r; + g = c.g; + b = c.b; + a = c.a; + } + + bool operator == (const Color& c) + { + return r == c.r && g == c.g && b == c.b && a == c.a; + } + + bool operator != (const Color& c) + { + return !(r == c.r && g == c.g && b == c.b && a == c.a); + } + + Channel r, g, b, a; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // jin_graphics + +#endif // __JE_COLOR_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_gl.cpp b/src/libjin/Graphics/je_gl.cpp new file mode 100644 index 0000000..9ef1460 --- /dev/null +++ b/src/libjin/Graphics/je_gl.cpp @@ -0,0 +1,12 @@ +#define OGL2D_IMPLEMENT +#include "je_gl.h" + +namespace JinEngine +{ + namespace Graphics + { + + OpenGL gl; + + } // namespace Graphics +} // namespace JinEngine diff --git a/src/libjin/Graphics/je_gl.h b/src/libjin/Graphics/je_gl.h new file mode 100644 index 0000000..cda8bf9 --- /dev/null +++ b/src/libjin/Graphics/je_gl.h @@ -0,0 +1,40 @@ +#ifndef __JE_OPENGL_H +#define __JE_OPENGL_H + +#include "../3rdparty/GLee/GLee.h" +#include "../3rdparty/ogl/OpenGL.h" +#include "../math/je_matrix.h" + +namespace JinEngine +{ + namespace Graphics + { + + class OpenGL : public ogl2d::OpenGL + { + public: + /// + /// + /// + Math::Matrix ProjectionMatrix; + + /// + /// + /// + Math::Matrix ModelMatrix; + + /// + /// + /// + OpenGL() : ogl2d::OpenGL() + { + } + + }; + + extern OpenGL gl; + + } // namespace Graphics +} // namespace JinEngine + +#endif // __JE_OPENGL_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_graphic.cpp b/src/libjin/Graphics/je_graphic.cpp new file mode 100644 index 0000000..831e409 --- /dev/null +++ b/src/libjin/Graphics/je_graphic.cpp @@ -0,0 +1,117 @@ +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include <stdlib.h> + +#include "../math/je_matrix.h" + +#include "shader/je_shader.h" +#include "je_graphic.h" + +namespace JinEngine +{ + namespace Graphics + { + + Graphic::Graphic(int w, int h) + : mTexture(0) + , mSize(w, h) + { + mVertexCoords[0] = 0; mVertexCoords[1] = 0; + mVertexCoords[2] = 0; mVertexCoords[3] = h; + mVertexCoords[4] = w; mVertexCoords[5] = h; + mVertexCoords[6] = w; mVertexCoords[7] = 0; + + mTextureCoords[0] = 0; mTextureCoords[1] = 0; + mTextureCoords[2] = 0; mTextureCoords[3] = 1; + mTextureCoords[4] = 1; mTextureCoords[5] = 1; + mTextureCoords[6] = 1; mTextureCoords[7] = 0; + } + + Graphic::Graphic(const Bitmap* bitmap) + : mTexture(0) + { + uint32 w = mSize.w = bitmap->getWidth(); + uint32 h = mSize.h = bitmap->getHeight(); + + mVertexCoords[0] = 0; mVertexCoords[1] = 0; + mVertexCoords[2] = 0; mVertexCoords[3] = h; + mVertexCoords[4] = w; mVertexCoords[5] = h; + mVertexCoords[6] = w; mVertexCoords[7] = 0; + + mTextureCoords[0] = 0; mTextureCoords[1] = 0; + mTextureCoords[2] = 0; mTextureCoords[3] = 1; + mTextureCoords[4] = 1; mTextureCoords[5] = 1; + mTextureCoords[6] = 1; mTextureCoords[7] = 0; + + const Color* pixels = bitmap->getPixels(); + + mTexture = gl.genTexture(); + gl.bindTexture(mTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + gl.bindTexture(0); + } + + Graphic::~Graphic() + { + glDeleteTextures(1, &mTexture); + } + + void Graphic::draw(int x, int y, float sx, float sy, float r, float ox, float oy) + { + gl.ModelMatrix.setTransformation(x, y, r, sx, sy, ox, oy); + + Shader* shader = Shader::getCurrentShader(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, mVertexCoords); + shader->bindUVPointer(2, GL_FLOAT, 0, mTextureCoords); + + gl.bindTexture(mTexture); + gl.drawArrays(GL_QUADS, 0, 4); + gl.bindTexture(0); + } + + void Graphic::draw(const Math::Quad& slice, int x, int y, float sx, float sy, float r, float ax, float ay) + { + float vertCoords[8] = { + 0, 0, + 0, slice.h, + slice.w, slice.h, + slice.w, 0 + }; + float slx = slice.x / mSize.w; + float sly = slice.y / mSize.h; + float slw = slice.w / mSize.w; + float slh = slice.h / mSize.h; + float texCoords[8] = { + slx, sly, + slx, sly + slh, + slx + slw, sly + slh, + slx + slw, sly + }; + + gl.ModelMatrix.setTransformation(x, y, r, sx, sy, ax, ay); + + Shader* shader = Shader::getCurrentShader(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, vertCoords); + shader->bindUVPointer(2, GL_FLOAT, 0, texCoords); + + gl.bindTexture(mTexture); + gl.drawArrays(GL_QUADS, 0, 4); + gl.bindTexture(0); + } + + //void Graphic::setFilter(GLint min, GLint max) + //{ + // glTexParameteri(GL_) + //} + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/Graphics/je_graphic.h b/src/libjin/Graphics/je_graphic.h new file mode 100644 index 0000000..fb6b19e --- /dev/null +++ b/src/libjin/Graphics/je_graphic.h @@ -0,0 +1,91 @@ +#ifndef __JE_GRAPHIC_H +#define __JE_GRAPHIC_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "../math/je_quad.h" +#include "../math/je_vector2.hpp" + +#include "je_gl.h" +#include "je_bitmap.h" + +namespace JinEngine +{ + namespace Graphics + { + + // + // Graphic + // |-Texture + // |-Canvas + // + + /// + /// Class inherites Graphic doesn't keep any state such as origin, scale and other + /// properties. + /// + class Graphic + { + public: + /// + /// + /// + Graphic(int w = 0, int h = 0); + + /// + /// + /// + Graphic(const Bitmap* bitmap); + + /// + /// + /// + virtual ~Graphic(); + + /// + /// + /// + void draw(int x, int y, float sx = 1, float sy = 1, float r = 0, float ox = 0, float oy = 0); + + /// + /// + /// + void draw(const Math::Quad& slice, int x, int y, float sx = 1, float sy = 1, float r = 0, float ax = 0, float ay = 0); + + /// + /// + /// + inline int getWidth() const { return mSize.w; } + + /// + /// + /// + inline int getHeight() const { return mSize.h; } + + /// + /// + /// + inline GLuint getTexture() const { return mTexture; } + + /// + /// + /// + void setFilter(GLint min, GLint max); + + protected: + GLuint mTexture; + + private: + JinEngine::Math::Vector2<uint> mSize; + // Screen coordinates and uv coordinates. + float mVertexCoords[8]; + float mTextureCoords[8]; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics) + +#endif // __JE_GRAPHIC_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_graphics.h b/src/libjin/Graphics/je_graphics.h new file mode 100644 index 0000000..2ba003d --- /dev/null +++ b/src/libjin/Graphics/je_graphics.h @@ -0,0 +1,21 @@ +#ifndef __JE_GRAPHICS_H +#define __JE_GRAPHICS_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "je_canvas.h" +#include "je_color.h" +#include "je_shapes.h" +#include "je_texture.h" +#include "je_window.h" +#include "je_bitmap.h" +#include "je_image.h" + +#include "shader/je_shader.h" + +#include "font/je_ttf.h" +#include "font/je_text.h" +#include "font/je_texture_font.h" + +#endif // defined(jin_graphics) +#endif // __JE_GRAPHICS_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_image.cpp b/src/libjin/Graphics/je_image.cpp new file mode 100644 index 0000000..f800423 --- /dev/null +++ b/src/libjin/Graphics/je_image.cpp @@ -0,0 +1,46 @@ +#include "../3rdparty/stb/stb_image.h" +#include "../filesystem/je_asset_database.h" + +#include "je_image.h" + +namespace JinEngine +{ + namespace Graphics + { + + using namespace Filesystem; + + /*static*/ Image* Image::createImage(const void* imgData, size_t size) + { + if (imgData == nullptr) + return nullptr; + int w, h; + void* data = stbi_load_from_memory((uint8*)imgData, size, &w, &h, NULL, STBI_rgb_alpha); + if (data == nullptr) + return nullptr; + Image* image = new Image(); + image->pixels = (Color*)data; + image->width = w; + image->height = h; + return image; + } + + Image* Image::createImage(const char* path) + { + AssetDatabase* fs = AssetDatabase::get(); + Buffer buffer; + fs->read(path, buffer); + return createImage(&buffer, buffer.size()); + } + + Image::Image() + : Bitmap() + { + } + + Image::~Image() + { + } + + } // namespace Graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Graphics/je_image.h b/src/libjin/Graphics/je_image.h new file mode 100644 index 0000000..04ee4d2 --- /dev/null +++ b/src/libjin/Graphics/je_image.h @@ -0,0 +1,60 @@ +#ifndef __JE_IMAGE_H +#define __JE_IMAGE_H + +#include "je_bitmap.h" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// A readonly bitmap. + /// + /// Just like bitmap but only from image file. The pixels data is readonly. + /// + class Image : public Bitmap + { + public: + /// + /// Create image from image file. + /// + /// @param path Image path. + /// @return Image if created successfully, otherwise return null. + /// + static Image* createImage(const char* path); + + /// + /// Create image from image data. + /// + /// @param imgData Image data to create image. + /// @param size Size of image data. + /// @return Image if created successfully, otherwise return null. + /// + static Image* createImage(const void* imgData, size_t size); + + /// + /// Image destructor. + /// + ~Image(); + + private: + /// + /// Image constructor. + /// + Image(); + + // Disable setters inherited from Bitmap. + void bind(Color* pixels, int w, int h); + void resetPixels(const Color* pixels, int w, int h); + void resetPixels(const Color& pixels, int w, int h); + void setPixel(const Color& pixel, int x, int y); + void setPixels(Color pixels); + void setPixels(Color* pixels); + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/je_mesh.cpp b/src/libjin/Graphics/je_mesh.cpp new file mode 100644 index 0000000..dd2d61c --- /dev/null +++ b/src/libjin/Graphics/je_mesh.cpp @@ -0,0 +1,11 @@ +#include "je_mesh.h" + +namespace JinEngine +{ + namespace Graphics + { + + + + } // namespace Graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Graphics/je_mesh.h b/src/libjin/Graphics/je_mesh.h new file mode 100644 index 0000000..ed22d91 --- /dev/null +++ b/src/libjin/Graphics/je_mesh.h @@ -0,0 +1,24 @@ +#ifndef __JE_MESH_H +#define __JE_MESH_H + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// + /// + class Mesh + { + public: + + private: + + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/je_shapes.cpp b/src/libjin/Graphics/je_shapes.cpp new file mode 100644 index 0000000..3146f31 --- /dev/null +++ b/src/libjin/Graphics/je_shapes.cpp @@ -0,0 +1,128 @@ +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include <string> + +#include "../math/je_matrix.h" +#include "../math/je_constant.h" + +#include "shader/je_shader.h" +#include "je_shapes.h" + +namespace JinEngine +{ + namespace Graphics + { + + using namespace Math; + + void point(int x, int y) + { + float verts[] = { x + 0.5f , y + 0.5f }; + + Shader* shader = Shader::getCurrentShader(); + shader->bindVertexPointer(2, GL_FLOAT, 0, verts); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + + glDrawArrays(GL_POINTS, 0, 1); + } + + void points(int n, GLshort* p) + { + Shader* shader = Shader::getCurrentShader(); + shader->bindVertexPointer(2, GL_SHORT, 0, p); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + + glDrawArrays(GL_POINTS, 0, n); + } + + void line(int x1, int y1, int x2, int y2) + { + float verts[] = { + x1, y1, + x2, y2 + }; + + Shader* shader = Shader::getCurrentShader(); + shader->bindVertexPointer(2, GL_FLOAT, 0, verts); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + + glDrawArrays(GL_LINES, 0, 2); + } + + void circle(RenderMode mode, int x, int y, int r) + { + r = r < 0 ? 0 : r; + + int points = 40; + float two_pi = static_cast<float>(PI * 2); + if (points <= 0) points = 1; + float angle_shift = (two_pi / points); + float phi = .0f; + + float *coords = new float[2 * (points + 1)]; + for (int i = 0; i < points; ++i, phi += angle_shift) + { + coords[2 * i] = x + r * cos(phi); + coords[2 * i + 1] = y + r * sin(phi); + } + + coords[2 * points] = coords[0]; + coords[2 * points + 1] = coords[1]; + + polygon(mode, coords, points); + + delete[] coords; + } + + void rect(RenderMode mode, int x, int y, int w, int h) + { + float coords[] = { x, y, x + w, y, x + w, y + h, x, y + h }; + polygon(mode, coords, 4); + } + + void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3) + { + float coords[] = { x1, y1, x2, y2, x3, y3 }; + polygon(mode, coords, 3); + } + + void polygon_line(float* p, int count) + { + Shader* shader = Shader::getCurrentShader(); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, p); + + glDrawArrays(GL_LINE_LOOP, 0, count); + } + + void polygon(RenderMode mode, float* p, int count) + { + if (mode == LINE) + { + polygon_line(p, count); + } + else if (mode == FILL) + { + Shader* shader = Shader::getCurrentShader(); + gl.ModelMatrix.setIdentity(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, p); + + glDrawArrays(GL_POLYGON, 0, count); + } + } + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/Graphics/je_shapes.h b/src/libjin/Graphics/je_shapes.h new file mode 100644 index 0000000..2221526 --- /dev/null +++ b/src/libjin/Graphics/je_shapes.h @@ -0,0 +1,34 @@ +#ifndef __JE_GEOMETRY_H +#define __JE_GEOMETRY_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "je_color.h" +#include "je_canvas.h" +#include "je_texture.h" + +namespace JinEngine +{ + namespace Graphics + { + + typedef enum { + NONE = 0, + FILL , + LINE + }RenderMode; + + extern void line(int x1, int y1, int x2, int y2); + extern void rect(RenderMode mode, int x, int y, int w, int h); + extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3); + extern void circle(RenderMode mode, int x, int y, int r); + extern void point(int x, int y); + extern void points(int n, GLshort* p, GLubyte* c); + extern void polygon(RenderMode mode, float* p, int count); + + } // namespace Graphics +} // namespace JinEngine + +#endif // jin_graphics + +#endif // __JE_GEOMETRY_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_sprite.cpp b/src/libjin/Graphics/je_sprite.cpp new file mode 100644 index 0000000..3ac976a --- /dev/null +++ b/src/libjin/Graphics/je_sprite.cpp @@ -0,0 +1,11 @@ +#include "je_sprite.h" + +namespace JinEngine +{ + namespace Graphics + { + + + + } // namespace Graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Graphics/je_sprite.h b/src/libjin/Graphics/je_sprite.h new file mode 100644 index 0000000..3b96162 --- /dev/null +++ b/src/libjin/Graphics/je_sprite.h @@ -0,0 +1,38 @@ +#ifndef __JE_SPRITE_H +#define __JE_SPRITE_H + +#include "../common/je_types.h" +#include "../math/je_vector2.hpp" + +#include "shader/je_shader.h" +#include "je_color.h" + +namespace JinEngine +{ + namespace Graphics + { + /// + /// A sprite is unit of rendering, logic and events. + /// + class Sprite + { + public: + void setOrigin(float x, float y); + void setPosition(int x, int y); + void setScale(float x, float y); + void setColor(Color color); + void setShader(const Shader* shader); + + private: + Math::Vector2<int> mPosition; + Math::Vector2<float> mOrigin; + Math::Vector2<float> mScale; + Color mColor; + const Shader* mShader; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Input/Joypad.cpp b/src/libjin/Graphics/je_sprite_batch.cpp index e69de29..e69de29 100644 --- a/src/libjin/Input/Joypad.cpp +++ b/src/libjin/Graphics/je_sprite_batch.cpp diff --git a/src/libjin/Graphics/je_sprite_batch.h b/src/libjin/Graphics/je_sprite_batch.h new file mode 100644 index 0000000..85a7951 --- /dev/null +++ b/src/libjin/Graphics/je_sprite_batch.h @@ -0,0 +1,17 @@ +#ifndef __JE_SPRITE_BATCH_H +#define __JE_SPRITE_BATCH_H + +namespace JinEngine +{ + namespace Graphics + { + + class SpriteBatch + { + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/je_texture.cpp b/src/libjin/Graphics/je_texture.cpp new file mode 100644 index 0000000..8aa3f9a --- /dev/null +++ b/src/libjin/Graphics/je_texture.cpp @@ -0,0 +1,44 @@ +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include <fstream> + +#include "../utils/je_utils.h" +#include "../math/je_math.h" + +#include "je_texture.h" + +using namespace JinEngine::Math; + +namespace JinEngine +{ + namespace Graphics + { + + Texture* Texture::createTexture(const char* path) + { + Bitmap* bitmap = Bitmap::createBitmap(path); + Texture* texture = createTexture(bitmap); + delete bitmap; + return texture; + } + + /*static*/ Texture* Texture::createTexture(Bitmap* bitmap) + { + Texture* tex = new Texture(bitmap); + return tex; + } + + Texture::Texture(const Bitmap* bitmap) + : Graphic(bitmap) + { + } + + Texture::~Texture() + { + } + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/Graphics/je_texture.h b/src/libjin/Graphics/je_texture.h new file mode 100644 index 0000000..ddc8cfc --- /dev/null +++ b/src/libjin/Graphics/je_texture.h @@ -0,0 +1,56 @@ +#ifndef __JE_TEXTURE_H +#define __JE_TEXTURE_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "../3rdparty/GLee/GLee.h" + +#include "je_color.h" +#include "je_graphic.h" +#include "je_bitmap.h" + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// + /// + class Texture: public Graphic + { + public: + /// + /// + /// + static Texture* createTexture(const char* path); + + /// + /// + /// + static Texture* createTexture(Bitmap* bitmap); + + /// + /// + /// + static Texture* createTexture(); + + /// + /// + /// + ~Texture(); + + private: + /// + /// + /// + Texture(const Bitmap* bitmap); + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // jin_graphics + +#endif // __JE_TEXTURE_H
\ No newline at end of file diff --git a/src/libjin/Graphics/je_window.cpp b/src/libjin/Graphics/je_window.cpp new file mode 100644 index 0000000..f0b789e --- /dev/null +++ b/src/libjin/Graphics/je_window.cpp @@ -0,0 +1,111 @@ +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include <iostream> + +#include "../utils/je_utils.h" +#include "../audio/sdl/je_sdl_audio.h" +#include "../utils/je_log.h" + +#include "shader/je_shader.h" +#include "je_window.h" +#include "je_gl.h" +#include "je_canvas.h" + +namespace JinEngine +{ + namespace Graphics + { + + bool Window::initSystem(const SettingBase* s) + { + #if defined(jin_debug) + Loghelper::log(Loglevel::LV_INFO, "Init window system"); + #endif + + if (SDL_Init(SDL_INIT_VIDEO) < 0) + return false; + + const Setting* setting = (Setting*)s; + mSize.w = setting->width; + mSize.h = setting->height; + mFps = setting->fps; + bool vsync = setting->vsync; + const char* title = setting->title; + + if (mWnd) + { + SDL_DestroyWindow(mWnd); + SDL_FlushEvent(SDL_WINDOWEVENT); + } + + SDL_GLContext ctx = NULL; + + if (ctx) + { + SDL_GL_DeleteContext(ctx); + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + int wx = SDL_WINDOWPOS_UNDEFINED, + wy = SDL_WINDOWPOS_UNDEFINED; + + int flag = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; + if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN; + if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE; + + mWnd = SDL_CreateWindow(title, wx, wy, mSize.w, mSize.h, flag); + if (mWnd == NULL) + return false; + ctx = SDL_GL_CreateContext(mWnd); + if (ctx == NULL) + return false; + SDL_GL_SetSwapInterval(vsync ? 1 : 0); + SDL_GL_MakeCurrent(mWnd, ctx); + // default configuration + gl.setClearColor(0, 0, 0, 0xff); + gl.pushColor(0xff, 0xff, 0xff, 0xff); + gl.enable(GL_BLEND); + gl.enable(GL_TEXTURE_2D); + gl.setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // avoid white screen blink on windows + swapBuffers(); + // bind to default canvas + Canvas::unbind(); + Shader::unuse(); + return true; + } + + void Window::quitSystem() + { + // disable opengl + gl.disable(GL_BLEND); + gl.disable(GL_TEXTURE_2D); + // close window + SDL_DestroyWindow(mWnd); + SDL_Quit(); + } + + void Window::swapBuffers() + { + if (mWnd) + SDL_GL_SwapWindow(mWnd); + } + + void Window::setTitle(const char* title) + { + SDL_SetWindowTitle(mWnd, title); + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // defined(jin_graphics)
\ No newline at end of file diff --git a/src/libjin/Graphics/je_window.h b/src/libjin/Graphics/je_window.h new file mode 100644 index 0000000..7ca1e5e --- /dev/null +++ b/src/libjin/Graphics/je_window.h @@ -0,0 +1,97 @@ +#ifndef __JE_RENDER_WINDOW +#define __JE_RENDER_WINDOW +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "SDL2/SDL.h" + +#include "../utils/je_utils.h" +#include "../math/je_vector2.hpp" +#include "../common/je_subsystem.hpp" + +namespace JinEngine +{ + namespace Graphics + { + /// + /// + /// + class Window : public Subsystem<Window> + { + public: + /// + /// + /// + struct Setting : SettingBase + { + public: + const char* title; ///< window title + bool fullscreen; ///< full screen + int width, height; ///< window size + bool vsync; ///< vsync + int fps; ///< frame per second + bool resizable; ///< resizable + }; + + /// + /// + /// + void setTitle(const char* title); + + /// + /// + /// + inline int getW(){ return mSize.w; } + + /// + /// + /// + inline int getH(){ return mSize.h; } + + /// + /// + /// + inline int getFPS(){ return mFps; } + + /// + /// + /// + void swapBuffers(); + + private: + + // declare a singleton + singleton(Window); + + /// + /// + /// + Window() {}; + + /// + /// + /// + virtual ~Window() {}; + + /// + /// + /// + bool initSystem(const SettingBase* setting) override; + + /// + /// + /// + void quitSystem() override; + + SDL_Window* mWnd; + JinEngine::Math::Vector2<unsigned int> mSize; + int mFps; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // jin_graphics + +#endif // __JE_RENDER_WINDOW
\ No newline at end of file diff --git a/src/libjin/Input/Keyboard.cpp b/src/libjin/Graphics/particle/je_particle.cpp index e69de29..e69de29 100644 --- a/src/libjin/Input/Keyboard.cpp +++ b/src/libjin/Graphics/particle/je_particle.cpp diff --git a/src/libjin/Graphics/particle/je_particle.h b/src/libjin/Graphics/particle/je_particle.h new file mode 100644 index 0000000..2a5c54f --- /dev/null +++ b/src/libjin/Graphics/particle/je_particle.h @@ -0,0 +1,21 @@ +#ifndef __JE_PARTICLE_H +#define __JE_PARTICLE_H + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// Single particle. + /// + class Particle + { + + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Tilemap/Tilemap.cpp b/src/libjin/Graphics/particle/je_particle_batch.cpp index e69de29..e69de29 100644 --- a/src/libjin/Tilemap/Tilemap.cpp +++ b/src/libjin/Graphics/particle/je_particle_batch.cpp diff --git a/src/libjin/Graphics/particle/je_particle_batch.h b/src/libjin/Graphics/particle/je_particle_batch.h new file mode 100644 index 0000000..19f4ded --- /dev/null +++ b/src/libjin/Graphics/particle/je_particle_batch.h @@ -0,0 +1,20 @@ +#ifndef __JE_PARTICLE_BATCH_H +#define __JE_PARTICLE_BATCH_H + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// + /// + class ParticleBatch + { + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Graphics/particle/je_particle_emitter.cpp b/src/libjin/Graphics/particle/je_particle_emitter.cpp new file mode 100644 index 0000000..d57d5ed --- /dev/null +++ b/src/libjin/Graphics/particle/je_particle_emitter.cpp @@ -0,0 +1,11 @@ +#include "je_particle_emitter.h" + +namespace JinEngine +{ + namespace Graphics + { + + + + } +} diff --git a/src/libjin/Graphics/particle/je_particle_emitter.h b/src/libjin/Graphics/particle/je_particle_emitter.h new file mode 100644 index 0000000..e191e36 --- /dev/null +++ b/src/libjin/Graphics/particle/je_particle_emitter.h @@ -0,0 +1,23 @@ +#ifndef __JE_PARTICLE_EMMITTER_H +#define __JE_PARTICLE_EMMITTER_H + +namespace JinEngine +{ + namespace Graphics + { + + /// + /// Particle emitter + /// + class ParticleEmitter + { + public: + + private: + + }; + + } +} + +#endif
\ No newline at end of file diff --git a/src/libjin/UI/UI.h b/src/libjin/Graphics/particle/je_particle_system.cpp index 6f70f09..6f70f09 100644 --- a/src/libjin/UI/UI.h +++ b/src/libjin/Graphics/particle/je_particle_system.cpp diff --git a/src/libjin/Utils/CSV/CSV.cpp b/src/libjin/Graphics/particle/je_particle_system.h index e69de29..e69de29 100644 --- a/src/libjin/Utils/CSV/CSV.cpp +++ b/src/libjin/Graphics/particle/je_particle_system.h diff --git a/src/libjin/Input/Event.cpp b/src/libjin/Input/Event.cpp deleted file mode 100644 index 8eb45e6..0000000 --- a/src/libjin/Input/Event.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "event.h" -#include "SDL2\SDL.h" - -namespace jin -{ - -}
\ No newline at end of file diff --git a/src/libjin/Input/Event.h b/src/libjin/Input/Event.h deleted file mode 100644 index 9feb3a5..0000000 --- a/src/libjin/Input/Event.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef __JIN_EVENT_H -#define __JIN_EVENT_H -#include "../modules.h" -#if JIN_MODULES_INPUT - -namespace jin -{ -namespace input -{ -#if JIN_INPUT_SDL -#include "SDL.h" - - typedef SDL_Event Event; - typedef SDL_Keycode Key; - typedef SDL_MouseWheelEvent Wheel; - - enum EventType { - QUIT = SDL_QUIT, - KEY_DOWN = SDL_KEYDOWN, - KEY_UP = SDL_KEYUP, - MOUSE_MOTION = SDL_MOUSEMOTION, - MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, - MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, - MOUSE_WHEEL = SDL_MOUSEWHEEL, - WINDOW_EVENT = SDL_WINDOWEVENT, - }; - - enum WindowEvent { - WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , - WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , - WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , - WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , - WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , - WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , - WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , - WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , - WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , - WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , - WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , - WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, - WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , - WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , - WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , - WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , - }; - - inline int pollEvent(Event* e) - { - return SDL_PollEvent(e); - } - - inline const char* getKeyName(Key key) - { - return SDL_GetKeyName(key); - } - - inline const char* getButtonName(int button) - { - switch (button) - { - case 1: return "left"; - case 2: return "middle"; - case 3: return "right"; - case 4: return "wheelup"; - case 5: return "wheeldown"; - default: return "?"; - } - } - -/* - inline const char* getWheelName(Wheel wheel) - { - if (wheel.x == -1) - return "left"; - else if (wheel.x == 1) - return "right"; - else if (wheel.y == -1) - return "near"; - else if (wheel.y == 1) - return "far"; - else - return "none"; - } -*/ - -#endif // JIN_INPUT_SDL -} // input -} // jin - -#endif // JIN_MODULES_INPUT -#endif
\ No newline at end of file diff --git a/src/libjin/Input/Input.h b/src/libjin/Input/Input.h deleted file mode 100644 index 217edd2..0000000 --- a/src/libjin/Input/Input.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __JIN_INPUT_H -#define __JIN_INPUT_H - -#include "event.h" -#include "keyboard.h" -#include "mouse.h" - -#endif
\ No newline at end of file diff --git a/src/libjin/Input/Joypad.h b/src/libjin/Input/Joypad.h deleted file mode 100644 index e8d309b..0000000 --- a/src/libjin/Input/Joypad.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __JIN_JOYPAD_H -#define __JIN_JOYPAD_H - -namespace jin -{ -namespace input -{ - - - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Input/Keyboard.h b/src/libjin/Input/Keyboard.h deleted file mode 100644 index 3e78ab1..0000000 --- a/src/libjin/Input/Keyboard.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __JIN_KEYBOARD_H -#define __JIN_KEYBOARD_H - -namespace jin -{ -namespace input -{ - class Keyboard - { - - }; -} -} - -#endif // __JIN_KEYBOARD_H
\ No newline at end of file diff --git a/src/libjin/Input/Mouse.cpp b/src/libjin/Input/Mouse.cpp deleted file mode 100644 index 98c4a39..0000000 --- a/src/libjin/Input/Mouse.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../modules.h" -#ifdef JIN_MODULES_INPUT - -#include "SDL.h" -#include "Mouse.h" - -namespace jin -{ -namespace input -{ - - void Mouse::getState(int* x, int* y) - { -#ifdef JIN_INPUT_SDL - SDL_GetMouseState(x, y); -#endif // JIN_INPUT_SDL - } - -} // input -} // jin - -#endif // JIN_MODULES_INPUT
\ No newline at end of file diff --git a/src/libjin/Input/Mouse.h b/src/libjin/Input/Mouse.h deleted file mode 100644 index 5fc6b47..0000000 --- a/src/libjin/Input/Mouse.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __JIN_MOUSE_H -#define __JIN_MOUSE_H -#include "../modules.h" -#ifdef JIN_MODULES_INPUT - -#include "../Common/Singleton.hpp" - -namespace jin -{ -namespace input -{ - class Mouse : public Singleton<Mouse> - { - public: - - // - void getState(int* x, int* y); - - private: - Mouse() {}; - ~Mouse() {}; - - SINGLETON(Mouse); - }; -} -} - -#endif // JIN_MODULES_INPUT -#endif // __JIN_MOUSE_H
\ No newline at end of file diff --git a/src/libjin/Input/je_event.cpp b/src/libjin/Input/je_event.cpp new file mode 100644 index 0000000..318ce59 --- /dev/null +++ b/src/libjin/Input/je_event.cpp @@ -0,0 +1,8 @@ +#include "SDL2\SDL.h" + +#include "je_event.h" + +namespace JinEngine +{ + +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Input/je_event.h b/src/libjin/Input/je_event.h new file mode 100644 index 0000000..126d0f6 --- /dev/null +++ b/src/libjin/Input/je_event.h @@ -0,0 +1,121 @@ +#ifndef __JE_EVENT_H +#define __JE_EVENT_H +#include "../core/je_configuration.h" +#if defined(jin_input) + +namespace JinEngine +{ + namespace Input + { + #if jin_input == jin_input_sdl + #include "SDL.h" + + typedef SDL_Event Event; + typedef SDL_Keycode Key; + typedef SDL_MouseWheelEvent Wheel; + + /// + /// + /// + enum EventType { + QUIT = SDL_QUIT, + /* keyboard events */ + KEY_DOWN = SDL_KEYDOWN, + KEY_UP = SDL_KEYUP, + /* mouse events */ + MOUSE_MOTION = SDL_MOUSEMOTION, + MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, + MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, + MOUSE_WHEEL = SDL_MOUSEWHEEL, + /* joypad events */ + JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, + JOYBUTTONUP = SDL_JOYBUTTONUP, + JOYAXISMOTION = SDL_JOYAXISMOTION, + JOYBALLMOTION = SDL_JOYBALLMOTION, + JOYHATMOTION = SDL_JOYHATMOTION, + JOYDEVICEADDED = SDL_JOYDEVICEADDED, + JOYDEVICEREMOVED = SDL_JOYDEVICEREMOVED, + CONTROLLERBUTTONDOWN = SDL_CONTROLLERBUTTONDOWN, + CONTROLLERBUTTONUP = SDL_CONTROLLERBUTTONUP, + CONTROLLERAXISMOTION = SDL_CONTROLLERAXISMOTION, + /* window evnets */ + WINDOW_EVENT = SDL_WINDOWEVENT, + }; + + /// + /// + /// + enum WindowEvent { + WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , + WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , + WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , + WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , + WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , + WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , + WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , + WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , + WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , + WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , + WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , + WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, + WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , + WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , + WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , + WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , + }; + + /// + /// + /// + inline int pollEvent(Event* e) + { + return SDL_PollEvent(e); + } + + /// + /// + /// + inline const char* getKeyName(Key key) + { + return SDL_GetKeyName(key); + } + + /// + /// + /// + inline const char* getButtonName(int button) + { + switch (button) + { + case 1: return "Left"; + case 2: return "Middle"; + case 3: return "Right"; + case 4: return "WheelUp"; + case 5: return "WheelDown"; + default: return "?"; + } + } + + /* + inline const char* getWheelName(Wheel wheel) + { + if (wheel.x == -1) + return "left"; + else if (wheel.x == 1) + return "right"; + else if (wheel.y == -1) + return "near"; + else if (wheel.y == 1) + return "far"; + else + return "none"; + } + */ + + #endif // jin_input == jin_input_sdl + } // namespace Input +} // namespace JinEngine + +#endif // defined(jin_input) + +#endif // __JE_EVENT_H
\ No newline at end of file diff --git a/src/libjin/Input/je_input.h b/src/libjin/Input/je_input.h new file mode 100644 index 0000000..8c7faf7 --- /dev/null +++ b/src/libjin/Input/je_input.h @@ -0,0 +1,9 @@ +#ifndef __JE_INPUT_H +#define __JE_INPUT_H + +#include "je_event.h" +#include "je_keyboard.h" +#include "je_mouse.h" +#include "je_joypad.h" + +#endif
\ No newline at end of file diff --git a/src/libjin/Utils/Json/Json.cpp b/src/libjin/Input/je_joypad.cpp index e69de29..e69de29 100644 --- a/src/libjin/Utils/Json/Json.cpp +++ b/src/libjin/Input/je_joypad.cpp diff --git a/src/libjin/Input/je_joypad.h b/src/libjin/Input/je_joypad.h new file mode 100644 index 0000000..74173af --- /dev/null +++ b/src/libjin/Input/je_joypad.h @@ -0,0 +1,56 @@ +#ifndef __JE_JOYPAD_H +#define __JE_JOYPAD_H + +#include <SDL2/SDL.h> + +namespace JinEngine +{ + namespace Input + { + + /// + /// + /// + inline const char* getJoyButtonName(int button) + { + switch (button) + { + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: return "A"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B : return "B"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X : return "X"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y: return "Y"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: return "Back"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE: return "Guide"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return "Start"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: return "LeftStick"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: return "RightStick"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return "LeftShoulder"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return "RightShoulder"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: return "DpadUp"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: return "DpadDown"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: return "DpadLeft"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return "DpadRight"; break; + default: return NULL; + } + } + + /// + /// + /// + inline const char* getJoyAxisName(int axis) + { + switch (axis) + { + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: return "LeftX"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: return "LeftY"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: return "RightX"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: return "RightY"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return "TriggerLeft"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return "TriggerRight"; break; + } + } + + } // namespace Input +} // namespace JinEngine + +#endif // __JE_JOYPAD_H
\ No newline at end of file diff --git a/src/libjin/Utils/XML/XML.cpp b/src/libjin/Input/je_keyboard.cpp index e69de29..e69de29 100644 --- a/src/libjin/Utils/XML/XML.cpp +++ b/src/libjin/Input/je_keyboard.cpp diff --git a/src/libjin/Input/je_keyboard.h b/src/libjin/Input/je_keyboard.h new file mode 100644 index 0000000..61da361 --- /dev/null +++ b/src/libjin/Input/je_keyboard.h @@ -0,0 +1,20 @@ +#ifndef __JE_KEYBOARD_H +#define __JE_KEYBOARD_H + +namespace JinEngine +{ + namespace Input + { + + /// + /// + /// + class Keyboard + { + + }; + + } // namespace Input +} // namespace JinEngine + +#endif // __JE_KEYBOARD_H
\ No newline at end of file diff --git a/src/libjin/Input/je_mouse.cpp b/src/libjin/Input/je_mouse.cpp new file mode 100644 index 0000000..476b1a2 --- /dev/null +++ b/src/libjin/Input/je_mouse.cpp @@ -0,0 +1,28 @@ +#include "../core/je_configuration.h" +#if defined(jin_input) + +#include "SDL.h" + +#include "je_mouse.h" + +namespace JinEngine +{ + namespace Input + { + + void Mouse::getState(int* x, int* y) + { + #ifdef jin_input == jin_input_sdl + SDL_GetMouseState(x, y); + #endif + } + + void Mouse::setVisible(bool visible) + { + SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); + } + + } // namespace Input +} // namespace JinEngine + +#endif // defined(jin_input)
\ No newline at end of file diff --git a/src/libjin/Input/je_mouse.h b/src/libjin/Input/je_mouse.h new file mode 100644 index 0000000..29038ec --- /dev/null +++ b/src/libjin/Input/je_mouse.h @@ -0,0 +1,49 @@ +#ifndef __JE_MOUSE_H +#define __JE_MOUSE_H +#include "../core/je_configuration.h" +#if defined(jin_input) + +#include "../common/je_singleton.hpp" + +namespace JinEngine +{ + namespace Input + { + + /// + /// + /// + class Mouse : public Singleton<Mouse> + { + public: + /// + /// + /// + void getState(int* x, int* y); + + /// + /// + /// + void setVisible(bool visible); + + private: + singleton(Mouse); + + /// + /// + /// + Mouse() {}; + + /// + /// + /// + ~Mouse() {}; + + }; + + } // namespace Input +} // namespace JinEngine + +#endif // defined(jin_input) + +#endif // __JE_MOUSE_H
\ No newline at end of file diff --git a/src/libjin/Math/Math.h b/src/libjin/Math/Math.h deleted file mode 100644 index 2bc8ed9..0000000 --- a/src/libjin/Math/Math.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __JIN_UTILS_MATH_H -#define __JIN_UTILS_MATH_H - -#include "constant.h" -#include "matrix.h" -#include "quad.h" - -namespace jin -{ -namespace math -{ - -#ifdef min -# undef min -#endif // min -#ifdef max -# undef max -#endif // max - - template<typename T> - inline T min(T a, T b) - { - return a < b ? a : b; - } - - template<typename T> - inline T max(T a, T b) - { - return a > b ? a : b; - } - - template<typename T> - inline T clamp(T a, T mi, T ma) - { - return min<T>(max<T>(a, mi), ma); - } - - template<typename T> - inline bool within(T a, T mi, T ma) - { - return a >= mi && a <= ma; - } - - template<typename T> - inline bool without(T a, T mi, T ma) - { - return a < mi || a > ma; - } - - template<typename T> - inline T abs(T a) - { - return a > 0 ? a : -a; - } - - template<typename T> - inline T lowerBound(T a, T lower) - { - return a < lower ? lower : a; - } - - template<typename T> - inline T upperBound(T a, T upper) - { - return a > upper ? upper : a; - } - - template<typename T> - inline T lerp(T a, T b, float t) - { - return a + t * (b - a); - } - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Math/Matrix.cpp b/src/libjin/Math/Matrix.cpp deleted file mode 100644 index 97e9178..0000000 --- a/src/libjin/Math/Matrix.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "Matrix.h" - -#include <cstring> // memcpy -#include <cmath> - -namespace jin -{ -namespace math -{ - - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - Matrix::Matrix() - { - setIdentity(); - } - - Matrix::~Matrix() - { - } - - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - Matrix Matrix::operator * (const Matrix & m) const - { - Matrix t; - - t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]); - t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]); - t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]); - t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]); - - t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]); - t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]); - t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]); - t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]); - - t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]); - t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]); - t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]); - t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]); - - t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]); - t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]); - t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]); - t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]); - - return t; - } - - void Matrix::operator *= (const Matrix & m) - { - Matrix t = (*this) * m; - memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16); - } - - const float * Matrix::getElements() const - { - return e; - } - - void Matrix::setIdentity() - { - memset(e, 0, sizeof(float) * 16); - e[0] = e[5] = e[10] = e[15] = 1; - } - - void Matrix::setTranslation(float x, float y) - { - setIdentity(); - e[12] = x; - e[13] = y; - } - - void Matrix::setRotation(float rad) - { - setIdentity(); - float c = cos(rad), s = sin(rad); - e[0] = c; e[4] = -s; - e[1] = s; e[5] = c; - } - - void Matrix::setScale(float sx, float sy) - { - setIdentity(); - e[0] = sx; - e[5] = sy; - } - - void Matrix::setShear(float kx, float ky) - { - setIdentity(); - e[1] = ky; - e[4] = kx; - } - - void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy) - { - memset(e, 0, sizeof(float) * 16); // zero out matrix - float c = cos(angle), s = sin(angle); - // matrix multiplication carried out on paper: - // |1 x| |c -s | |sx | |1 -ox| - // | 1 y| |s c | | sy | | 1 -oy| - // | 1 | | 1 | | 1 | | 1 | - // | 1| | 1| | 1| | 1 | - // move rotate scale origin - e[10] = e[15] = 1.0f; - e[0] = c * sx ; // = a - e[1] = s * sx ; // = b - e[4] = - s * sy; // = c - e[5] = c * sy; // = d - e[12] = x - ox * e[0] - oy * e[4]; - e[13] = y - ox * e[1] - oy * e[5]; - } - - void Matrix::translate(float x, float y) - { - Matrix t; - t.setTranslation(x, y); - this->operator *=(t); - } - - void Matrix::rotate(float rad) - { - Matrix t; - t.setRotation(rad); - this->operator *=(t); - } - - void Matrix::scale(float sx, float sy) - { - Matrix t; - t.setScale(sx, sy); - this->operator *=(t); - } - - void Matrix::shear(float kx, float ky) - { - Matrix t; - t.setShear(kx, ky); - this->operator *=(t); - } - - // | x | - // | y | - // | 0 | - // | 1 | - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - void Matrix::transform(vertex * dst, const vertex * src, int size) const - { - for (int i = 0; i<size; ++i) - { - // Store in temp variables in case src = dst - float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]); - float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]); - - dst[i].x = x; - dst[i].y = y; - } - } - -} -}
\ No newline at end of file diff --git a/src/libjin/Math/Matrix.h b/src/libjin/Math/Matrix.h deleted file mode 100644 index ff4a51a..0000000 --- a/src/libjin/Math/Matrix.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __JIN_MATRIX_H -#define __JIN_MATRIX_H - -namespace jin -{ -namespace math -{ - - struct vertex - { - unsigned char r, g, b, a; - float x, y; - float s, t; - }; - /** - * This class is the basis for all transformations in LOVE. Althought not - * really needed for 2D, it contains 4x4 elements to be compatible with - * OpenGL without conversions. - **/ - class Matrix - { - private: - - /** - * | e0 e4 e8 e12 | - * | e1 e5 e9 e13 | - * | e2 e6 e10 e14 | - * | e3 e7 e11 e15 | - **/ - float e[16]; - - public: - - /** - * Creates a new identity matrix. - **/ - Matrix(); - - /** - * Destructor. - **/ - ~Matrix(); - - /** - * Multiplies this Matrix with another Matrix, changing neither. - * @param m The Matrix to multiply with this Matrix. - * @return The combined matrix. - **/ - Matrix operator * (const Matrix & m) const; - - /** - * Multiplies a Matrix into this Matrix. - * @param m The Matrix to combine into this Matrix. - **/ - void operator *= (const Matrix & m); - - /** - * Gets a pointer to the 16 array elements. - * @return The array elements. - **/ - const float * getElements() const; - - /** - * Resets this Matrix to the identity matrix. - **/ - void setIdentity(); - - /** - * Resets this Matrix to a translation. - * @param x Translation along x-axis. - * @param y Translation along y-axis. - **/ - void setTranslation(float x, float y); - - /** - * Resets this Matrix to a rotation. - * @param r The angle in radians. - **/ - void setRotation(float r); - - /** - * Resets this Matrix to a scale transformation. - * @param sx Scale factor along the x-axis. - * @param sy Scale factor along the y-axis. - **/ - void setScale(float sx, float sy); - - /** - * Resets this Matrix to a shear transformation. - * @param kx Shear along x-axis. - * @param ky Shear along y-axis. - **/ - void setShear(float kx, float ky); - - /** - * Creates a transformation with a certain position, orientation, scale - * and offset. Perfect for Drawables -- what a coincidence! - * - * @param x The translation along the x-axis. - * @param y The translation along the y-axis. - * @param angle The rotation (rad) around the center with offset (ox,oy). - * @param sx Scale along x-axis. - * @param sy Scale along y-axis. - * @param ox The offset for rotation along the x-axis. - * @param oy The offset for rotation along the y-axis. - * @param kx Shear along x-axis - * @param ky Shear along y-axis - **/ - void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); - - /** - * Multiplies this Matrix with a translation. - * @param x Translation along x-axis. - * @param y Translation along y-axis. - **/ - void translate(float x, float y); - - /** - * Multiplies this Matrix with a rotation. - * @param r Angle in radians. - **/ - void rotate(float r); - - /** - * Multiplies this Matrix with a scale transformation. - * @param sx Scale factor along the x-axis. - * @param sy Scale factor along the y-axis. - **/ - void scale(float sx, float sy); - - /** - * Multiplies this Matrix with a shear transformation. - * @param kx Shear along the x-axis. - * @param ky Shear along the y-axis. - **/ - void shear(float kx, float ky); - - /** - * Transforms an array of vertices by this Matrix. The sources and - * destination arrays may be the same. - * - * @param dst Storage for the transformed vertices. - * @param src The source vertices. - * @param size The number of vertices. - **/ - void transform(vertex * dst, const vertex * src, int size) const; - - }; - -} -} - -#endif diff --git a/src/libjin/Math/Quad.h b/src/libjin/Math/Quad.h deleted file mode 100644 index a50cc9e..0000000 --- a/src/libjin/Math/Quad.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JIN_QUAD_H -#define __JIN_QUAD_H - -namespace jin -{ -namespace math -{ - - struct Quad - { - float x, y, w, h; - }; - -} -} - -#endif diff --git a/src/libjin/Math/README.md b/src/libjin/Math/README.md new file mode 100644 index 0000000..a096332 --- /dev/null +++ b/src/libjin/Math/README.md @@ -0,0 +1 @@ +ļռΪJinEngineڴģ乲õ
\ No newline at end of file diff --git a/src/libjin/Math/Vector.cpp b/src/libjin/Math/Vector.cpp deleted file mode 100644 index f26d0c4..0000000 --- a/src/libjin/Math/Vector.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "vector.h" - diff --git a/src/libjin/Math/Vector.h b/src/libjin/Math/Vector.h deleted file mode 100644 index 43e249e..0000000 --- a/src/libjin/Math/Vector.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __JIN_VECTOR_H -#define __JIN_VECTOR_H - -namespace jin -{ -namespace math -{ - - - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Math/constant.h b/src/libjin/Math/je_constant.h index f2f740f..5ab126c 100644 --- a/src/libjin/Math/constant.h +++ b/src/libjin/Math/je_constant.h @@ -1,5 +1,5 @@ -#ifndef __JIN_MATH_CONSTANT_H -#define __JIN_MATH_CONSTANT_H +#ifndef __JE_MATH_CONSTANT_H +#define __JE_MATH_CONSTANT_H #define PI 3.1415926f diff --git a/src/libjin/Math/je_math.h b/src/libjin/Math/je_math.h new file mode 100644 index 0000000..1f8e0b3 --- /dev/null +++ b/src/libjin/Math/je_math.h @@ -0,0 +1,77 @@ +#ifndef __JE_UTILS_MATH_H +#define __JE_UTILS_MATH_H + +#include "je_constant.h" +#include "je_matrix.h" +#include "je_quad.h" + +namespace JinEngine +{ + namespace Math + { + + #ifdef min + #undef min + #endif // min + #ifdef max + #undef max + #endif // max + + template<typename T> + inline T min(T a, T b) + { + return a < b ? a : b; + } + + template<typename T> + inline T max(T a, T b) + { + return a > b ? a : b; + } + + template<typename T> + inline T clamp(T a, T mi, T ma) + { + return min<T>(max<T>(a, mi), ma); + } + + template<typename T> + inline bool within(T a, T mi, T ma) + { + return a >= mi && a <= ma; + } + + template<typename T> + inline bool without(T a, T mi, T ma) + { + return a < mi || a > ma; + } + + template<typename T> + inline T abs(T a) + { + return a > 0 ? a : -a; + } + + template<typename T> + inline T lowerBound(T a, T lower) + { + return a < lower ? lower : a; + } + + template<typename T> + inline T upperBound(T a, T upper) + { + return a > upper ? upper : a; + } + + template<typename T> + inline T lerp(T a, T b, float t) + { + return a + t * (b - a); + } + + } // namespace Math +} // namespace JinEngine + +#endif // __JE_UTILS_MATH_H
\ No newline at end of file diff --git a/src/libjin/Math/je_matrix.cpp b/src/libjin/Math/je_matrix.cpp new file mode 100644 index 0000000..bc1fcea --- /dev/null +++ b/src/libjin/Math/je_matrix.cpp @@ -0,0 +1,194 @@ +#include "je_matrix.h" + +#include <cstring> // memcpy +#include <cmath> + +namespace JinEngine +{ + namespace Math + { + + const Matrix Matrix::Identity; + + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + Matrix::Matrix() + { + setIdentity(); + } + + Matrix::~Matrix() + { + } + + void Matrix::setOrtho(float l, float r, float b, float t, float n, float f) + { + setIdentity(); + float w = r - l; + float h = t - b; + float z = f - n; + e[0] = 2 / w; + e[5] = 2 / h; + e[10] = -2 / z; + e[12] = -(r + l) / w; + e[13] = -(t + b) / h; + e[14] = -(f + n) / z; + e[15] = 1; + } + + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + Matrix Matrix::operator * (const Matrix & m) const + { + Matrix t; + + t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]); + t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]); + t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]); + t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]); + + t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]); + t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]); + t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]); + t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]); + + t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]); + t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]); + t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]); + t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]); + + t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]); + t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]); + t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]); + t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]); + + return t; + } + + void Matrix::operator *= (const Matrix & m) + { + Matrix t = (*this) * m; + memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16); + } + + const float * Matrix::getElements() const + { + return e; + } + + void Matrix::setIdentity() + { + memset(e, 0, sizeof(float) * 16); + e[0] = e[5] = e[10] = e[15] = 1; + } + + void Matrix::setTranslation(float x, float y) + { + setIdentity(); + e[12] = x; + e[13] = y; + } + + void Matrix::setRotation(float rad) + { + setIdentity(); + float c = cos(rad), s = sin(rad); + e[0] = c; e[4] = -s; + e[1] = s; e[5] = c; + } + + void Matrix::setScale(float sx, float sy) + { + setIdentity(); + e[0] = sx; + e[5] = sy; + } + + void Matrix::setShear(float kx, float ky) + { + setIdentity(); + e[1] = ky; + e[4] = kx; + } + + void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy) + { + memset(e, 0, sizeof(float) * 16); // zero out matrix + float c = cos(angle), s = sin(angle); + // matrix multiplication carried out on paper: + // |1 x| |c -s | |sx | |1 -ox| + // | 1 y| |s c | | sy | | 1 -oy| + // | 1 | | 1 | | 1 | | 1 | + // | 1| | 1| | 1| | 1 | + // move rotate scale origin + e[10] = e[15] = 1.0f; + e[0] = c * sx ; // = a + e[1] = s * sx ; // = b + e[4] = - s * sy; // = c + e[5] = c * sy; // = d + e[12] = x - ox * e[0] - oy * e[4]; + e[13] = y - ox * e[1] - oy * e[5]; + } + + void Matrix::translate(float x, float y) + { + Matrix t; + t.setTranslation(x, y); + this->operator *=(t); + } + + void Matrix::rotate(float rad) + { + Matrix t; + t.setRotation(rad); + this->operator *=(t); + } + + void Matrix::scale(float sx, float sy) + { + Matrix t; + t.setScale(sx, sy); + this->operator *=(t); + } + + void Matrix::shear(float kx, float ky) + { + Matrix t; + t.setShear(kx, ky); + this->operator *=(t); + } + + // | x | + // | y | + // | 0 | + // | 1 | + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + void Matrix::transform(vertex * dst, const vertex * src, int size) const + { + for (int i = 0; i<size; ++i) + { + // Store in temp variables in case src = dst + float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]); + float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]); + + dst[i].x = x; + dst[i].y = y; + } + } + + } // namespace Math +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Math/je_matrix.h b/src/libjin/Math/je_matrix.h new file mode 100644 index 0000000..3592d18 --- /dev/null +++ b/src/libjin/Math/je_matrix.h @@ -0,0 +1,159 @@ +#ifndef __JE_MATRIX_H +#define __JE_MATRIX_H + +namespace JinEngine +{ + namespace Math + { + + struct vertex + { + unsigned char r, g, b, a; + float x, y; + float s, t; + }; + /// + /// This class is the basis for all transformations in LOVE. Althought not + /// really needed for 2D, it contains 4x4 elements to be compatible with + /// OpenGL without conversions. + /// Ҫתõľ + /// https://blog.csdn.net/candycat1992/article/details/8830894 + /// + class Matrix + { + private: + + /// + /// | e0 e4 e8 e12 | + /// | e1 e5 e9 e13 | + /// | e2 e6 e10 e14 | + /// | e3 e7 e11 e15 | + /// + float e[16]; + + public: + + static const Matrix Identity; + + /// + /// Creates a new identity matrix. + /// + Matrix(); + + /// + /// Destructor. + /// + ~Matrix(); + + void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); + + /// + /// Multiplies this Matrix with another Matrix, changing neither. + /// @param m The Matrix to multiply with this Matrix. + /// @return The combined matrix. + /// + Matrix operator * (const Matrix & m) const; + + /// + /// Multiplies a Matrix into this Matrix. + /// @param m The Matrix to combine into this Matrix. + /// + void operator *= (const Matrix & m); + + /// + /// Gets a pointer to the 16 array elements. + /// @return The array elements. + /// + const float* getElements() const; + + /// + /// Resets this Matrix to the identity matrix. + /// + void setIdentity(); + + /// + /// Resets this Matrix to a translation. + /// @param x Translation along x-axis. + /// @param y Translation along y-axis. + /// + void setTranslation(float x, float y); + + /// + /// Resets this Matrix to a rotation. + /// @param r The angle in radians. + /// + void setRotation(float r); + + /// + /// Resets this Matrix to a scale transformation. + /// @param sx Scale factor along the x-axis. + /// @param sy Scale factor along the y-axis. + /// + void setScale(float sx, float sy); + + /// + /// Resets this Matrix to a shear transformation. + /// @param kx Shear along x-axis. + /// @param ky Shear along y-axis. + /// + void setShear(float kx, float ky); + + /// + /// Creates a transformation with a certain position, orientation, scale + /// and offset. Perfect for Drawables -- what a coincidence! + /// + /// @param x The translation along the x-axis. + /// @param y The translation along the y-axis. + /// @param angle The rotation (rad) around the center with offset (ox,oy). + /// @param sx Scale along x-axis. + /// @param sy Scale along y-axis. + /// @param ox The offset for rotation along the x-axis. + /// @param oy The offset for rotation along the y-axis. + /// @param kx Shear along x-axis + /// @param ky Shear along y-axis + /// + void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); + + /// + /// Multiplies this Matrix with a translation. + /// @param x Translation along x-axis. + /// @param y Translation along y-axis. + /// + void translate(float x, float y); + + /// + /// Multiplies this Matrix with a rotation. + /// @param r Angle in radians. + /// + void rotate(float r); + + /// + /// Multiplies this Matrix with a scale transformation. + /// @param sx Scale factor along the x-axis. + /// @param sy Scale factor along the y-axis. + /// + void scale(float sx, float sy); + + /// + /// Multiplies this Matrix with a shear transformation. + /// @param kx Shear along the x-axis. + /// @param ky Shear along the y-axis. + /// + void shear(float kx, float ky); + + /// + /// Transforms an array of vertices by this Matrix. The sources and + /// destination arrays may be the same. + /// + /// @param dst Storage for the transformed vertices. + /// @param src The source vertices. + /// @param size The number of vertices. + /// + void transform(vertex * dst, const vertex * src, int size) const; + + }; + + } // namespace Math +} // namespace JinEngine + +#endif // __JE_MATRIX_H
\ No newline at end of file diff --git a/src/libjin/Math/je_quad.h b/src/libjin/Math/je_quad.h new file mode 100644 index 0000000..2a66fa1 --- /dev/null +++ b/src/libjin/Math/je_quad.h @@ -0,0 +1,23 @@ +#ifndef __JE_QUAD_H +#define __JE_QUAD_H + +namespace JinEngine +{ + namespace Math + { + + /// + /// + /// + struct Quad + { + /// + /// + /// + float x, y, w, h; + }; + + } // namespace Math +} // namespace JinEngine + +#endif // __JE_QUAD_H
\ No newline at end of file diff --git a/src/libjin/Math/je_random.h b/src/libjin/Math/je_random.h new file mode 100644 index 0000000..eb59341 --- /dev/null +++ b/src/libjin/Math/je_random.h @@ -0,0 +1,14 @@ +#ifndef __JE_RANDOM_H +#define __JE_RANDOM_H + +namespace JinEngine +{ + namespace Math + { + + + + } +} + +#endif
\ No newline at end of file diff --git a/src/libjin/Math/je_vector2.hpp b/src/libjin/Math/je_vector2.hpp new file mode 100644 index 0000000..a2b3371 --- /dev/null +++ b/src/libjin/Math/je_vector2.hpp @@ -0,0 +1,40 @@ +#ifndef __JE_VECTOR_H +#define __JE_VECTOR_H + +namespace JinEngine +{ + namespace Math + { + + template<typename T> + class Vector2 + { + public: + Vector2() + { + data[0] = data[1] = 0; + } + Vector2(T _x, T _y) + { + data[0] = _x; + data[1] = _y; + } + Vector2(const Vector2<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + } + + T &x = data[0], &y = data[1]; // xy + T &w = data[0], &h = data[1]; // wh + T &colum = data[0], &row = data[1]; // colum row + + private: + T data[2]; + + }; + + } // namespace Math +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Math/je_vector3.hpp b/src/libjin/Math/je_vector3.hpp new file mode 100644 index 0000000..0f9448d --- /dev/null +++ b/src/libjin/Math/je_vector3.hpp @@ -0,0 +1,41 @@ +#ifndef __JE_VECTOR3_H +#define __JE_VECTOR3_H + +namespace JinEngine +{ + namespace Math + { + + template<typename T> + class Vector3 + { + public: + Vector3() + { + data[0] = data[1] = data[2] = 0; + } + Vector3(T _x, T _y, T _z) + { + data[0] = _x; + data[1] = _y; + data[2] = _z; + } + Vector3(const Vector3<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + data[2] = v.data[2]; + } + + T &x = data[0], &y = data[1], &z = data[2]; // xyz + T &r = data[0], &g = data[1], &b = data[2]; // rgb + + private: + T data[3]; + + }; + + } // namespace Math +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Math/je_vector4.hpp b/src/libjin/Math/je_vector4.hpp new file mode 100644 index 0000000..20353eb --- /dev/null +++ b/src/libjin/Math/je_vector4.hpp @@ -0,0 +1,45 @@ +#ifndef __JE_VECTOR4_H +#define __JE_VECTOR4_H + +namespace JinEngine +{ + namespace Math + { + + template<typename T> + class Vector4 + { + public: + Vector4() + { + data[0] = data[1] = data[2] = data[3] = 0; + } + Vector4(T _x, T _y, T _z, T _t) + { + data[0] = _x; + data[1] = _y; + data[2] = _z; + data[3] = _t; + } + Vector4(const Vector4<T>& v) + { + data[0] = v.data[0]; + data[1] = v.data[1]; + data[2] = v.data[2]; + data[3] = v.data[3]; + } + + T &x = data[0], &y = data[1], &z = data[2], &t = data[3]; // xyzt + T &w = data[2], &h = data[3]; // xywh + T &r = data[0], &g = data[1], &b = data[2], &a = data[3]; // rgb + T &left = data[0], &right = data[1], &top = data[2], &bottom = data[3]; // lrtb + + private: + T data[4]; + + }; + + } // namespace Math +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin/Net/Net.cpp b/src/libjin/Net/Net.cpp deleted file mode 100644 index db39be7..0000000 --- a/src/libjin/Net/Net.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "Net.h" - -namespace jin -{ -namespace net -{ - - bool Net::initSystem(const SettingBase* setting) - { - #ifdef _WIN32 - #if JIN_NET_TEKCOS - tk_init(); - #endif - #endif - return true; - } - - void Net::quitSystem() - { - - } - -} -} diff --git a/src/libjin/Net/Net.h b/src/libjin/Net/Net.h deleted file mode 100644 index 54ffede..0000000 --- a/src/libjin/Net/Net.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __JIN_NET_H -#define __JIN_NET_H -#include "../modules.h" -#if JIN_MODULES_NET - -#include "../Common/Subsystem.hpp" -#include "Socket.h" - -namespace jin -{ -namespace net -{ - - class Net : public Subsystem<Net> - { - public: - - protected: - Net() {}; - ~Net() {}; - SINGLETON(Net); - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - }; - -} -} - -#endif // JIN_MODULES_NET -#endif // __JIN_NET_H
\ No newline at end of file diff --git a/src/libjin/Net/Socket.cpp b/src/libjin/Net/Socket.cpp deleted file mode 100644 index cfc593a..0000000 --- a/src/libjin/Net/Socket.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "Socket.h" - -namespace jin -{ -namespace net -{ - Socket::Socket(const Socket& socket) - : handle(socket.handle) - , type(socket.type) - { - } - - Socket::Socket(const SocketInformation& info) - : type(info.type) - { - if (type == SocketType::TCP) - { - tk_IPaddress ip; - ip.host = info.address; - ip.port = info.port; - handle.tcpHandle = tk_tcp_open(ip); - } - else if (type == SocketType::UDP) - { - handle.udpHandle = tk_udp_open(info.port); - } - } - - Socket::Socket(SocketType type, const char* address, unsigned short port) - { - this->type = type; - if (type == SocketType::TCP) - { - tk_IPaddress ip; - #if JIN_NET_TEKCOS - ip.host = tk_strtohl(address); - ip.port = port; - handle.tcpHandle = tk_tcp_open(ip); - #endif - } - else if (type == SocketType::UDP) - { - handle.udpHandle = tk_udp_open(port); - } - } - - Socket::Socket(SocketType type, unsigned int address, unsigned short port) - { - this->type = type; - if (type == SocketType::TCP) - { - tk_IPaddress ip; - ip.host = address; - ip.port = port; - handle.tcpHandle = tk_tcp_open(ip); - } - else if (type == SocketType::UDP) - { - handle.udpHandle = tk_udp_open(port); - } - } - - Socket::Socket(SocketType type, unsigned short port) - { - this->type = type; - if (type == SocketType::TCP) - { - tk_IPaddress ip; - ip.host = 0; - ip.port = port; - handle.tcpHandle = tk_tcp_open(ip); - } - else if (type == SocketType::UDP) - { - handle.udpHandle = tk_udp_open(port); - } - } - -#if JIN_NET_TEKCOS - - Socket::Socket(const tk_TCPsocket& tcphandle) - { - handle.tcpHandle = tcphandle; - } - - Socket::Socket(const tk_UDPsocket& udphandle) - { - handle.udpHandle = udphandle; - } - -#endif // JIN_NET_TEKCOS - - Socket::~Socket() - { - } - - void Socket::configureBlocking(bool blocking) - { - if (type != SocketType::TCP) - return; - #if JIN_NET_TEKCOS - if (blocking) - tk_tcp_blocking(&handle.tcpHandle); - else - tk_tcp_nonblocking(&handle.tcpHandle); - #endif - } - - Socket* Socket::accept() - { - if (type != SocketType::TCP) - return nullptr; - Socket* client; - #if JIN_NET_TEKCOS - tk_TCPsocket socket = tk_tcp_accept(&handle.tcpHandle); - client = new Socket(socket); - #endif - return client; - } - - int Socket::receive(char* buffer, int size) - { - if (type != SocketType::TCP) - return 0; - #if JIN_NET_TEKCOS - int len; - tk_tcp_recv(&handle.tcpHandle, buffer, size, &len); - return len; - #endif - } - - int Socket::send(char* buffer, int size) - { - if (type != SocketType::TCP) - return 0; - #if JIN_NET_TEKCOS - int len; - tk_tcp_send(&handle.tcpHandle, buffer, size, &len); - return len; - #endif - } - - void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port) - { - if (type != SocketType::UDP) - return; - #if JIN_NET_TEKCOS - tk_UDPpack pack; - pack.data = buffer; - pack.len = size; - pack.ip.host = address; - pack.ip.port = port; - tk_udp_sendto(&handle.udpHandle, &pack); - #endif - } - - int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port) - { - if (type != SocketType::UDP) - return 0; - int len; - #if JIN_NET_TEKCOS - tk_UDPpack pack; - pack.data = buffer; - pack.len = size; - pack.ip.host = address; - pack.ip.port = port; - tk_udp_recvfrom(&handle.udpHandle, &pack); - return pack.len; - #endif - } - - void Socket::close() - { - if (type == SocketType::TCP) - { - #if JIN_NET_TEKCOS - tk_tcp_close(&handle.tcpHandle); - #endif - } - else if (type == SocketType::UDP) - { - #if JIN_NET_TEKCOS - tk_udp_close(&handle.udpHandle); - #endif - } - } - -} -}
\ No newline at end of file diff --git a/src/libjin/Net/Socket.h b/src/libjin/Net/Socket.h deleted file mode 100644 index 6d9e09b..0000000 --- a/src/libjin/Net/Socket.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __JIN_NET_SOCKET_H -#define __JIN_NET_SOCKET_H -#include "../modules.h" -#if JIN_MODULES_NET - -#include "../3rdparty/tekcos/tekcos.h" - -namespace jin -{ -namespace net -{ - - enum SocketType - { - TCP, - UDP - }; - - struct SocketInformation - { - unsigned int address; - unsigned short port; - SocketType type; - }; - - class Socket - { - public: - Socket() {}; - Socket(const Socket& socket); - Socket(const SocketInformation& socketInformation); - Socket(SocketType type, unsigned short port); - Socket(SocketType type, unsigned int address, unsigned short port); - Socket(SocketType type, const char* address, unsigned short port); - ~Socket(); - - void configureBlocking(bool bocking); - Socket* accept(); - int receive(char* buffer, int size); - int send(char* buffer, int size); - void sendTo(char* buffer, int size, unsigned int address, unsigned int port); - int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port); - void close(); - - protected: - #if JIN_NET_TEKCOS - Socket(const tk_TCPsocket& tcpHandle); - Socket(const tk_UDPsocket& udpHandle); - union - { - tk_TCPsocket tcpHandle; - tk_UDPsocket udpHandle; - } handle; - #endif - SocketType type; - }; - -} // net -} // jin - -#endif // JIN_MODULES_NET -#endif // __JIN_NET_SOCKET_H
\ No newline at end of file diff --git a/src/libjin/Net/je_net_manager.cpp b/src/libjin/Net/je_net_manager.cpp new file mode 100644 index 0000000..c4f822e --- /dev/null +++ b/src/libjin/Net/je_net_manager.cpp @@ -0,0 +1,24 @@ +#include "je_net_manager.h" + +namespace JinEngine +{ + namespace Net + { + + bool NetManager::initSystem(const SettingBase* setting) + { + #ifdef _WIN32 + #if jin_net == jin_net_tekcos + tk_init(); + #endif + #endif + return true; + } + + void NetManager::quitSystem() + { + + } + + } // namespace Net +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Net/je_net_manager.h b/src/libjin/Net/je_net_manager.h new file mode 100644 index 0000000..8f72b73 --- /dev/null +++ b/src/libjin/Net/je_net_manager.h @@ -0,0 +1,50 @@ +#ifndef __JE_NET_H +#define __JE_NET_H +#include "../core/je_configuration.h" +#if defined(jin_net) + +#include "../common/je_subsystem.hpp" + +#include "je_socket.h" + +namespace JinEngine +{ + namespace Net + { + + /// + /// + /// + class NetManager : public Subsystem<NetManager> + { + protected: + singleton(NetManager); + + /// + /// + /// + NetManager() {}; + + /// + /// + /// + ~NetManager() {}; + + /// + /// + /// + bool initSystem(const SettingBase* setting) override; + + /// + /// + /// + void quitSystem() override; + + }; + + } // namespace Net +} // namespace JinEngine + +#endif // defined(jin_net) + +#endif // __JE_NET_H
\ No newline at end of file diff --git a/src/libjin/Net/je_socket.cpp b/src/libjin/Net/je_socket.cpp new file mode 100644 index 0000000..1810601 --- /dev/null +++ b/src/libjin/Net/je_socket.cpp @@ -0,0 +1,190 @@ +#include "je_socket.h" + +namespace JinEngine +{ + namespace Net + { + Socket::Socket(const Socket& socket) + : mHandle(socket.mHandle) + , mType(socket.mType) + { + } + + Socket::Socket(const SocketInformation& info) + : mType(info.type) + { + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = info.address; + ip.port = info.port; + mHandle.tcpHandle = tk_tcp_open(ip); + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(info.port); + } + } + + Socket::Socket(SocketType type, const char* address, unsigned short port) + { + mType = type; + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + #if jin_net == jin_net_tekcos + ip.host = tk_strtohl(address); + ip.port = port; + mHandle.tcpHandle = tk_tcp_open(ip); + #endif + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(port); + } + } + + Socket::Socket(SocketType type, unsigned int address, unsigned short port) + { + mType = type; + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = address; + ip.port = port; + mHandle.tcpHandle = tk_tcp_open(ip); + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(port); + } + } + + Socket::Socket(SocketType type, unsigned short port) + { + mType = type; + if (mType == SocketType::TCP) + { + tk_IPaddress ip; + ip.host = 0; + ip.port = port; + mHandle.tcpHandle = tk_tcp_open(ip); + } + else if (mType == SocketType::UDP) + { + mHandle.udpHandle = tk_udp_open(port); + } + } + + #if jin_net == jin_net_tekcos + + Socket::Socket(const tk_TCPsocket& tcphandle) + { + mHandle.tcpHandle = tcphandle; + } + + Socket::Socket(const tk_UDPsocket& udphandle) + { + mHandle.udpHandle = udphandle; + } + + #endif // jin_net == jin_net_tekcos + + Socket::~Socket() + { + } + + void Socket::configureBlocking(bool blocking) + { + if (mType != SocketType::TCP) + return; + #if jin_net == jin_net_tekcos + if (blocking) + tk_tcp_blocking(&mHandle.tcpHandle); + else + tk_tcp_nonblocking(&mHandle.tcpHandle); + #endif + } + + Socket* Socket::accept() + { + if (mType != SocketType::TCP) + return nullptr; + Socket* client; + #if jin_net == jin_net_tekcos + tk_TCPsocket socket = tk_tcp_accept(&mHandle.tcpHandle); + client = new Socket(socket); + #endif + return client; + } + + int Socket::receive(char* buffer, int size) + { + if (mType != SocketType::TCP) + return 0; + #if jin_net == jin_net_tekcos + int len; + tk_tcp_recv(&mHandle.tcpHandle, buffer, size, &len); + return len; + #endif + } + + int Socket::send(char* buffer, int size) + { + if (mType != SocketType::TCP) + return 0; + #if jin_net == jin_net_tekcos + int len; + tk_tcp_send(&mHandle.tcpHandle, buffer, size, &len); + return len; + #endif + } + + void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port) + { + if (mType != SocketType::UDP) + return; + #if jin_net == jin_net_tekcos + tk_UDPpack pack; + pack.data = buffer; + pack.len = size; + pack.ip.host = address; + pack.ip.port = port; + tk_udp_sendto(&mHandle.udpHandle, &pack); + #endif + } + + int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port) + { + if (mType != SocketType::UDP) + return 0; + int len; + #if jin_net == jin_net_tekcos + tk_UDPpack pack; + pack.data = buffer; + pack.len = size; + pack.ip.host = address; + pack.ip.port = port; + tk_udp_recvfrom(&mHandle.udpHandle, &pack); + return pack.len; + #endif + } + + void Socket::close() + { + if (mType == SocketType::TCP) + { + #if jin_net == jin_net_tekcos + tk_tcp_close(&mHandle.tcpHandle); + #endif + } + else if (mType == SocketType::UDP) + { + #if jin_net == jin_net_tekcos + tk_udp_close(&mHandle.udpHandle); + #endif + } + } + + } // namespace Net +} // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/Net/je_socket.h b/src/libjin/Net/je_socket.h new file mode 100644 index 0000000..d496fcb --- /dev/null +++ b/src/libjin/Net/je_socket.h @@ -0,0 +1,144 @@ +#ifndef __JE_NET_SOCKET_H +#define __JE_NET_SOCKET_H +#include "../core/je_configuration.h" +#if defined(jin_net) + +#include "../3rdparty/tekcos/tekcos.h" + +namespace JinEngine +{ + namespace Net + { + + /// + /// + /// + enum SocketType + { + TCP, + UDP + }; + + /// + /// + /// + struct SocketInformation + { + unsigned int address; + unsigned short port; + SocketType type; + }; + + /// + /// + /// + class Socket + { + public: + + /// + /// + /// + Socket() {}; + + /// + /// + /// + Socket(const Socket& socket); + + /// + /// + /// + Socket(const SocketInformation& socketInformation); + + /// + /// + /// + Socket(SocketType type, unsigned short port); + + /// + /// + /// + Socket(SocketType type, unsigned int address, unsigned short port); + + /// + /// + /// + Socket(SocketType type, const char* address, unsigned short port); + + /// + /// + /// + ~Socket(); + + /// + /// + /// + void configureBlocking(bool bocking); + + /// + /// + /// + Socket* accept(); + + /// + /// + /// + int receive(char* buffer, int size); + + /// + /// + /// + int send(char* buffer, int size); + + /// + /// + /// + void sendTo(char* buffer, int size, unsigned int address, unsigned int port); + + /// + /// + /// + int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port); + + /// + /// + /// + void close(); + + protected: + #if jin_net == jin_net_tekcos + + /// + /// + /// + Socket(const tk_TCPsocket& tcpHandle); + + /// + /// + /// + Socket(const tk_UDPsocket& udpHandle); + + /// + /// + /// + union + { + tk_TCPsocket tcpHandle; + tk_UDPsocket udpHandle; + } mHandle; + #endif + + /// + /// + /// + SocketType mType; + + }; + + } // namespace Net +} // namespace JinEngine + +#endif // defined(jin_net) + +#endif // __JE_NET_SOCKET_H
\ No newline at end of file diff --git a/src/libjin/Net/net.cpp b/src/libjin/Net/net.cpp deleted file mode 100644 index db39be7..0000000 --- a/src/libjin/Net/net.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "Net.h" - -namespace jin -{ -namespace net -{ - - bool Net::initSystem(const SettingBase* setting) - { - #ifdef _WIN32 - #if JIN_NET_TEKCOS - tk_init(); - #endif - #endif - return true; - } - - void Net::quitSystem() - { - - } - -} -} diff --git a/src/libjin/Net/net.h b/src/libjin/Net/net.h deleted file mode 100644 index 54ffede..0000000 --- a/src/libjin/Net/net.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __JIN_NET_H -#define __JIN_NET_H -#include "../modules.h" -#if JIN_MODULES_NET - -#include "../Common/Subsystem.hpp" -#include "Socket.h" - -namespace jin -{ -namespace net -{ - - class Net : public Subsystem<Net> - { - public: - - protected: - Net() {}; - ~Net() {}; - SINGLETON(Net); - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - }; - -} -} - -#endif // JIN_MODULES_NET -#endif // __JIN_NET_H
\ No newline at end of file diff --git a/src/libjin/Physics/Physics.h b/src/libjin/Physics/Physics.h deleted file mode 100644 index 126911e..0000000 --- a/src/libjin/Physics/Physics.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __JIN_PHYSICS_H -#define __JIN_PHYSICS_H - -namespace jin -{ -namespace physics -{ - #include "../3rdparty/Box2D/Box2D.h" -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/Thread/Thread.cpp b/src/libjin/Thread/Thread.cpp deleted file mode 100644 index 13e691a..0000000 --- a/src/libjin/Thread/Thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_THREAD - -#include "Thread.h" - -namespace jin -{ -namespace thread -{ - - class Mutex - { - public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - private: - #if JIN_THREAD_SDL - SDL_mutex* mutex; - #endif - friend class Conditional; - }; - - // ̼߳signal wait - class Conditional - { - public: - Conditional(); - ~Conditional(); - void signal(); - void broadcast(); - bool wait(Mutex* mutex, int timeout = -1); - private: - #if JIN_THREAD_SDL - SDL_cond* cond; - #endif - }; - - class Lock - { - public: - Lock(Mutex* m) : mutex(m) { - mutex->lock(); - } - - Lock(Mutex& m) : mutex(&m) { - mutex->lock(); - } - - ~Lock() { - mutex->unlock(); - } - private: - Mutex* mutex; - - Lock(Lock&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - Mutex::Mutex() - { - #if JIN_THREAD_SDL - mutex = SDL_CreateMutex(); - #endif - } - - Mutex::~Mutex() - { - #if JIN_THREAD_SDL - SDL_DestroyMutex(mutex); - #endif - } - - void Mutex::lock() - { - #if JIN_THREAD_SDL - SDL_LockMutex(mutex); - #endif - } - - void Mutex::unlock() - { - #if JIN_THREAD_SDL - SDL_UnlockMutex(mutex); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Conditional::Conditional() - { - #if JIN_THREAD_SDL - cond = SDL_CreateCond(); - #endif - } - - Conditional::~Conditional() - { - #if JIN_THREAD_SDL - SDL_DestroyCond(cond); - #endif - } - - void Conditional::signal() - { - #if JIN_THREAD_SDL - SDL_CondSignal(cond); - #endif - } - - void Conditional::broadcast() - { - #if JIN_THREAD_SDL - SDL_CondBroadcast(cond); - #endif - } - - bool Conditional::wait(Mutex* mutex, int timeout) - { - #if JIN_THREAD_SDL - if (timeout < 0) - return !SDL_CondWait(cond, mutex->mutex); - else - return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) - : mutex(m) - , condition(c) - , share() - { - } - - Thread::ThreadData::~ThreadData() - { - } - - void Thread::ThreadData::set(int slot, Variant value) - { - Lock l(mutex); - share[slot] = value; - } - - Thread::Variant Thread::ThreadData::get(int slot) - { - Lock l(mutex); - return share[slot]; - } - - bool Thread::ThreadData::exist(int slot) - { - Lock l(mutex); - return share.count(slot) == 1; - } - - void Thread::ThreadData::remove(int slot) - { - Lock l(mutex); - if (exist(slot)) - { - share.erase(slot); - } - } - - ////////////////////////////////////////////////////////////////////// - - Thread::Thread(const std::string tname, ThreadRunner runner) - : name(tname) - , running(false) - , threadRunner(runner) - { - mutex = new Mutex(); - condition = new Conditional(); - common = new Thread::ThreadData(mutex, condition); - } - - Thread::~Thread() - { - #if JIN_THREAD_SDL - #endif - } - - const char* Thread::getName() - { - Lock l(mutex); - return name.c_str(); - }; - - bool Thread::isRunning() - { - Lock l(mutex); - return running; - }; - - bool Thread::start(void* p) - { - Lock l(mutex); - if (running) - return false; - if (handle) - { - #if JIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - } - #if JIN_THREAD_SDL - handle = SDL_CreateThread(threadRunner, name.c_str(), p); - #elif JIN_THREAD_CPP - handle = new std::thread(); - #endif - return (running = (handle != nullptr)); - } - - void Thread::wait() - { - { - Lock l(mutex); - if (!handle) - return; - } - #if JIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - Lock l(mutex); - running = false; - handle = nullptr; - } - - void Thread::lock() - { - if (mutex != nullptr) - mutex->lock(); - } - - void Thread::unlock() - { - if (mutex != nullptr) - mutex->unlock(); - } - - void Thread::send(int slot, const Variant& value) - { - lock(); - common->set(slot, value); - unlock(); - condition->broadcast(); - } - - bool Thread::receive(int slot) - { - return common->exist(slot); - } - - Thread::Variant Thread::fetch(int slot) - { - Thread::Variant v = common->get(slot); - return v; - } - - Thread::Variant Thread::demand(int slot) - { - /** - * pthread_mutex_lock(mtx); - * while(pass == 0) - * { - * pthread_mutex_unlock(mtx); - * pthread_cond_just_wait(cv); - * pthread_mutex_lock(mtx); - * } - * pthread_mutex_unlock(mtx); - */ - lock(); - while (!common->exist(slot)) - { - if (common->exist(ThreadData::SLOT_ERROR)) - return 0; - condition->wait(mutex); - } - Thread::Variant v = common->get(slot); - unlock(); - return v; - } - - void Thread::remove(int slot) - { - lock(); - common->remove(slot); - unlock(); - } - -} // thread -} // jin - -#endif // JIN_MODULES_THREAD
\ No newline at end of file diff --git a/src/libjin/Thread/Thread.h b/src/libjin/Thread/Thread.h deleted file mode 100644 index 046c8f6..0000000 --- a/src/libjin/Thread/Thread.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef __JIN_THREAD_H -#define __JIN_THREAD_H -#include "../modules.h" -#if JIN_MODULES_THREAD - -#include <string> -#include <map> -#if JIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif JIN_THREAD_CPP -# include <thread> -# include <mutex> -# include <condition_variable> -#endif - -namespace jin -{ -namespace thread -{ - /** - * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ - * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ - * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz - * һӦûҪ˻ƵԴУꡢСжϴڶеĴ - * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ - * ߣָѣ - */ - class Mutex; - class Conditional; - - /** - * Thread::demand Receive a message from a thread. Wait for the message to exist before returning. - * Thread::getName Get the name of a thread. - * Thread::kill Forcefully terminate the thread. - * Thread::peek Receive a message from a thread, but leave it in the message box. - * Thread::receive Receive a message from a thread. - * Thread::send Send a message. - * Thread::set Set a value. - * Thread::start Starts the thread. - * Thread::wait Wait for a thread to finish. - */ - class Thread - { - public: - struct Variant - { - enum Type - { - NONE = 0, - INTERGER, - BOOLEAN, - CHARACTER, - CSTRING, - POINTER, - REAL, - }; - Type type; - union - { - int integer; - bool boolean; - char character; - const char* cstring; - void* pointer; - float real; - }; - Variant() :type(NONE) {}; - Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } - Variant(int i) : integer(i), type(INTERGER) {}; - Variant(float f) : real(f), type(REAL) {}; - Variant(bool b) : boolean(b), type(BOOLEAN) {}; - Variant(char c) : character(c), type(CHARACTER) {}; - Variant(const char* s) : cstring(s), type(CSTRING) {}; - Variant(void* p) : pointer(p), type(POINTER) {}; - }; - - private: - class ThreadData - { - public: - ThreadData(Mutex*, Conditional*); - ~ThreadData(); - bool exist(int slot); - void set(int slot, Variant value); - Variant get(int slot); - void remove(int slot); - Conditional* condition; - Mutex* mutex; - - static const int SLOT_ERROR = -1; - static const int SLOT_WARN = -2; - static const int SLOT_INFO = -3; - static const int SLOT_DEBUG = -4; - - private: - std::map<int, Variant> share; // threads shared value - }; - - public: - typedef int(*ThreadRunner)(void* obj); - Thread(const std::string name, ThreadRunner threadfuncs); - ~Thread(); - bool start(void* p); - void wait(); - void send(int slot, const Variant& value); - bool receive(int slot); - Variant fetch(int slot); - Variant demand(int slot); - void remove(int slot); - const char* getName(); - bool isRunning(); - void lock(); - void unlock(); - - protected: - #if JIN_THREAD_SDL - SDL_Thread* handle; // SDL thread - #elif JIN_THREAD_CPP - std::thread* handle; // cpp thread - #endif - Mutex* mutex; // mutex variable - Conditional* condition; // condition variable - ThreadRunner threadRunner; // thread function - ThreadData* common; // threads common data - const std::string name; // thread name, for debugging purposes - /** - * https://stackoverflow.com/questions/149932/naming-conventions-for-threads - * - * Use short names because they don't make the lines in a log file too long. - * - * Create names where the important part is at the beginning. Log viewers in a - * graphical user interface tend to have tables with columns, and the thread - * column is usually small or will be made small by you to read everything else. - * - * Do not use the word "thread" in the thread name because it is obvious. - * - * Make the thread names easily grep-able. Avoid similar sounding thread names - * - * If you have several threads of the same nature, enumerate them with IDs that - * are unique to one execution of the application or one log file, whichever fits - * your logging habits. - * - * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker - * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or - * "Calculation" (what does it calculate?). - * - * If you have a test group that uses thread names to grep your application's log - * files, do not rename your threads after some time. Your testers will hate you for - * doing so. Thread names in well-tested applications should be there to stay. - * - * When you have threads that service a network connection, try to include the target - * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about - * enumeration though if there are multiple connections to the same host. - */ - bool running; // running - - }; - -} // thread -} // jin - -#endif // JIN_MODULES_THREAD -#endif // __JIN_THREAD_H
\ No newline at end of file diff --git a/src/libjin/Thread/thread.cpp b/src/libjin/Thread/thread.cpp deleted file mode 100644 index 13e691a..0000000 --- a/src/libjin/Thread/thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_THREAD - -#include "Thread.h" - -namespace jin -{ -namespace thread -{ - - class Mutex - { - public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - private: - #if JIN_THREAD_SDL - SDL_mutex* mutex; - #endif - friend class Conditional; - }; - - // ̼߳signal wait - class Conditional - { - public: - Conditional(); - ~Conditional(); - void signal(); - void broadcast(); - bool wait(Mutex* mutex, int timeout = -1); - private: - #if JIN_THREAD_SDL - SDL_cond* cond; - #endif - }; - - class Lock - { - public: - Lock(Mutex* m) : mutex(m) { - mutex->lock(); - } - - Lock(Mutex& m) : mutex(&m) { - mutex->lock(); - } - - ~Lock() { - mutex->unlock(); - } - private: - Mutex* mutex; - - Lock(Lock&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - Mutex::Mutex() - { - #if JIN_THREAD_SDL - mutex = SDL_CreateMutex(); - #endif - } - - Mutex::~Mutex() - { - #if JIN_THREAD_SDL - SDL_DestroyMutex(mutex); - #endif - } - - void Mutex::lock() - { - #if JIN_THREAD_SDL - SDL_LockMutex(mutex); - #endif - } - - void Mutex::unlock() - { - #if JIN_THREAD_SDL - SDL_UnlockMutex(mutex); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Conditional::Conditional() - { - #if JIN_THREAD_SDL - cond = SDL_CreateCond(); - #endif - } - - Conditional::~Conditional() - { - #if JIN_THREAD_SDL - SDL_DestroyCond(cond); - #endif - } - - void Conditional::signal() - { - #if JIN_THREAD_SDL - SDL_CondSignal(cond); - #endif - } - - void Conditional::broadcast() - { - #if JIN_THREAD_SDL - SDL_CondBroadcast(cond); - #endif - } - - bool Conditional::wait(Mutex* mutex, int timeout) - { - #if JIN_THREAD_SDL - if (timeout < 0) - return !SDL_CondWait(cond, mutex->mutex); - else - return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) - : mutex(m) - , condition(c) - , share() - { - } - - Thread::ThreadData::~ThreadData() - { - } - - void Thread::ThreadData::set(int slot, Variant value) - { - Lock l(mutex); - share[slot] = value; - } - - Thread::Variant Thread::ThreadData::get(int slot) - { - Lock l(mutex); - return share[slot]; - } - - bool Thread::ThreadData::exist(int slot) - { - Lock l(mutex); - return share.count(slot) == 1; - } - - void Thread::ThreadData::remove(int slot) - { - Lock l(mutex); - if (exist(slot)) - { - share.erase(slot); - } - } - - ////////////////////////////////////////////////////////////////////// - - Thread::Thread(const std::string tname, ThreadRunner runner) - : name(tname) - , running(false) - , threadRunner(runner) - { - mutex = new Mutex(); - condition = new Conditional(); - common = new Thread::ThreadData(mutex, condition); - } - - Thread::~Thread() - { - #if JIN_THREAD_SDL - #endif - } - - const char* Thread::getName() - { - Lock l(mutex); - return name.c_str(); - }; - - bool Thread::isRunning() - { - Lock l(mutex); - return running; - }; - - bool Thread::start(void* p) - { - Lock l(mutex); - if (running) - return false; - if (handle) - { - #if JIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - } - #if JIN_THREAD_SDL - handle = SDL_CreateThread(threadRunner, name.c_str(), p); - #elif JIN_THREAD_CPP - handle = new std::thread(); - #endif - return (running = (handle != nullptr)); - } - - void Thread::wait() - { - { - Lock l(mutex); - if (!handle) - return; - } - #if JIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - Lock l(mutex); - running = false; - handle = nullptr; - } - - void Thread::lock() - { - if (mutex != nullptr) - mutex->lock(); - } - - void Thread::unlock() - { - if (mutex != nullptr) - mutex->unlock(); - } - - void Thread::send(int slot, const Variant& value) - { - lock(); - common->set(slot, value); - unlock(); - condition->broadcast(); - } - - bool Thread::receive(int slot) - { - return common->exist(slot); - } - - Thread::Variant Thread::fetch(int slot) - { - Thread::Variant v = common->get(slot); - return v; - } - - Thread::Variant Thread::demand(int slot) - { - /** - * pthread_mutex_lock(mtx); - * while(pass == 0) - * { - * pthread_mutex_unlock(mtx); - * pthread_cond_just_wait(cv); - * pthread_mutex_lock(mtx); - * } - * pthread_mutex_unlock(mtx); - */ - lock(); - while (!common->exist(slot)) - { - if (common->exist(ThreadData::SLOT_ERROR)) - return 0; - condition->wait(mutex); - } - Thread::Variant v = common->get(slot); - unlock(); - return v; - } - - void Thread::remove(int slot) - { - lock(); - common->remove(slot); - unlock(); - } - -} // thread -} // jin - -#endif // JIN_MODULES_THREAD
\ No newline at end of file diff --git a/src/libjin/Thread/thread.h b/src/libjin/Thread/thread.h deleted file mode 100644 index 046c8f6..0000000 --- a/src/libjin/Thread/thread.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef __JIN_THREAD_H -#define __JIN_THREAD_H -#include "../modules.h" -#if JIN_MODULES_THREAD - -#include <string> -#include <map> -#if JIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif JIN_THREAD_CPP -# include <thread> -# include <mutex> -# include <condition_variable> -#endif - -namespace jin -{ -namespace thread -{ - /** - * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ - * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ - * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz - * һӦûҪ˻ƵԴУꡢСжϴڶеĴ - * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ - * ߣָѣ - */ - class Mutex; - class Conditional; - - /** - * Thread::demand Receive a message from a thread. Wait for the message to exist before returning. - * Thread::getName Get the name of a thread. - * Thread::kill Forcefully terminate the thread. - * Thread::peek Receive a message from a thread, but leave it in the message box. - * Thread::receive Receive a message from a thread. - * Thread::send Send a message. - * Thread::set Set a value. - * Thread::start Starts the thread. - * Thread::wait Wait for a thread to finish. - */ - class Thread - { - public: - struct Variant - { - enum Type - { - NONE = 0, - INTERGER, - BOOLEAN, - CHARACTER, - CSTRING, - POINTER, - REAL, - }; - Type type; - union - { - int integer; - bool boolean; - char character; - const char* cstring; - void* pointer; - float real; - }; - Variant() :type(NONE) {}; - Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } - Variant(int i) : integer(i), type(INTERGER) {}; - Variant(float f) : real(f), type(REAL) {}; - Variant(bool b) : boolean(b), type(BOOLEAN) {}; - Variant(char c) : character(c), type(CHARACTER) {}; - Variant(const char* s) : cstring(s), type(CSTRING) {}; - Variant(void* p) : pointer(p), type(POINTER) {}; - }; - - private: - class ThreadData - { - public: - ThreadData(Mutex*, Conditional*); - ~ThreadData(); - bool exist(int slot); - void set(int slot, Variant value); - Variant get(int slot); - void remove(int slot); - Conditional* condition; - Mutex* mutex; - - static const int SLOT_ERROR = -1; - static const int SLOT_WARN = -2; - static const int SLOT_INFO = -3; - static const int SLOT_DEBUG = -4; - - private: - std::map<int, Variant> share; // threads shared value - }; - - public: - typedef int(*ThreadRunner)(void* obj); - Thread(const std::string name, ThreadRunner threadfuncs); - ~Thread(); - bool start(void* p); - void wait(); - void send(int slot, const Variant& value); - bool receive(int slot); - Variant fetch(int slot); - Variant demand(int slot); - void remove(int slot); - const char* getName(); - bool isRunning(); - void lock(); - void unlock(); - - protected: - #if JIN_THREAD_SDL - SDL_Thread* handle; // SDL thread - #elif JIN_THREAD_CPP - std::thread* handle; // cpp thread - #endif - Mutex* mutex; // mutex variable - Conditional* condition; // condition variable - ThreadRunner threadRunner; // thread function - ThreadData* common; // threads common data - const std::string name; // thread name, for debugging purposes - /** - * https://stackoverflow.com/questions/149932/naming-conventions-for-threads - * - * Use short names because they don't make the lines in a log file too long. - * - * Create names where the important part is at the beginning. Log viewers in a - * graphical user interface tend to have tables with columns, and the thread - * column is usually small or will be made small by you to read everything else. - * - * Do not use the word "thread" in the thread name because it is obvious. - * - * Make the thread names easily grep-able. Avoid similar sounding thread names - * - * If you have several threads of the same nature, enumerate them with IDs that - * are unique to one execution of the application or one log file, whichever fits - * your logging habits. - * - * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker - * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or - * "Calculation" (what does it calculate?). - * - * If you have a test group that uses thread names to grep your application's log - * files, do not rename your threads after some time. Your testers will hate you for - * doing so. Thread names in well-tested applications should be there to stay. - * - * When you have threads that service a network connection, try to include the target - * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about - * enumeration though if there are multiple connections to the same host. - */ - bool running; // running - - }; - -} // thread -} // jin - -#endif // JIN_MODULES_THREAD -#endif // __JIN_THREAD_H
\ No newline at end of file diff --git a/src/libjin/Tilemap/Tilemap.h b/src/libjin/Tilemap/Tilemap.h deleted file mode 100644 index a2bce62..0000000 --- a/src/libjin/Tilemap/Tilemap.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JIN_TILEMAP_H -#define __JIN_TILEMAP_H -#include "../modules.h" -#if JIN_MODULES_TILEMAP - -namespace jin -{ -namespace tilemap -{ - - - -}// tilemap -}// jin - -#endif // JIN_MODULES_TILEMAP -#endif // __JIN_TILEMAP_H
\ No newline at end of file diff --git a/src/libjin/Time/Timer.cpp b/src/libjin/Time/Timer.cpp deleted file mode 100644 index cfdb4bd..0000000 --- a/src/libjin/Time/Timer.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_TIME - -#include "Timer.h" - -namespace jin -{ -namespace time -{ - - - Timers::Timers() - : timers() - { - } - - Timers::~Timers() - { - for (int i = 0; i < timers.size(); ++i) - delete timers[i]; - } - - void Timers::update(int ms) - { - std::vector<Timer*>::iterator it = timers.begin(); - for (; it != timers.end(); ) - { - if (!(*it)->process(ms)) - { - Timer* t = *it; - timers.erase(it); - delete t; - return; - } - ++it; - } - } - - void Timers::every(int ms, timer_callback callback, void* p) - { - Timer* t = new Timer(Timer::EVERY, ms, 0, callback, p); - timers.push_back(t); - } - - void Timers::after(int ms, timer_callback callback, void* p) - { - Timer* t = new Timer(Timer::AFTER, ms, 0, callback, p); - timers.push_back(t); - } - - void Timers::repeat(int ms, int count, timer_callback callback, void* p) - { - Timer* t = new Timer(Timer::REPEAT, ms, count, callback, p); - timers.push_back(t); - } - - Timers::Timer::Timer(Type t, int d, int c, timer_callback f, void* p) - : type(t) - , duration(d) - , count(c) - , tickdown(d) - , countdown(c) - , callback(f) - , paramters(p) - { - } - - Timers::Timer::~Timer() - { - } - - bool Timers::Timer::process(int ms) - { - tickdown -= ms; - if (tickdown <= 0) - { - tickdown = duration; - if (callback != nullptr) - callback(paramters); - if (type == EVERY) - { - } - else if (type == AFTER) - { - return false; - } - else if (type == REPEAT) - { - --countdown; - if (countdown <= 0) - return false; - } - } - return true; - } - -} -} - -#endif // JIN_MODULES_TIME
\ No newline at end of file diff --git a/src/libjin/Time/Timer.h b/src/libjin/Time/Timer.h deleted file mode 100644 index 173cd95..0000000 --- a/src/libjin/Time/Timer.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef __JIN_TIMER_H -#define __JIN_TIMER_H -#include "../modules.h" -#if JIN_MODULES_TIME - -#include "SDL2/SDL.h" -#include <vector> - -namespace jin -{ -namespace time -{ - - class Timers - { - public: - typedef void(*timer_callback)(void* prameters); - - Timers(); - ~Timers(); - - void update(int ms); - - void every(int ms, timer_callback callback, void* paramters); - void after(int ms, timer_callback callback, void* paramters); - void repeat(int ms, int count, timer_callback callback, void* paramters); - - private: - class Timer - { - public: - enum Type - { - EVERY, - AFTER, - REPEAT, - }; - Timer(Type type, int duration, int count = 0, timer_callback callback = nullptr, void* paramters = nullptr); - virtual ~Timer(); - bool process(int ms); - private: - int duration; - int count; - int tickdown; - int countdown; - Type type; - timer_callback callback; - void* paramters; - }; - std::vector<Timer*> timers; - }; - - inline void sleep(int ms) - { - #if JIN_TIME_SDL - SDL_Delay(ms); - #endif - } - - inline double getSecond() - { - #if JIN_TIME_SDL - return SDL_GetTicks() / 1000.f; - #endif - } - - inline double getMilliSecond() - { - #if JIN_TIME_SDL - return SDL_GetTicks(); - #endif - } - -} // time -} // jin - -#endif // JIN_MODULES_TIME -#endif // __JIN_TIMER_H
\ No newline at end of file diff --git a/src/libjin/Time/je_timer.cpp b/src/libjin/Time/je_timer.cpp new file mode 100644 index 0000000..a2f2486 --- /dev/null +++ b/src/libjin/Time/je_timer.cpp @@ -0,0 +1,100 @@ +#include "../core/je_configuration.h" +#if defined(jin_time) + +#include "je_timer.h" + +namespace JinEngine +{ + namespace Time + { + + + Timers::Timers() + : timers() + { + } + + Timers::~Timers() + { + for (int i = 0; i < timers.size(); ++i) + delete timers[i]; + } + + void Timers::update(int ms) + { + std::vector<Timer*>::iterator it = timers.begin(); + for (; it != timers.end(); ) + { + if (!(*it)->process(ms)) + { + Timer* t = *it; + timers.erase(it); + delete t; + return; + } + ++it; + } + } + + void Timers::every(int ms, timer_callback callback, void* p) + { + Timer* t = new Timer(Timer::EVERY, ms, 0, callback, p); + timers.push_back(t); + } + + void Timers::after(int ms, timer_callback callback, void* p) + { + Timer* t = new Timer(Timer::AFTER, ms, 0, callback, p); + timers.push_back(t); + } + + void Timers::repeat(int ms, int count, timer_callback callback, void* p) + { + Timer* t = new Timer(Timer::REPEAT, ms, count, callback, p); + timers.push_back(t); + } + + Timers::Timer::Timer(Type t, int d, int c, timer_callback f, void* p) + : type(t) + , duration(d) + , count(c) + , tickdown(d) + , countdown(c) + , callback(f) + , paramters(p) + { + } + + Timers::Timer::~Timer() + { + } + + bool Timers::Timer::process(int ms) + { + tickdown -= ms; + if (tickdown <= 0) + { + tickdown = duration; + if (callback != nullptr) + callback(paramters); + if (type == EVERY) + { + } + else if (type == AFTER) + { + return false; + } + else if (type == REPEAT) + { + --countdown; + if (countdown <= 0) + return false; + } + } + return true; + } + + } // namespace Time +} // namespace JinEngine + +#endif // defined(jin_time) diff --git a/src/libjin/Time/je_timer.h b/src/libjin/Time/je_timer.h new file mode 100644 index 0000000..b6b4b9e --- /dev/null +++ b/src/libjin/Time/je_timer.h @@ -0,0 +1,117 @@ +#ifndef __JE_TIMER_H +#define __JE_TIMER_H +#include "../core/je_configuration.h" +#if defined(jin_time) + +#include <vector> +#include "SDL2/SDL.h" + +namespace JinEngine +{ + namespace Time + { + + /// + /// + /// + class Timers + { + public: + typedef void(*timer_callback)(void* prameters); + + /// + /// + /// + Timers(); + + /// + /// + /// + ~Timers(); + + /// + /// + /// + void update(int ms); + + /// + /// + /// + void every(int ms, timer_callback callback, void* paramters); + + /// + /// + /// + void after(int ms, timer_callback callback, void* paramters); + + /// + /// + /// + void repeat(int ms, int count, timer_callback callback, void* paramters); + + private: + + /// + /// + /// + class Timer + { + public: + enum Type + { + EVERY, + AFTER, + REPEAT, + }; + Timer(Type type, int duration, int count = 0, timer_callback callback = nullptr, void* paramters = nullptr); + virtual ~Timer(); + bool process(int ms); + private: + int duration; + int count; + int tickdown; + int countdown; + Type type; + timer_callback callback; + void* paramters; + }; + std::vector<Timer*> timers; + + }; + + /// + /// + /// + inline void sleep(int ms) + { + #if jin_time == jin_time_sdl + SDL_Delay(ms); + #endif + } + + /// + /// + /// + inline double getSecond() + { + #if jin_time == jin_time_sdl + return SDL_GetTicks() / 1000.f; + #endif + } + + /// + /// + /// + inline double getMilliSecond() + { + #if jin_time == jin_time_sdl + return SDL_GetTicks(); + #endif + } + + } // namespace Time +} // namespace JinEngine + +#endif // defined(jin_time) + +#endif // __JE_TIMER_H
\ No newline at end of file diff --git a/src/libjin/Utils/CSV/CSV.h b/src/libjin/Utils/CSV/CSV.h deleted file mode 100644 index 6f70f09..0000000 --- a/src/libjin/Utils/CSV/CSV.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/src/libjin/Utils/Component/Component.h b/src/libjin/Utils/Component/Component.h deleted file mode 100644 index f63fb59..0000000 --- a/src/libjin/Utils/Component/Component.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __JIN_TOOLS_COMPONENT_H -#define __JIN_TOOLS_COMPONENT_H -#include "../../modules.h" -#if JIN_MODULES_TOOLS && JIN_TOOLS_COMPONENT - -namespace jin -{ -namespace utils -{ - - class GameObject; - - class Component - { - public: - Component(GameObject* obj) - : gameObject(obj) - {} - - virtual void update(float dt) = 0; - - private: - GameObject* gameObject; - }; - -} // tools -} // jin - -#endif // JIN_MODULES_TOOLS && JIN_TOOLS_COMPONENT -#endif // __JIN_TOOLS_COMPONENT_H
\ No newline at end of file diff --git a/src/libjin/Utils/Component/GameObject.h b/src/libjin/Utils/Component/GameObject.h deleted file mode 100644 index e4f3aa5..0000000 --- a/src/libjin/Utils/Component/GameObject.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __JIN_TOOLS_GAMEOBJECT_H -#define __JIN_TOOLS_GAMEOBJECT_H -#include "../../modules.h" -#if JIN_MODULES_TOOLS && JIN_TOOLS_COMPONENT - -#include <vector> -#include "Component.h" - -namespace jin -{ -namespace utils -{ - - class GameObject - { - public: - - GameObject() - : components() - { - } - - virtual void update(float dt) - { - for each (Component* component in components) - component->update(dt); - } - - virtual void draw() = 0; - - protected: - - std::vector<Component*> components; - }; - -} // tools -} // jin - -#endif // JIN_MODULES_TOOLS && JIN_TOOLS_COMPONENT -#endif // __JIN_TOOLS_GAMEOBJECT_H
\ No newline at end of file diff --git a/src/libjin/Utils/EventMsgCenter/EventMsgCenter.h b/src/libjin/Utils/EventMsgCenter/EventMsgCenter.h deleted file mode 100644 index 6717b83..0000000 --- a/src/libjin/Utils/EventMsgCenter/EventMsgCenter.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __JIN_TOOLS_EVENTMSGCENTER_H -#define __JIN_TOOLS_EVENTMSGCENTER_H -#include "../../modules.h" -#if JIN_MODULES_TOOLS && JIN_TOOLS_EVENTMSGCENTER - -namespace jin -{ -namespace utils -{ - - class EventMSGCenter - { - - }; - -} // tools -} // jin - -#endif // JIN_MODULES_TOOLS && JIN_TOOLS_EVENTMSGCENTER -#endif // __JIN_TOOLS_EVENTMSGCENTER_H
\ No newline at end of file diff --git a/src/libjin/Utils/EventMsgCenter/Events.h b/src/libjin/Utils/EventMsgCenter/Events.h deleted file mode 100644 index 9ebc30d..0000000 --- a/src/libjin/Utils/EventMsgCenter/Events.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __JIN_TOOLS_EVENTS_H -#define __JIN_TOOLS_EVENTS_H -#include "../../modules.h" -#if JIN_MODULES_TOOLS && JIN_TOOLS_EVENTMSGCENTER - -namespace jin -{ -namespace utils -{ - - enum Event - { - - }; - -} // tools -} // jin - -#endif // JIN_MODULES_TOOLS && JIN_TOOLS_EVENTMSGCENTER -#endif // __JIN_TOOLS_EVENTS_H
\ No newline at end of file diff --git a/src/libjin/Utils/Json/Json.h b/src/libjin/Utils/Json/Json.h deleted file mode 100644 index 6f70f09..0000000 --- a/src/libjin/Utils/Json/Json.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/src/libjin/Utils/Log.h b/src/libjin/Utils/Log.h deleted file mode 100644 index e4ed879..0000000 --- a/src/libjin/Utils/Log.h +++ /dev/null @@ -1,134 +0,0 @@ -/** -* Single.h/loghelper.h -* Copyright (C) 2017~2018 chai -*/ -#ifndef __LOG_HELPER_H -#define __LOG_HELPER_H -#include <string> -#include <iostream> -#include <fstream> -#include <stdarg.h> - -class Loghelper -{ -public: - // logĿ - enum Direction - { - DIR_CERR = 1 << 1, // - DIR_FILE = 1 << 2, // logļ - }; - - // ȼ - enum Level - { - LV_NONE = 0, // none - LV_ERROR = 1 << 1, // error - LV_WARN = 1 << 2, // warn - LV_INFO = 1 << 3, // info - LV_DEBUG = 1 << 4, // debug - LV_ALL = 0xffffffff - }; - - static void log(Level _level, const char* _fmt, ...); - - // ض - static void redirect(unsigned int _dir, char* _path = nullptr); - - // ɸѡȼ - static void restrict(unsigned int levels); - - static void close(); - -private: - static unsigned int dir; // Ŀ - static unsigned int levels; // ȼ - static std::ofstream fs; // ļ -}; - -typedef Loghelper::Level Loglevel; - -#ifdef LOGHELPER_IMPLEMENT - -#define hasbit(flag, bit) ((flag & bit) == bit) - -unsigned int Loghelper::dir = Loghelper::Direction::DIR_CERR; -unsigned int Loghelper::levels = Loghelper::Level::LV_ALL; -std::ofstream Loghelper::fs; - -void Loghelper::log(Level _level, const char* _fmt, ...) -{ - if (!hasbit(levels, _level)) - return; -#define FORMAT_MSG_BUFFER_SIZE (204800) - const char* levelStr = nullptr; - switch (_level) - { - case LV_ERROR: - levelStr = "[Jin Error]:"; - break; - case LV_WARN: - levelStr = "[Jin Warn]:"; - break; - case LV_INFO: - levelStr = "[Jin Info]:"; - break; - case LV_DEBUG: - levelStr = "[Jin Debug]:"; - break; - default: - levelStr = "[Jin Unknown]:"; - break; - } - char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; - strcpy(buffer, levelStr); - va_list args; - va_start(args, _fmt); - vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); - va_end(args); - if (hasbit(dir, DIR_CERR)) - { - std::cerr << buffer << std::endl; - } - if (hasbit(dir, DIR_FILE)) - { - fs << buffer << std::endl; - } -#undef FORMAT_MSG_BUFFER_SIZE -} - -// ض -void Loghelper::redirect(unsigned int _dir, char* _path) -{ - dir = _dir; - if (hasbit(dir, DIR_FILE)) - { - try - { - fs.open(_path, std::ios_base::app); - } - catch (std::ios_base::failure& e) { - dir = DIR_CERR; - log(Level::LV_WARN, "ضlog· %s ʧ", _path); - } - } -} - -// ɸѡȼ -void Loghelper::restrict(unsigned int _levels) -{ - levels = _levels; -} - -void Loghelper::close() -{ - if (!fs.fail()) - fs.close(); - fs.clear(); -} - -#undef hasbit - -#endif - -#endif diff --git a/src/libjin/Utils/Proxy/lock.h b/src/libjin/Utils/Proxy/lock.h deleted file mode 100644 index 29194a1..0000000 --- a/src/libjin/Utils/Proxy/lock.h +++ /dev/null @@ -1,4 +0,0 @@ -class Lock -{ - -};
\ No newline at end of file diff --git a/src/libjin/Utils/XML/XML.h b/src/libjin/Utils/XML/XML.h deleted file mode 100644 index 6f70f09..0000000 --- a/src/libjin/Utils/XML/XML.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/src/libjin/Utils/endian.h b/src/libjin/Utils/je_endian.h index d4c441a..db8c8fd 100644 --- a/src/libjin/Utils/endian.h +++ b/src/libjin/Utils/je_endian.h @@ -1,23 +1,23 @@ -#ifndef JIN_LIL_ENDIAN && JIN_BIG_ENDIAN +#ifndef jin_endian_lil && jin_endian_big -#define JIN_LIL_ENDIAN 2 -#define JIN_BIG_ENDIAN 4 +#define jin_endian_lil 2 +#define jin_endian_big 4 #endif -#ifndef JIN_BYTEORDER +#ifndef jin_byte_order #ifdef __linux__ #include <endian.h> -#define JIN_BYTEORDER __BYTE_ORDER +#define jin_byte_order __BYTE_ORDER #else /* __linux__ */ #if defined(__hppa__) || \ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ (defined(__MIPS__) && defined(__MISPEB__)) || \ defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ defined(__sparc__) -#define JIN_BYTEORDER JIN_BIG_ENDIAN +#define jin_byte_order jin_endian_big #else -#define JIN_BYTEORDER JIN_LIL_ENDIAN +#define jin_byte_order jin_endian_lil #endif #endif /* __linux__ */ #endif /* !SDL_BYTEORDER */
\ No newline at end of file diff --git a/src/libjin/Utils/Log.cpp b/src/libjin/Utils/je_log.cpp index 5299942..2bcb25a 100644 --- a/src/libjin/Utils/Log.cpp +++ b/src/libjin/Utils/je_log.cpp @@ -1,2 +1,2 @@ #define LOGHELPER_IMPLEMENT -#include "log.h"
\ No newline at end of file +#include "je_log.h"
\ No newline at end of file diff --git a/src/libjin/Utils/log.h b/src/libjin/Utils/je_log.h index e4ed879..928a009 100644 --- a/src/libjin/Utils/log.h +++ b/src/libjin/Utils/je_log.h @@ -1,9 +1,6 @@ -/** -* Single.h/loghelper.h -* Copyright (C) 2017~2018 chai -*/ #ifndef __LOG_HELPER_H #define __LOG_HELPER_H + #include <string> #include <iostream> #include <fstream> @@ -131,4 +128,4 @@ void Loghelper::close() #endif -#endif +#endif
\ No newline at end of file diff --git a/src/libjin/Utils/je_macros.h b/src/libjin/Utils/je_macros.h new file mode 100644 index 0000000..475a482 --- /dev/null +++ b/src/libjin/Utils/je_macros.h @@ -0,0 +1,17 @@ +#ifndef __JE_MACROS_H +#define __JE_MACROS_H +#include <cstring> + +//#define implement // ʵֽӿ +// +//#define shared // ķ +// +//#define MASK // enum +// +//#define onlyonce // ֻһ +//#define CALLONCE(call) static char __dummy__=(call, 1) // ֻһ +//#define SAFECALL(func, params) if(func) func(params) +// +//#define zero(mem) memset(&mem, 0, sizeof(mem)) + +#endif
\ No newline at end of file diff --git a/src/libjin/utils/unittest.cpp b/src/libjin/Utils/je_unittest.cpp index 44f1ae5..294351b 100644 --- a/src/libjin/utils/unittest.cpp +++ b/src/libjin/Utils/je_unittest.cpp @@ -1,4 +1,4 @@ -#include "utils.h" +#include "je_utils.h" #if UNITTEST #include <iostream> @@ -7,7 +7,7 @@ #include "../audio/sdl/source.h" #include "../audio/sdl/audio.h" -using namespace jin::audio; +using namespace JinEngine::audio; using namespace std; int main(int argc, char* argv[]) diff --git a/src/libjin/Utils/je_utils.h b/src/libjin/Utils/je_utils.h new file mode 100644 index 0000000..21c507d --- /dev/null +++ b/src/libjin/Utils/je_utils.h @@ -0,0 +1,9 @@ +#ifndef __JE_UTILS_H +#define __JE_UTILS_H + +#include "je_macros.h" +#include "je_endian.h" + +#define UNITTEST 0 + +#endif
\ No newline at end of file diff --git a/src/libjin/Utils/macros.h b/src/libjin/Utils/macros.h deleted file mode 100644 index a57cb7c..0000000 --- a/src/libjin/Utils/macros.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JIN_MACROS_H -#define __JIN_MACROS_H -#include <cstring> - -#define implement // ʵֽӿ - -#define shared // ķ - -#define MASK // enum - -#define onlyonce // ֻһ -#define CALLONCE(call) static char __dummy__=(call, 1) // ֻһ -#define SAFECALL(func, params) if(func) func(params) - -#define zero(mem) memset(&mem, 0, sizeof(mem)) - -#endif
\ No newline at end of file diff --git a/src/libjin/Utils/unittest.cpp b/src/libjin/Utils/unittest.cpp deleted file mode 100644 index 44f1ae5..0000000 --- a/src/libjin/Utils/unittest.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "utils.h" -#if UNITTEST - -#include <iostream> -#include <stdio.h> -#include <fstream> -#include "../audio/sdl/source.h" -#include "../audio/sdl/audio.h" - -using namespace jin::audio; -using namespace std; - -int main(int argc, char* argv[]) -{ - SDLAudio* audio = SDLAudio::get(); - audio->init(0); - SDLSource* source = SDLSource::createSource("a.ogg"); - SDLSource* source2 = SDLSource::createSource("a.wav"); - //source->play(); - source2->play(); - source->setLoop(true); - source2->setLoop(true); - int i = 0; - while (true) - { - SDL_Delay(1000); - } - audio->quit(); - return 0; -} - -/* -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "SDL2/SDL.h" - -#include <3rdparty/cmixer/cmixer.h> - -static SDL_mutex* audio_mutex; - -static void lock_handler(cm_Event *e) { - if (e->type == CM_EVENT_LOCK) { - SDL_LockMutex(audio_mutex); - } - if (e->type == CM_EVENT_UNLOCK) { - SDL_UnlockMutex(audio_mutex); - } -} - - -static void audio_callback(void *udata, Uint8 *stream, int size) { - cm_process((cm_Int16*)stream, size / 2); -} - - -int main(int argc, char **argv) { - SDL_AudioDeviceID dev; - SDL_AudioSpec fmt, got; - cm_Source *src; - cm_Source* src2; - - - SDL_Init(SDL_INIT_AUDIO); - audio_mutex = SDL_CreateMutex(); - - memset(&fmt, 0, sizeof(fmt)); - fmt.freq = 44100; - fmt.format = AUDIO_S16; - fmt.channels = 2; - fmt.samples = 1024; - fmt.callback = audio_callback; - - dev = SDL_OpenAudioDevice(NULL, 0, &fmt, &got, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); - if (dev == 0) { - fprintf(stderr, "Error: failed to open audio device '%s'\n", SDL_GetError()); - exit(EXIT_FAILURE); - } - - cm_init(got.freq); - cm_set_lock(lock_handler); - cm_set_master_gain(0.5); - - SDL_PauseAudioDevice(dev, 0); - - src = cm_new_source_from_file("a.ogg"); - src2 = cm_new_source_from_file("loop.wav"); - if (!src) { - fprintf(stderr, "Error: failed to create source '%s'\n", cm_get_error()); - exit(EXIT_FAILURE); - } - cm_set_loop(src2, 1); - - cm_play(src); - cm_play(src2); - - printf("Press [return] to exit\n"); - getchar(); - - cm_destroy_source(src); - SDL_CloseAudioDevice(dev); - SDL_Quit(); - - return EXIT_SUCCESS; -} -*/ - -#endif
\ No newline at end of file diff --git a/src/libjin/Utils/utils.h b/src/libjin/Utils/utils.h deleted file mode 100644 index cf0920e..0000000 --- a/src/libjin/Utils/utils.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __JIN_UTILS_H -#define __JIN_UTILS_H - -#include "macros.h" -#include "endian.h" - -#define UNITTEST 0 - -#endif
\ No newline at end of file diff --git a/src/libjin/input/joypad.cpp b/src/libjin/ai/je_behavior_tree.cpp index e69de29..e69de29 100644 --- a/src/libjin/input/joypad.cpp +++ b/src/libjin/ai/je_behavior_tree.cpp diff --git a/src/libjin/ai/je_behavior_tree.h b/src/libjin/ai/je_behavior_tree.h new file mode 100644 index 0000000..6e276b6 --- /dev/null +++ b/src/libjin/ai/je_behavior_tree.h @@ -0,0 +1,25 @@ +#ifndef __JE_BEHAVIOR_TREE_H +#define __JE_BEHAVIOR_TREE_H + +#include "../core/je_configuration.h" +#if defined(jin_ai) + +namespace JinEngine +{ + namespace AI + { + + /// + /// + /// + class BehaviorTree + { + + }; + + } +} + +#endif // jin_ai + +#endif
\ No newline at end of file diff --git a/src/libjin/input/keyboard.cpp b/src/libjin/ai/je_state_machine.cpp index e69de29..e69de29 100644 --- a/src/libjin/input/keyboard.cpp +++ b/src/libjin/ai/je_state_machine.cpp diff --git a/src/libjin/ai/je_state_machine.h b/src/libjin/ai/je_state_machine.h new file mode 100644 index 0000000..7869925 --- /dev/null +++ b/src/libjin/ai/je_state_machine.h @@ -0,0 +1,25 @@ +#ifndef __JE_STATEMACHINE_TREE_H +#define __JE_STATEMACHINE_TREE_H + +#include "../core/je_configuration.h" +#if defined(jin_ai) + +namespace JinEngine +{ + namespace AI + { + + /// + /// + /// + class StateMachine + { + + }; + + } +} + +#endif // jin_ai + +#endif
\ No newline at end of file diff --git a/src/libjin/audio/audio.cpp b/src/libjin/audio/audio.cpp deleted file mode 100644 index 5fb10da..0000000 --- a/src/libjin/audio/audio.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include "SDL2/SDL.h" -#include "audio.h" - -namespace jin -{ -namespace audio -{ - -} -} - -#endif // JIN_MODULES_AUDIO
\ No newline at end of file diff --git a/src/libjin/audio/audio.h b/src/libjin/audio/audio.h deleted file mode 100644 index 6c3468e..0000000 --- a/src/libjin/audio/audio.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __JIN_AUDIO_H -#define __JIN_AUDIO_H -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -#include "../utils/macros.h" -#include "../common/Subsystem.hpp" - -namespace jin -{ -namespace audio -{ - class Source; - - template<class SubAudio> - class Audio : public Subsystem<SubAudio> - { - - public: - - enum State - { - PLAY , - STOP , - PAUSE, - }; - - virtual void play() = 0; - virtual void stop() = 0; - virtual void pause() = 0; - virtual void resume() = 0; - virtual void setVolume(float volume) = 0; - - protected: - - Audio() - : volume(1) - , state(State::PLAY) - {}; - virtual ~Audio() {}; - SINGLETON(Audio); - - float volume; - State state; - }; - -} -} - -#endif // JIN_MODULES_AUDIO -#endif // __JIN_AUDIO_H
\ No newline at end of file diff --git a/src/libjin/audio/source.cpp b/src/libjin/audio/source.cpp deleted file mode 100644 index 61f4055..0000000 --- a/src/libjin/audio/source.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include <cstring> -#include "source.h" - -namespace jin -{ -namespace audio -{ - - static int check_header(const void *data, int size, const char *str, int offset) { - int len = strlen(str); - return (size >= offset + len) && !memcmp((char*)data + offset, str, len); - } - - SourceType Source::getType(const void* mem, int size) - { - if(check_header(mem, size, "WAVE", 8)) - return SourceType::WAV; - if(check_header(mem, size, "OggS", 0)) - return SourceType::OGG; - return SourceType::INVALID; - } - -} -} -#endif // JIN_MODULES_AUDIO
\ No newline at end of file diff --git a/src/libjin/audio/source.h b/src/libjin/audio/source.h deleted file mode 100644 index 3abe7de..0000000 --- a/src/libjin/audio/source.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __JIN_AUDIO_SOURCE_H -#define __JIN_AUDIO_SOURCE_H -#include "../modules.h" -#if JIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -namespace jin -{ -namespace audio -{ - - enum SourceType - { - INVALID = 0, - WAV, - OGG, - }; - - class Source - { - - public: - - Source() {}; - virtual ~Source() {}; - - /* interface */ - virtual void play() = 0; - virtual void stop() = 0; - virtual void pause() = 0; - virtual void resume() = 0; - virtual void rewind() = 0; - virtual bool isStopped() const = 0; - virtual bool isPaused() const = 0; - virtual void setPitch(float pitch) = 0; - virtual void setVolume(float volume) = 0; - virtual bool setLoop(bool loop) = 0; - virtual void setRate(float rate) = 0; - - protected: - - static SourceType getType(const void* mem, int size); - - }; - -} -} - -#endif // JIN_MODULES_AUDIO -#endif // __JIN_AUDIO_SOURCE_H
\ No newline at end of file diff --git a/src/libjin/common/data.h b/src/libjin/common/data.h deleted file mode 100644 index 4b0f1ba..0000000 --- a/src/libjin/common/data.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __JIN_COMMON_DATA_H -#define __JIN_COMMON_DATA_H - - - -namespace jin -{ - - class DataBuffer - { - public: - DataBuffer(int n) - : len(n) - { - buffer = new char[len]; - memset(buffer, 0, len); - } - ~DataBuffer() - { - delete[] buffer; - } - char* operator&() - { - return buffer; - } - - private: - char* buffer; - int len; - }; - -} // jin - -#endif
\ No newline at end of file diff --git a/src/libjin/core/core.h b/src/libjin/core/core.h deleted file mode 100644 index dd902b4..0000000 --- a/src/libjin/core/core.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __JIN_CORE_H -#define __JIN_CORE_H - -#include "game.h" - -#endif
\ No newline at end of file diff --git a/src/libjin/core/game.cpp b/src/libjin/core/game.cpp deleted file mode 100644 index b480b12..0000000 --- a/src/libjin/core/game.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "game.h" -#include "../Time/Timer.h" -#include "../input/Event.h" -#include "../Graphics/Window.h" -#include "../Math/Math.h" -#include <iostream> - -namespace jin -{ -namespace core -{ - - using namespace jin::graphics; - using namespace jin::input; - using namespace jin::time; - using namespace jin::math; - - Game::Game() :_running(true) {}; - - void Game::run() - { - SAFECALL(_onLoad); - Window* wnd = Window::get(); - const int FPS = wnd ? wnd->getFPS() : 60; - const int MS_PER_UPDATE = 1000.0f / FPS; - _running = true; - Event e; - int previous = getMilliSecond(); - int dt = MS_PER_UPDATE; - while (_running) - { - while (jin::input::pollEvent(&e)) - { - SAFECALL(_onEvent, &e); - if (!_running) goto quitloop; - } - SAFECALL(_onUpdate, dt); - SAFECALL(_onDraw); - wnd->swapBuffers(); - const int current = getMilliSecond(); - dt = current - previous; - const int wait = MS_PER_UPDATE - (current - previous); - previous += MS_PER_UPDATE; - if (wait > 0) - { - sleep(wait); - dt = MS_PER_UPDATE; - } - else - previous = current; - } - quitloop:; - } - - bool Game::initSystem(const SettingBase* setting) - { - if (setting == nullptr) - return false; - Game::Setting* s = (Game::Setting*) setting; - _onEvent = s->eventHandler; - _onUpdate = s->updater; - _onDraw = s->drawer; - _onLoad = s->loader; - return true; - } - - void Game::quitSystem() - { - } - -} // core -} // jin
\ No newline at end of file diff --git a/src/libjin/core/game.h b/src/libjin/core/game.h deleted file mode 100644 index 31f32d8..0000000 --- a/src/libjin/core/game.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __JIN_CORE_GAME_H -#define __JIN_CORE_GAME_H - -#include "SDL2/SDL.h" - -#include "../Common/Subsystem.hpp" -#include "../utils/macros.h" -#include "../Input/Event.h" - -namespace jin -{ -namespace core -{ - - class Game : public Subsystem<Game> - { - public: - - typedef void(*onLoad)(); - typedef void(*onEvent)(jin::input::Event* e); - typedef void(*onUpdate)(int dt); - typedef void(*onDraw)(); - - struct Setting : SettingBase - { - onEvent eventHandler; - onUpdate updater; - onDraw drawer; - onLoad loader; - }; - - void run(); - inline void stop() { _running = false; }; - inline bool running() { return _running; }; - - private: - - Game(); - ~Game() {}; - - SINGLETON(Game); - - onEvent _onEvent; - onUpdate _onUpdate; - onDraw _onDraw; - onLoad _onLoad; - - bool _running; - - bool initSystem(const SettingBase* setting); - void quitSystem(); - - }; - -} // core -} // jin - -#endif // __JIN_CORE_GAME_H
\ No newline at end of file diff --git a/src/libjin/debug/debug.h b/src/libjin/debug/debug.h deleted file mode 100644 index 9fa9fe1..0000000 --- a/src/libjin/debug/debug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __JIN_DEBUG_H -#define __JIN_DEBUG_H - - - -#endif
\ No newline at end of file diff --git a/src/libjin/debug/log.h b/src/libjin/debug/log.h deleted file mode 100644 index e1624f5..0000000 --- a/src/libjin/debug/log.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __JIN_LOG_H -#define __JIN_LOG_H - -namespace jin -{ -namespace debug -{ - - const char* err; - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/input/event.cpp b/src/libjin/input/event.cpp deleted file mode 100644 index 8eb45e6..0000000 --- a/src/libjin/input/event.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "event.h" -#include "SDL2\SDL.h" - -namespace jin -{ - -}
\ No newline at end of file diff --git a/src/libjin/input/event.h b/src/libjin/input/event.h deleted file mode 100644 index 9feb3a5..0000000 --- a/src/libjin/input/event.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef __JIN_EVENT_H -#define __JIN_EVENT_H -#include "../modules.h" -#if JIN_MODULES_INPUT - -namespace jin -{ -namespace input -{ -#if JIN_INPUT_SDL -#include "SDL.h" - - typedef SDL_Event Event; - typedef SDL_Keycode Key; - typedef SDL_MouseWheelEvent Wheel; - - enum EventType { - QUIT = SDL_QUIT, - KEY_DOWN = SDL_KEYDOWN, - KEY_UP = SDL_KEYUP, - MOUSE_MOTION = SDL_MOUSEMOTION, - MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, - MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, - MOUSE_WHEEL = SDL_MOUSEWHEEL, - WINDOW_EVENT = SDL_WINDOWEVENT, - }; - - enum WindowEvent { - WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , - WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , - WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , - WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , - WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , - WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , - WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , - WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , - WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , - WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , - WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , - WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, - WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , - WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , - WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , - WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , - }; - - inline int pollEvent(Event* e) - { - return SDL_PollEvent(e); - } - - inline const char* getKeyName(Key key) - { - return SDL_GetKeyName(key); - } - - inline const char* getButtonName(int button) - { - switch (button) - { - case 1: return "left"; - case 2: return "middle"; - case 3: return "right"; - case 4: return "wheelup"; - case 5: return "wheeldown"; - default: return "?"; - } - } - -/* - inline const char* getWheelName(Wheel wheel) - { - if (wheel.x == -1) - return "left"; - else if (wheel.x == 1) - return "right"; - else if (wheel.y == -1) - return "near"; - else if (wheel.y == 1) - return "far"; - else - return "none"; - } -*/ - -#endif // JIN_INPUT_SDL -} // input -} // jin - -#endif // JIN_MODULES_INPUT -#endif
\ No newline at end of file diff --git a/src/libjin/input/input.h b/src/libjin/input/input.h deleted file mode 100644 index 217edd2..0000000 --- a/src/libjin/input/input.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __JIN_INPUT_H -#define __JIN_INPUT_H - -#include "event.h" -#include "keyboard.h" -#include "mouse.h" - -#endif
\ No newline at end of file diff --git a/src/libjin/input/joypad.h b/src/libjin/input/joypad.h deleted file mode 100644 index e8d309b..0000000 --- a/src/libjin/input/joypad.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __JIN_JOYPAD_H -#define __JIN_JOYPAD_H - -namespace jin -{ -namespace input -{ - - - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/input/keyboard.h b/src/libjin/input/keyboard.h deleted file mode 100644 index 3e78ab1..0000000 --- a/src/libjin/input/keyboard.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __JIN_KEYBOARD_H -#define __JIN_KEYBOARD_H - -namespace jin -{ -namespace input -{ - class Keyboard - { - - }; -} -} - -#endif // __JIN_KEYBOARD_H
\ No newline at end of file diff --git a/src/libjin/input/mouse.cpp b/src/libjin/input/mouse.cpp deleted file mode 100644 index 98c4a39..0000000 --- a/src/libjin/input/mouse.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../modules.h" -#ifdef JIN_MODULES_INPUT - -#include "SDL.h" -#include "Mouse.h" - -namespace jin -{ -namespace input -{ - - void Mouse::getState(int* x, int* y) - { -#ifdef JIN_INPUT_SDL - SDL_GetMouseState(x, y); -#endif // JIN_INPUT_SDL - } - -} // input -} // jin - -#endif // JIN_MODULES_INPUT
\ No newline at end of file diff --git a/src/libjin/input/mouse.h b/src/libjin/input/mouse.h deleted file mode 100644 index 5fc6b47..0000000 --- a/src/libjin/input/mouse.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __JIN_MOUSE_H -#define __JIN_MOUSE_H -#include "../modules.h" -#ifdef JIN_MODULES_INPUT - -#include "../Common/Singleton.hpp" - -namespace jin -{ -namespace input -{ - class Mouse : public Singleton<Mouse> - { - public: - - // - void getState(int* x, int* y); - - private: - Mouse() {}; - ~Mouse() {}; - - SINGLETON(Mouse); - }; -} -} - -#endif // JIN_MODULES_INPUT -#endif // __JIN_MOUSE_H
\ No newline at end of file diff --git a/src/libjin/jin.h b/src/libjin/jin.h index c8d1193..b47a56d 100644 --- a/src/libjin/jin.h +++ b/src/libjin/jin.h @@ -1,24 +1,20 @@ -#ifndef __JIN_H -#define __JIN_H +#ifndef __JE_H +#define __JE_H -#include "modules.h" +#include "core/je_configuration.h" -#include "Utils/utils.h" -#ifdef JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO -#include "Audio/SDL/SDLAudio.h" -#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO -#include "Physics/Physics.h" -#include "Core/Core.h" -#include "Filesystem/Filesystem.h" -#include "Input/Input.h" -#include "Net/Net.h" -#include "Graphics/Graphics.h" -#include "Time/Timer.h" -#include "Thread/Thread.h" +#include "utils/je_utils.h" +#if jin_audio == jin_audio_sdl + #include "audio/sdl/je_sdl_audio.h" +#endif +#include "game/je_game.h" +#include "filesystem/je_asset_database.h" +#include "filesystem/je_buffer.h" +#include "input/je_input.h" +#include "net/je_net_manager.h" +#include "graphics/je_graphics.h" +#include "time/je_timer.h" +#include "multithread/je_thread.h" +#include "common/je_common.h" -#define JIN_VERSION "Jin 0.1"; -#define JIN_AUTHOR "Chai"; -#define JIN_RELEASE "Jin 0.1.1"; -#define JIN_VERSION_NUM 101; - -#endif // __JIN_H
\ No newline at end of file +#endif // __JE_H
\ No newline at end of file diff --git a/src/libjin/math/constant.h b/src/libjin/math/constant.h deleted file mode 100644 index f2f740f..0000000 --- a/src/libjin/math/constant.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __JIN_MATH_CONSTANT_H -#define __JIN_MATH_CONSTANT_H - -#define PI 3.1415926f - -// int16 Χ -#define INT16_RANGE_LEFT -32768 -#define INT16_RANGE_RIGHT 32767 - -#endif
\ No newline at end of file diff --git a/src/libjin/math/math.h b/src/libjin/math/math.h deleted file mode 100644 index 2bc8ed9..0000000 --- a/src/libjin/math/math.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __JIN_UTILS_MATH_H -#define __JIN_UTILS_MATH_H - -#include "constant.h" -#include "matrix.h" -#include "quad.h" - -namespace jin -{ -namespace math -{ - -#ifdef min -# undef min -#endif // min -#ifdef max -# undef max -#endif // max - - template<typename T> - inline T min(T a, T b) - { - return a < b ? a : b; - } - - template<typename T> - inline T max(T a, T b) - { - return a > b ? a : b; - } - - template<typename T> - inline T clamp(T a, T mi, T ma) - { - return min<T>(max<T>(a, mi), ma); - } - - template<typename T> - inline bool within(T a, T mi, T ma) - { - return a >= mi && a <= ma; - } - - template<typename T> - inline bool without(T a, T mi, T ma) - { - return a < mi || a > ma; - } - - template<typename T> - inline T abs(T a) - { - return a > 0 ? a : -a; - } - - template<typename T> - inline T lowerBound(T a, T lower) - { - return a < lower ? lower : a; - } - - template<typename T> - inline T upperBound(T a, T upper) - { - return a > upper ? upper : a; - } - - template<typename T> - inline T lerp(T a, T b, float t) - { - return a + t * (b - a); - } - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/math/matrix.cpp b/src/libjin/math/matrix.cpp deleted file mode 100644 index 97e9178..0000000 --- a/src/libjin/math/matrix.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "Matrix.h" - -#include <cstring> // memcpy -#include <cmath> - -namespace jin -{ -namespace math -{ - - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - Matrix::Matrix() - { - setIdentity(); - } - - Matrix::~Matrix() - { - } - - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - Matrix Matrix::operator * (const Matrix & m) const - { - Matrix t; - - t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]); - t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]); - t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]); - t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]); - - t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]); - t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]); - t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]); - t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]); - - t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]); - t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]); - t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]); - t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]); - - t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]); - t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]); - t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]); - t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]); - - return t; - } - - void Matrix::operator *= (const Matrix & m) - { - Matrix t = (*this) * m; - memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16); - } - - const float * Matrix::getElements() const - { - return e; - } - - void Matrix::setIdentity() - { - memset(e, 0, sizeof(float) * 16); - e[0] = e[5] = e[10] = e[15] = 1; - } - - void Matrix::setTranslation(float x, float y) - { - setIdentity(); - e[12] = x; - e[13] = y; - } - - void Matrix::setRotation(float rad) - { - setIdentity(); - float c = cos(rad), s = sin(rad); - e[0] = c; e[4] = -s; - e[1] = s; e[5] = c; - } - - void Matrix::setScale(float sx, float sy) - { - setIdentity(); - e[0] = sx; - e[5] = sy; - } - - void Matrix::setShear(float kx, float ky) - { - setIdentity(); - e[1] = ky; - e[4] = kx; - } - - void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy) - { - memset(e, 0, sizeof(float) * 16); // zero out matrix - float c = cos(angle), s = sin(angle); - // matrix multiplication carried out on paper: - // |1 x| |c -s | |sx | |1 -ox| - // | 1 y| |s c | | sy | | 1 -oy| - // | 1 | | 1 | | 1 | | 1 | - // | 1| | 1| | 1| | 1 | - // move rotate scale origin - e[10] = e[15] = 1.0f; - e[0] = c * sx ; // = a - e[1] = s * sx ; // = b - e[4] = - s * sy; // = c - e[5] = c * sy; // = d - e[12] = x - ox * e[0] - oy * e[4]; - e[13] = y - ox * e[1] - oy * e[5]; - } - - void Matrix::translate(float x, float y) - { - Matrix t; - t.setTranslation(x, y); - this->operator *=(t); - } - - void Matrix::rotate(float rad) - { - Matrix t; - t.setRotation(rad); - this->operator *=(t); - } - - void Matrix::scale(float sx, float sy) - { - Matrix t; - t.setScale(sx, sy); - this->operator *=(t); - } - - void Matrix::shear(float kx, float ky) - { - Matrix t; - t.setShear(kx, ky); - this->operator *=(t); - } - - // | x | - // | y | - // | 0 | - // | 1 | - // | e0 e4 e8 e12 | - // | e1 e5 e9 e13 | - // | e2 e6 e10 e14 | - // | e3 e7 e11 e15 | - - void Matrix::transform(vertex * dst, const vertex * src, int size) const - { - for (int i = 0; i<size; ++i) - { - // Store in temp variables in case src = dst - float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]); - float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]); - - dst[i].x = x; - dst[i].y = y; - } - } - -} -}
\ No newline at end of file diff --git a/src/libjin/math/matrix.h b/src/libjin/math/matrix.h deleted file mode 100644 index ff4a51a..0000000 --- a/src/libjin/math/matrix.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __JIN_MATRIX_H -#define __JIN_MATRIX_H - -namespace jin -{ -namespace math -{ - - struct vertex - { - unsigned char r, g, b, a; - float x, y; - float s, t; - }; - /** - * This class is the basis for all transformations in LOVE. Althought not - * really needed for 2D, it contains 4x4 elements to be compatible with - * OpenGL without conversions. - **/ - class Matrix - { - private: - - /** - * | e0 e4 e8 e12 | - * | e1 e5 e9 e13 | - * | e2 e6 e10 e14 | - * | e3 e7 e11 e15 | - **/ - float e[16]; - - public: - - /** - * Creates a new identity matrix. - **/ - Matrix(); - - /** - * Destructor. - **/ - ~Matrix(); - - /** - * Multiplies this Matrix with another Matrix, changing neither. - * @param m The Matrix to multiply with this Matrix. - * @return The combined matrix. - **/ - Matrix operator * (const Matrix & m) const; - - /** - * Multiplies a Matrix into this Matrix. - * @param m The Matrix to combine into this Matrix. - **/ - void operator *= (const Matrix & m); - - /** - * Gets a pointer to the 16 array elements. - * @return The array elements. - **/ - const float * getElements() const; - - /** - * Resets this Matrix to the identity matrix. - **/ - void setIdentity(); - - /** - * Resets this Matrix to a translation. - * @param x Translation along x-axis. - * @param y Translation along y-axis. - **/ - void setTranslation(float x, float y); - - /** - * Resets this Matrix to a rotation. - * @param r The angle in radians. - **/ - void setRotation(float r); - - /** - * Resets this Matrix to a scale transformation. - * @param sx Scale factor along the x-axis. - * @param sy Scale factor along the y-axis. - **/ - void setScale(float sx, float sy); - - /** - * Resets this Matrix to a shear transformation. - * @param kx Shear along x-axis. - * @param ky Shear along y-axis. - **/ - void setShear(float kx, float ky); - - /** - * Creates a transformation with a certain position, orientation, scale - * and offset. Perfect for Drawables -- what a coincidence! - * - * @param x The translation along the x-axis. - * @param y The translation along the y-axis. - * @param angle The rotation (rad) around the center with offset (ox,oy). - * @param sx Scale along x-axis. - * @param sy Scale along y-axis. - * @param ox The offset for rotation along the x-axis. - * @param oy The offset for rotation along the y-axis. - * @param kx Shear along x-axis - * @param ky Shear along y-axis - **/ - void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); - - /** - * Multiplies this Matrix with a translation. - * @param x Translation along x-axis. - * @param y Translation along y-axis. - **/ - void translate(float x, float y); - - /** - * Multiplies this Matrix with a rotation. - * @param r Angle in radians. - **/ - void rotate(float r); - - /** - * Multiplies this Matrix with a scale transformation. - * @param sx Scale factor along the x-axis. - * @param sy Scale factor along the y-axis. - **/ - void scale(float sx, float sy); - - /** - * Multiplies this Matrix with a shear transformation. - * @param kx Shear along the x-axis. - * @param ky Shear along the y-axis. - **/ - void shear(float kx, float ky); - - /** - * Transforms an array of vertices by this Matrix. The sources and - * destination arrays may be the same. - * - * @param dst Storage for the transformed vertices. - * @param src The source vertices. - * @param size The number of vertices. - **/ - void transform(vertex * dst, const vertex * src, int size) const; - - }; - -} -} - -#endif diff --git a/src/libjin/math/quad.h b/src/libjin/math/quad.h deleted file mode 100644 index a50cc9e..0000000 --- a/src/libjin/math/quad.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JIN_QUAD_H -#define __JIN_QUAD_H - -namespace jin -{ -namespace math -{ - - struct Quad - { - float x, y, w, h; - }; - -} -} - -#endif diff --git a/src/libjin/math/vector.cpp b/src/libjin/math/vector.cpp deleted file mode 100644 index f26d0c4..0000000 --- a/src/libjin/math/vector.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "vector.h" - diff --git a/src/libjin/math/vector.h b/src/libjin/math/vector.h deleted file mode 100644 index 43e249e..0000000 --- a/src/libjin/math/vector.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __JIN_VECTOR_H -#define __JIN_VECTOR_H - -namespace jin -{ -namespace math -{ - - - -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/modules.h b/src/libjin/modules.h deleted file mode 100644 index 5992f0c..0000000 --- a/src/libjin/modules.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __JIN_COMMON_MODULES_H -#define __JIN_COMMON_MODULES_H -/* -* ģģı룬Ҫģرղ -*/ - -#define JIN_MODULES_AUDIO 1 -#define JIN_AUDIO_SDLAUDIO 1 -#define JIN_AUDIO_OPENAL 1 - -#define JIN_MODULES_RENDER 1 - -#define JIN_MODULES_DEBUG 1 - -#define JIN_MODULES_FILESYSTEM 1 - -#define JIN_MODULES_INPUT 1 -#define JIN_INPUT_SDL 1 - -#define JIN_MODULES_MATH 1 - -#define JIN_MODULES_NET 1 -#define JIN_NET_TEKCOS 1 - -#define JIN_MODULES_PHYSICS 0 -#define JIN_PHYSICS_BOX2D 1 -#define JIN_PHYSICS_NEWTON 1 - -#define JIN_MODULES_TILEMAP 1 - -#define JIN_MODULES_UI 1 - -#define JIN_MODULES_TOOLS 0 -#define JIN_TOOLS_COMPONENT 1 -#define JIN_TOOLS_EVENTMSGCENTER 1 -#define JIN_TOOLS_XML 1 -#define JIN_TOOLS_CSV 1 -#define JIN_TOOLS_JSON 1 - -#define JIN_MODULES_THREAD 1 -#define JIN_THREAD_SDL 1 -#define JIN_THREAD_CPP 0 -#define JIN_THREAD_PTHREAD 0 - -#define JIN_MODULES_TIME 1 -#define JIN_TIME_SDL 1 - -/* -* Open libjin debug -*/ - -#define JIN_DEBUG 0 - -/* -* Operating system -*/ - -#define JIN_WINDOWS 1 -#define JIN_MACOS 2 -#define JIN_LINUX 3 - -#define JIN_OS JIN_WINDOWS - -#endif
\ No newline at end of file diff --git a/src/libjin/multithread/je_thread.cpp b/src/libjin/multithread/je_thread.cpp new file mode 100644 index 0000000..0c528bf --- /dev/null +++ b/src/libjin/multithread/je_thread.cpp @@ -0,0 +1,301 @@ +#include "../core/je_configuration.h" +#if defined(jin_thread) + +#include "je_thread.h" + +namespace JinEngine +{ + namespace MultiThread + { + + class Mutex + { + public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + private: + #if jin_thread == jin_thread_sdl + SDL_mutex* mutex; + #endif + friend class Conditional; + }; + + // ̼߳signal wait + class Conditional + { + public: + Conditional(); + ~Conditional(); + void signal(); + void broadcast(); + bool wait(Mutex* mutex, int timeout = -1); + private: + #if jin_thread == jin_thread_sdl + SDL_cond* cond; + #endif + }; + + class Lock + { + public: + Lock(Mutex* m) : mutex(m) { + mutex->lock(); + } + + Lock(Mutex& m) : mutex(&m) { + mutex->lock(); + } + + ~Lock() { + mutex->unlock(); + } + private: + Mutex* mutex; + + Lock(Lock&) {} + + }; + + ////////////////////////////////////////////////////////////////////// + + Mutex::Mutex() + { + #if jin_thread == jin_thread_sdl + mutex = SDL_CreateMutex(); + #endif + } + + Mutex::~Mutex() + { + #if jin_thread == jin_thread_sdl + SDL_DestroyMutex(mutex); + #endif + } + + void Mutex::lock() + { + #if jin_thread == jin_thread_sdl + SDL_LockMutex(mutex); + #endif + } + + void Mutex::unlock() + { + #if jin_thread == jin_thread_sdl + SDL_UnlockMutex(mutex); + #endif + } + + ////////////////////////////////////////////////////////////////////// + + Conditional::Conditional() + { + #if jin_thread == jin_thread_sdl + cond = SDL_CreateCond(); + #endif + } + + Conditional::~Conditional() + { + #if jin_thread == jin_thread_sdl + SDL_DestroyCond(cond); + #endif + } + + void Conditional::signal() + { + #if jin_thread == jin_thread_sdl + SDL_CondSignal(cond); + #endif + } + + void Conditional::broadcast() + { + #if jin_thread == jin_thread_sdl + SDL_CondBroadcast(cond); + #endif + } + + bool Conditional::wait(Mutex* mutex, int timeout) + { + #if jin_thread == jin_thread_sdl + if (timeout < 0) + return !SDL_CondWait(cond, mutex->mutex); + else + return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); + #endif + } + + ////////////////////////////////////////////////////////////////////// + + Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) + : mutex(m) + , condition(c) + , share() + { + } + + Thread::ThreadData::~ThreadData() + { + } + + void Thread::ThreadData::set(int slot, Variant value) + { + Lock l(mutex); + share[slot] = value; + } + + Thread::Variant Thread::ThreadData::get(int slot) + { + Lock l(mutex); + return share[slot]; + } + + bool Thread::ThreadData::exist(int slot) + { + Lock l(mutex); + return share.count(slot) == 1; + } + + void Thread::ThreadData::remove(int slot) + { + Lock l(mutex); + if (exist(slot)) + { + share.erase(slot); + } + } + + ////////////////////////////////////////////////////////////////////// + + Thread::Thread(const std::string tname, ThreadRunner runner) + : name(tname) + , running(false) + , threadRunner(runner) + { + mutex = new Mutex(); + condition = new Conditional(); + common = new Thread::ThreadData(mutex, condition); + } + + Thread::~Thread() + { + #if jin_thread == jin_thread_sdl + #endif + } + + const char* Thread::getName() + { + Lock l(mutex); + return name.c_str(); + }; + + bool Thread::isRunning() + { + Lock l(mutex); + return running; + }; + + bool Thread::start(void* p) + { + Lock l(mutex); + if (running) + return false; + if (handle) + { + #if jin_thread == jin_thread_sdl + SDL_WaitThread(handle, nullptr); + #endif + } + #if jin_thread == jin_thread_sdl + handle = SDL_CreateThread(threadRunner, name.c_str(), p); + #elif jin_thread == jin_thread_cpp + handle = new std::thread(); + #endif + return (running = (handle != nullptr)); + } + + void Thread::wait() + { + { + Lock l(mutex); + if (!handle) + return; + } + #if jin_thread == jin_thread_sdl + SDL_WaitThread(handle, nullptr); + #endif + Lock l(mutex); + running = false; + handle = nullptr; + } + + void Thread::lock() + { + if (mutex != nullptr) + mutex->lock(); + } + + void Thread::unlock() + { + if (mutex != nullptr) + mutex->unlock(); + } + + void Thread::send(int slot, const Variant& value) + { + lock(); + common->set(slot, value); + unlock(); + condition->broadcast(); + } + + bool Thread::receive(int slot) + { + return common->exist(slot); + } + + Thread::Variant Thread::fetch(int slot) + { + Thread::Variant v = common->get(slot); + return v; + } + + Thread::Variant Thread::demand(int slot) + { + /** + * pthread_mutex_lock(mtx); + * while(pass == 0) + * { + * pthread_mutex_unlock(mtx); + * pthread_cond_just_wait(cv); + * pthread_mutex_lock(mtx); + * } + * pthread_mutex_unlock(mtx); + */ + lock(); + while (!common->exist(slot)) + { + if (common->exist(ThreadData::SLOT_ERROR)) + return 0; + condition->wait(mutex); + } + Thread::Variant v = common->get(slot); + unlock(); + return v; + } + + void Thread::remove(int slot) + { + lock(); + common->remove(slot); + unlock(); + } + + } // namespace MultiThread +} // namespace JinEngine + +#endif // defined(jin_thread)
\ No newline at end of file diff --git a/src/libjin/multithread/je_thread.h b/src/libjin/multithread/je_thread.h new file mode 100644 index 0000000..353690c --- /dev/null +++ b/src/libjin/multithread/je_thread.h @@ -0,0 +1,167 @@ +#ifndef __JE_THREAD_H +#define __JE_THREAD_H +#include "../core/je_configuration.h" +#if defined(jin_thread) + +#include <string> +#include <map> +#if jin_thread == jin_thread_sdl + #include "SDL2/SDL_thread.h" +#elif jin_thread == jin_thread_cpp + #include <thread> + #include <mutex> + #include <condition_variable> +#endif + +namespace JinEngine +{ + namespace MultiThread + { + /** + * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ + * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ + * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz + * һӦûҪ˻ƵԴУꡢСжϴڶеĴ + * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ + * ߣָѣ + */ + class Mutex; + class Conditional; + + // + // Thread::demand Receive a message from a thread. Wait for the message to exist before returning. + // Thread::getName Get the name of a thread. + // Thread::kill Forcefully terminate the thread. + // Thread::peek Receive a message from a thread, but leave it in the message box. + // Thread::receive Receive a message from a thread. + // Thread::send Send a message. + // Thread::set Set a value. + // Thread::start Starts the thread. + // Thread::wait Wait for a thread to finish. + // + class Thread + { + public: + struct Variant + { + enum Type + { + NONE = 0, + INTERGER, + BOOLEAN, + CHARACTER, + CSTRING, + POINTER, + REAL, + }; + Type type; + union + { + int integer; + bool boolean; + char character; + const char* cstring; + void* pointer; + float real; + }; + Variant() :type(NONE) {}; + Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } + Variant(int i) : integer(i), type(INTERGER) {}; + Variant(float f) : real(f), type(REAL) {}; + Variant(bool b) : boolean(b), type(BOOLEAN) {}; + Variant(char c) : character(c), type(CHARACTER) {}; + Variant(const char* s) : cstring(s), type(CSTRING) {}; + Variant(void* p) : pointer(p), type(POINTER) {}; + }; + + private: + class ThreadData + { + public: + static const int SLOT_ERROR = -1; + static const int SLOT_WARN = -2; + static const int SLOT_INFO = -3; + static const int SLOT_DEBUG = -4; + + ThreadData(Mutex*, Conditional*); + ~ThreadData(); + bool exist(int slot); + void set(int slot, Variant value); + Variant get(int slot); + void remove(int slot); + + Conditional* condition; + Mutex* mutex; + + private: + std::map<int, Variant> share; // threads shared value + + }; + + public: + typedef int(*ThreadRunner)(void* obj); + + Thread(const std::string name, ThreadRunner threadfuncs); + ~Thread(); + bool start(void* p); + void wait(); + void send(int slot, const Variant& value); + bool receive(int slot); + Variant fetch(int slot); + Variant demand(int slot); + void remove(int slot); + const char* getName(); + bool isRunning(); + void lock(); + void unlock(); + + protected: + #if jin_thread == jin_thread_sdl + SDL_Thread* handle; // SDL thread + #elif jin_thread == jin_thread_cpp + std::thread* handle; // cpp thread + #endif + Mutex* mutex; // mutex variable + Conditional* condition; // condition variable + ThreadRunner threadRunner; // thread function + ThreadData* common; // threads common data + const std::string name; // thread name, for debugging purposes + /** + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * Use short names because they don't make the lines in a log file too long. + * + * Create names where the important part is at the beginning. Log viewers in a + * graphical user interface tend to have tables with columns, and the thread + * column is usually small or will be made small by you to read everything else. + * + * Do not use the word "thread" in the thread name because it is obvious. + * + * Make the thread names easily grep-able. Avoid similar sounding thread names + * + * If you have several threads of the same nature, enumerate them with IDs that + * are unique to one execution of the application or one log file, whichever fits + * your logging habits. + * + * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker + * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or + * "Calculation" (what does it calculate?). + * + * If you have a test group that uses thread names to grep your application's log + * files, do not rename your threads after some time. Your testers will hate you for + * doing so. Thread names in well-tested applications should be there to stay. + * + * When you have threads that service a network connection, try to include the target + * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about + * enumeration though if there are multiple connections to the same host. + */ + bool running; // running + + }; + + } // namespace MultiThread +} // namespace JinEngine + +#endif // defined(jin_thread) + +#endif // __JE_THREAD_H
\ No newline at end of file diff --git a/src/libjin/net/net.cpp b/src/libjin/net/net.cpp deleted file mode 100644 index db39be7..0000000 --- a/src/libjin/net/net.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "Net.h" - -namespace jin -{ -namespace net -{ - - bool Net::initSystem(const SettingBase* setting) - { - #ifdef _WIN32 - #if JIN_NET_TEKCOS - tk_init(); - #endif - #endif - return true; - } - - void Net::quitSystem() - { - - } - -} -} diff --git a/src/libjin/net/net.h b/src/libjin/net/net.h deleted file mode 100644 index 54ffede..0000000 --- a/src/libjin/net/net.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __JIN_NET_H -#define __JIN_NET_H -#include "../modules.h" -#if JIN_MODULES_NET - -#include "../Common/Subsystem.hpp" -#include "Socket.h" - -namespace jin -{ -namespace net -{ - - class Net : public Subsystem<Net> - { - public: - - protected: - Net() {}; - ~Net() {}; - SINGLETON(Net); - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - }; - -} -} - -#endif // JIN_MODULES_NET -#endif // __JIN_NET_H
\ No newline at end of file diff --git a/src/libjin/physics/physics.h b/src/libjin/physics/physics.h deleted file mode 100644 index 126911e..0000000 --- a/src/libjin/physics/physics.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __JIN_PHYSICS_H -#define __JIN_PHYSICS_H - -namespace jin -{ -namespace physics -{ - #include "../3rdparty/Box2D/Box2D.h" -} -} - -#endif
\ No newline at end of file diff --git a/src/libjin/thread/thread.cpp b/src/libjin/thread/thread.cpp deleted file mode 100644 index 13e691a..0000000 --- a/src/libjin/thread/thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../modules.h" -#if JIN_MODULES_THREAD - -#include "Thread.h" - -namespace jin -{ -namespace thread -{ - - class Mutex - { - public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - private: - #if JIN_THREAD_SDL - SDL_mutex* mutex; - #endif - friend class Conditional; - }; - - // ̼߳signal wait - class Conditional - { - public: - Conditional(); - ~Conditional(); - void signal(); - void broadcast(); - bool wait(Mutex* mutex, int timeout = -1); - private: - #if JIN_THREAD_SDL - SDL_cond* cond; - #endif - }; - - class Lock - { - public: - Lock(Mutex* m) : mutex(m) { - mutex->lock(); - } - - Lock(Mutex& m) : mutex(&m) { - mutex->lock(); - } - - ~Lock() { - mutex->unlock(); - } - private: - Mutex* mutex; - - Lock(Lock&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - Mutex::Mutex() - { - #if JIN_THREAD_SDL - mutex = SDL_CreateMutex(); - #endif - } - - Mutex::~Mutex() - { - #if JIN_THREAD_SDL - SDL_DestroyMutex(mutex); - #endif - } - - void Mutex::lock() - { - #if JIN_THREAD_SDL - SDL_LockMutex(mutex); - #endif - } - - void Mutex::unlock() - { - #if JIN_THREAD_SDL - SDL_UnlockMutex(mutex); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Conditional::Conditional() - { - #if JIN_THREAD_SDL - cond = SDL_CreateCond(); - #endif - } - - Conditional::~Conditional() - { - #if JIN_THREAD_SDL - SDL_DestroyCond(cond); - #endif - } - - void Conditional::signal() - { - #if JIN_THREAD_SDL - SDL_CondSignal(cond); - #endif - } - - void Conditional::broadcast() - { - #if JIN_THREAD_SDL - SDL_CondBroadcast(cond); - #endif - } - - bool Conditional::wait(Mutex* mutex, int timeout) - { - #if JIN_THREAD_SDL - if (timeout < 0) - return !SDL_CondWait(cond, mutex->mutex); - else - return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) - : mutex(m) - , condition(c) - , share() - { - } - - Thread::ThreadData::~ThreadData() - { - } - - void Thread::ThreadData::set(int slot, Variant value) - { - Lock l(mutex); - share[slot] = value; - } - - Thread::Variant Thread::ThreadData::get(int slot) - { - Lock l(mutex); - return share[slot]; - } - - bool Thread::ThreadData::exist(int slot) - { - Lock l(mutex); - return share.count(slot) == 1; - } - - void Thread::ThreadData::remove(int slot) - { - Lock l(mutex); - if (exist(slot)) - { - share.erase(slot); - } - } - - ////////////////////////////////////////////////////////////////////// - - Thread::Thread(const std::string tname, ThreadRunner runner) - : name(tname) - , running(false) - , threadRunner(runner) - { - mutex = new Mutex(); - condition = new Conditional(); - common = new Thread::ThreadData(mutex, condition); - } - - Thread::~Thread() - { - #if JIN_THREAD_SDL - #endif - } - - const char* Thread::getName() - { - Lock l(mutex); - return name.c_str(); - }; - - bool Thread::isRunning() - { - Lock l(mutex); - return running; - }; - - bool Thread::start(void* p) - { - Lock l(mutex); - if (running) - return false; - if (handle) - { - #if JIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - } - #if JIN_THREAD_SDL - handle = SDL_CreateThread(threadRunner, name.c_str(), p); - #elif JIN_THREAD_CPP - handle = new std::thread(); - #endif - return (running = (handle != nullptr)); - } - - void Thread::wait() - { - { - Lock l(mutex); - if (!handle) - return; - } - #if JIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - Lock l(mutex); - running = false; - handle = nullptr; - } - - void Thread::lock() - { - if (mutex != nullptr) - mutex->lock(); - } - - void Thread::unlock() - { - if (mutex != nullptr) - mutex->unlock(); - } - - void Thread::send(int slot, const Variant& value) - { - lock(); - common->set(slot, value); - unlock(); - condition->broadcast(); - } - - bool Thread::receive(int slot) - { - return common->exist(slot); - } - - Thread::Variant Thread::fetch(int slot) - { - Thread::Variant v = common->get(slot); - return v; - } - - Thread::Variant Thread::demand(int slot) - { - /** - * pthread_mutex_lock(mtx); - * while(pass == 0) - * { - * pthread_mutex_unlock(mtx); - * pthread_cond_just_wait(cv); - * pthread_mutex_lock(mtx); - * } - * pthread_mutex_unlock(mtx); - */ - lock(); - while (!common->exist(slot)) - { - if (common->exist(ThreadData::SLOT_ERROR)) - return 0; - condition->wait(mutex); - } - Thread::Variant v = common->get(slot); - unlock(); - return v; - } - - void Thread::remove(int slot) - { - lock(); - common->remove(slot); - unlock(); - } - -} // thread -} // jin - -#endif // JIN_MODULES_THREAD
\ No newline at end of file diff --git a/src/libjin/thread/thread.h b/src/libjin/thread/thread.h deleted file mode 100644 index 046c8f6..0000000 --- a/src/libjin/thread/thread.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef __JIN_THREAD_H -#define __JIN_THREAD_H -#include "../modules.h" -#if JIN_MODULES_THREAD - -#include <string> -#include <map> -#if JIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif JIN_THREAD_CPP -# include <thread> -# include <mutex> -# include <condition_variable> -#endif - -namespace jin -{ -namespace thread -{ - /** - * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ - * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ - * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz - * һӦûҪ˻ƵԴУꡢСжϴڶеĴ - * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ - * ߣָѣ - */ - class Mutex; - class Conditional; - - /** - * Thread::demand Receive a message from a thread. Wait for the message to exist before returning. - * Thread::getName Get the name of a thread. - * Thread::kill Forcefully terminate the thread. - * Thread::peek Receive a message from a thread, but leave it in the message box. - * Thread::receive Receive a message from a thread. - * Thread::send Send a message. - * Thread::set Set a value. - * Thread::start Starts the thread. - * Thread::wait Wait for a thread to finish. - */ - class Thread - { - public: - struct Variant - { - enum Type - { - NONE = 0, - INTERGER, - BOOLEAN, - CHARACTER, - CSTRING, - POINTER, - REAL, - }; - Type type; - union - { - int integer; - bool boolean; - char character; - const char* cstring; - void* pointer; - float real; - }; - Variant() :type(NONE) {}; - Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } - Variant(int i) : integer(i), type(INTERGER) {}; - Variant(float f) : real(f), type(REAL) {}; - Variant(bool b) : boolean(b), type(BOOLEAN) {}; - Variant(char c) : character(c), type(CHARACTER) {}; - Variant(const char* s) : cstring(s), type(CSTRING) {}; - Variant(void* p) : pointer(p), type(POINTER) {}; - }; - - private: - class ThreadData - { - public: - ThreadData(Mutex*, Conditional*); - ~ThreadData(); - bool exist(int slot); - void set(int slot, Variant value); - Variant get(int slot); - void remove(int slot); - Conditional* condition; - Mutex* mutex; - - static const int SLOT_ERROR = -1; - static const int SLOT_WARN = -2; - static const int SLOT_INFO = -3; - static const int SLOT_DEBUG = -4; - - private: - std::map<int, Variant> share; // threads shared value - }; - - public: - typedef int(*ThreadRunner)(void* obj); - Thread(const std::string name, ThreadRunner threadfuncs); - ~Thread(); - bool start(void* p); - void wait(); - void send(int slot, const Variant& value); - bool receive(int slot); - Variant fetch(int slot); - Variant demand(int slot); - void remove(int slot); - const char* getName(); - bool isRunning(); - void lock(); - void unlock(); - - protected: - #if JIN_THREAD_SDL - SDL_Thread* handle; // SDL thread - #elif JIN_THREAD_CPP - std::thread* handle; // cpp thread - #endif - Mutex* mutex; // mutex variable - Conditional* condition; // condition variable - ThreadRunner threadRunner; // thread function - ThreadData* common; // threads common data - const std::string name; // thread name, for debugging purposes - /** - * https://stackoverflow.com/questions/149932/naming-conventions-for-threads - * - * Use short names because they don't make the lines in a log file too long. - * - * Create names where the important part is at the beginning. Log viewers in a - * graphical user interface tend to have tables with columns, and the thread - * column is usually small or will be made small by you to read everything else. - * - * Do not use the word "thread" in the thread name because it is obvious. - * - * Make the thread names easily grep-able. Avoid similar sounding thread names - * - * If you have several threads of the same nature, enumerate them with IDs that - * are unique to one execution of the application or one log file, whichever fits - * your logging habits. - * - * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker - * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or - * "Calculation" (what does it calculate?). - * - * If you have a test group that uses thread names to grep your application's log - * files, do not rename your threads after some time. Your testers will hate you for - * doing so. Thread names in well-tested applications should be there to stay. - * - * When you have threads that service a network connection, try to include the target - * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about - * enumeration though if there are multiple connections to the same host. - */ - bool running; // running - - }; - -} // thread -} // jin - -#endif // JIN_MODULES_THREAD -#endif // __JIN_THREAD_H
\ No newline at end of file diff --git a/src/libjin/tilemap/tilemap.h b/src/libjin/tilemap/tilemap.h deleted file mode 100644 index a2bce62..0000000 --- a/src/libjin/tilemap/tilemap.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JIN_TILEMAP_H -#define __JIN_TILEMAP_H -#include "../modules.h" -#if JIN_MODULES_TILEMAP - -namespace jin -{ -namespace tilemap -{ - - - -}// tilemap -}// jin - -#endif // JIN_MODULES_TILEMAP -#endif // __JIN_TILEMAP_H
\ No newline at end of file diff --git a/src/libjin/ui/ui.h b/src/libjin/ui/ui.h deleted file mode 100644 index 6f70f09..0000000 --- a/src/libjin/ui/ui.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/src/libjin/utils/endian.h b/src/libjin/utils/endian.h deleted file mode 100644 index d4c441a..0000000 --- a/src/libjin/utils/endian.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef JIN_LIL_ENDIAN && JIN_BIG_ENDIAN - -#define JIN_LIL_ENDIAN 2 -#define JIN_BIG_ENDIAN 4 - -#endif - -#ifndef JIN_BYTEORDER -#ifdef __linux__ -#include <endian.h> -#define JIN_BYTEORDER __BYTE_ORDER -#else /* __linux__ */ -#if defined(__hppa__) || \ - defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ - (defined(__MIPS__) && defined(__MISPEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ - defined(__sparc__) -#define JIN_BYTEORDER JIN_BIG_ENDIAN -#else -#define JIN_BYTEORDER JIN_LIL_ENDIAN -#endif -#endif /* __linux__ */ -#endif /* !SDL_BYTEORDER */
\ No newline at end of file diff --git a/src/libjin/utils/log.cpp b/src/libjin/utils/log.cpp deleted file mode 100644 index 5299942..0000000 --- a/src/libjin/utils/log.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#define LOGHELPER_IMPLEMENT -#include "log.h"
\ No newline at end of file diff --git a/src/libjin/utils/log.h b/src/libjin/utils/log.h deleted file mode 100644 index e4ed879..0000000 --- a/src/libjin/utils/log.h +++ /dev/null @@ -1,134 +0,0 @@ -/** -* Single.h/loghelper.h -* Copyright (C) 2017~2018 chai -*/ -#ifndef __LOG_HELPER_H -#define __LOG_HELPER_H -#include <string> -#include <iostream> -#include <fstream> -#include <stdarg.h> - -class Loghelper -{ -public: - // logĿ - enum Direction - { - DIR_CERR = 1 << 1, // - DIR_FILE = 1 << 2, // logļ - }; - - // ȼ - enum Level - { - LV_NONE = 0, // none - LV_ERROR = 1 << 1, // error - LV_WARN = 1 << 2, // warn - LV_INFO = 1 << 3, // info - LV_DEBUG = 1 << 4, // debug - LV_ALL = 0xffffffff - }; - - static void log(Level _level, const char* _fmt, ...); - - // ض - static void redirect(unsigned int _dir, char* _path = nullptr); - - // ɸѡȼ - static void restrict(unsigned int levels); - - static void close(); - -private: - static unsigned int dir; // Ŀ - static unsigned int levels; // ȼ - static std::ofstream fs; // ļ -}; - -typedef Loghelper::Level Loglevel; - -#ifdef LOGHELPER_IMPLEMENT - -#define hasbit(flag, bit) ((flag & bit) == bit) - -unsigned int Loghelper::dir = Loghelper::Direction::DIR_CERR; -unsigned int Loghelper::levels = Loghelper::Level::LV_ALL; -std::ofstream Loghelper::fs; - -void Loghelper::log(Level _level, const char* _fmt, ...) -{ - if (!hasbit(levels, _level)) - return; -#define FORMAT_MSG_BUFFER_SIZE (204800) - const char* levelStr = nullptr; - switch (_level) - { - case LV_ERROR: - levelStr = "[Jin Error]:"; - break; - case LV_WARN: - levelStr = "[Jin Warn]:"; - break; - case LV_INFO: - levelStr = "[Jin Info]:"; - break; - case LV_DEBUG: - levelStr = "[Jin Debug]:"; - break; - default: - levelStr = "[Jin Unknown]:"; - break; - } - char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; - strcpy(buffer, levelStr); - va_list args; - va_start(args, _fmt); - vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); - va_end(args); - if (hasbit(dir, DIR_CERR)) - { - std::cerr << buffer << std::endl; - } - if (hasbit(dir, DIR_FILE)) - { - fs << buffer << std::endl; - } -#undef FORMAT_MSG_BUFFER_SIZE -} - -// ض -void Loghelper::redirect(unsigned int _dir, char* _path) -{ - dir = _dir; - if (hasbit(dir, DIR_FILE)) - { - try - { - fs.open(_path, std::ios_base::app); - } - catch (std::ios_base::failure& e) { - dir = DIR_CERR; - log(Level::LV_WARN, "ضlog· %s ʧ", _path); - } - } -} - -// ɸѡȼ -void Loghelper::restrict(unsigned int _levels) -{ - levels = _levels; -} - -void Loghelper::close() -{ - if (!fs.fail()) - fs.close(); - fs.clear(); -} - -#undef hasbit - -#endif - -#endif diff --git a/src/libjin/utils/macros.h b/src/libjin/utils/macros.h deleted file mode 100644 index a57cb7c..0000000 --- a/src/libjin/utils/macros.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JIN_MACROS_H -#define __JIN_MACROS_H -#include <cstring> - -#define implement // ʵֽӿ - -#define shared // ķ - -#define MASK // enum - -#define onlyonce // ֻһ -#define CALLONCE(call) static char __dummy__=(call, 1) // ֻһ -#define SAFECALL(func, params) if(func) func(params) - -#define zero(mem) memset(&mem, 0, sizeof(mem)) - -#endif
\ No newline at end of file diff --git a/src/libjin/utils/utils.h b/src/libjin/utils/utils.h deleted file mode 100644 index cf0920e..0000000 --- a/src/libjin/utils/utils.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __JIN_UTILS_H -#define __JIN_UTILS_H - -#include "macros.h" -#include "endian.h" - -#define UNITTEST 0 - -#endif
\ No newline at end of file diff --git a/src/lua/common/Proxy.h b/src/lua/common/Proxy.h index 8323ead..5ebb5b2 100644 --- a/src/lua/common/Proxy.h +++ b/src/lua/common/Proxy.h @@ -3,46 +3,65 @@ #include "Reference.hpp" -namespace jin +namespace JinEngine { -namespace lua -{ - - class Proxy + namespace Lua { - public: - void bind(RefBase* ref) - { - if (ref == nullptr) - return; - reference = ref; - } - void release() + class Proxy { - if (reference != nullptr) + public: + void bind(RefBase* ref) { - reference->release(); - reference = nullptr; + if (ref == nullptr) + return; + reference = ref; } - } - template<class T> - Ref<T>& getRef() - { - return *(Ref<T>*) reference; - } + void release() + { + if (reference != nullptr) + { + reference->release(); + reference = nullptr; + } + } - const char* getObjectType() - { - return reference->type; - } + void retain() + { + if (reference != nullptr) + reference->retain(); + } + + void setUserdata(void* data) + { + if (reference != nullptr) + reference->setUserdata(data); + } + + template<class T> + Ref<T>& getRef() + { + return *(Ref<T>*) reference; + } + + template<class T> + T* getObject() + { + Ref<T>& ref = getRef<T>(); + return ref.getObject(); + } + + const char* getObjectType() + { + return reference->type; + } - RefBase* reference; + RefBase* reference; - }; + }; -} // lua -} // jin + } // namespace Lua +} // namespace JinEngine #endif // __JIN_COMMON_PROXY_H
\ No newline at end of file diff --git a/src/lua/common/Reference.hpp b/src/lua/common/Reference.hpp index feb96bb..ba918bb 100644 --- a/src/lua/common/Reference.hpp +++ b/src/lua/common/Reference.hpp @@ -1,78 +1,88 @@ #ifndef __JIN_COMMON_REFERENCE_H #define __JIN_COMMON_REFERENCE_H -namespace jin +namespace JinEngine { -namespace lua -{ - - /*abstract*/class RefBase + namespace Lua { - public: - void retain() - { - ++count; - } - void release() + /*abstract*/class RefBase { - if (--count <= 0) - delete this; - } - - // object type string - const char* const type; - - protected: - RefBase(void* obj, const char* t) - : count(1) - , object(obj) - , type(t) - { - } - - RefBase(const RefBase&); - - virtual ~RefBase() - { - } - - void* object; - int count; - - }; - - template<class T> - class Ref : public RefBase - { - public: - Ref(T* obj, const char* type) - : RefBase(obj, type) + public: + void retain() + { + ++count; + } + + void release() + { + if (--count <= 0) + delete this; + } + + // object type string + const char* const type; + + void setUserdata(void* data) + { + userdata = data; + } + + void* getUserdata() + { + return userdata; + } + + protected: + RefBase(void* obj, const char* t) + : count(1) + , object(obj) + , type(t) + { + } + + RefBase(const RefBase&); + + virtual ~RefBase() + { + } + + void* object; + int count; + void* userdata; + }; + + template<class T> + class Ref : public RefBase { - } - - ~Ref() - { - T* obj = (T*)object; - delete obj; - } - - T* operator->() - { - return (T*)object; - } - - T* getObject() - { - return (T*)object; - } - - private: - Ref(const Ref<T>& ref); - - }; - -} + public: + Ref(T* obj, const char* type) + : RefBase(obj, type) + { + } + + ~Ref() + { + T* obj = static_cast<T*>(object); + delete obj; + } + + T* operator->() + { + return (T*)object; + } + + T* getObject() + { + return (T*)object; + } + + private: + Ref(const Ref<T>& ref); + + }; + + } } #endif
\ No newline at end of file diff --git a/src/lua/common/common.h b/src/lua/common/common.h index 536b897..0ee72cc 100644 --- a/src/lua/common/common.h +++ b/src/lua/common/common.h @@ -3,5 +3,6 @@ #include "Proxy.h" #include "Reference.hpp" +#include "error.h" #endif
\ No newline at end of file diff --git a/src/lua/common/error.h b/src/lua/common/error.h new file mode 100644 index 0000000..c254486 --- /dev/null +++ b/src/lua/common/error.h @@ -0,0 +1,28 @@ +#ifndef __JIN_ERROR_H +#define __JIN_ERROR_H +#include "../../luax.h" +#include "../jin.h" +#include <string.h> + +namespace JinEngine +{ +namespace Lua +{ + + static const int FORMAT_MSG_BUFFER_SIZE = 2048; + + inline void error(lua_State* L, const char* fmt, ...) + { + char err[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; + va_list args; + va_start(args, fmt); + vsnprintf(err + strlen(err), FORMAT_MSG_BUFFER_SIZE, fmt, args); + va_end(args); + luax_getglobal(L, MODULE_NAME); + luax_setfieldstring(L, "error", err); + } + +} +} + +#endif
\ No newline at end of file diff --git a/src/lua/modules/embed/boot.lua.h b/src/lua/embed/boot.lua.h index d84ca21..99e657b 100644 --- a/src/lua/modules/embed/boot.lua.h +++ b/src/lua/embed/boot.lua.h @@ -1,8 +1,8 @@ /* boot.lua */ static const char* boot_lua = R"( -jin._argv[2] = jin._argv[2] or '.' +jin.args[2] = jin.args[2] or '.' jin.filesystem.init() -jin.filesystem.mount(jin._argv[2]) +jin.filesystem.mount(jin.args[2]) ------------------------------------------------------------------------- -- Config game @@ -14,10 +14,11 @@ if jin.filesystem.exist("config.lua") then end jin.config.width = jin.config.width or 576 jin.config.height = jin.config.height or 448 -jin.config.vsync = jin.config.vsync or false -jin.config.title = jin.config.title or ("jin v" .. jin.version()) +jin.config.vsync = jin.config.vsync or true +jin.config.title = jin.config.title or ("jin v" .. jin.version) jin.config.resizable = jin.config.resizable or false jin.config.fullscreen = jin.config.fullscreen or false +jin.config.fps = jin.config.fps or 60 ------------------------------------------------------------------------- -- Initialize sub systems @@ -25,6 +26,7 @@ jin.config.fullscreen = jin.config.fullscreen or false jin.graphics.init(jin.config) jin.audio.init() +-- TODO: ϵͳģ ------------------------------------------------------------------------- -- Default game loop @@ -36,49 +38,30 @@ local function call(func, ...) end end -jin.core.setHandler = function(handler) - if handler == nil then - return - end - jin.core.onLoad = handler.onLoad - jin.core.onEvent = handler.onEvent - jin.core.onUpdate = handler.onUpdate - jin.core.onDraw = handler.onDraw -end - function jin.core.run() call(jin.core.onLoad) + jin.graphics.reset() local dt = 0 local previous = jin.time.second() local current = previous while jin.core.running() do for _, e in pairs(jin.event.poll()) do - if e.type == "keydown" then + if e.type == "KeyDown" then jin.keyboard.set(e.key, true) - elseif e.type == "keyup" then + elseif e.type == "KeyUp" then jin.keyboard.set(e.key, false) end call(jin.core.onEvent, e) end - previous = current current = jin.time.second() dt = current - previous - - call(jin.core.onUpdate, dt) - - if jin.graphics then - jin.graphics.unbindCanvas() - jin.graphics.clear() - jin.graphics.setColor() - jin.graphics.setFont() - call(jin.core.onDraw) - jin.graphics.present() - end - - if jin.time then - jin.time.sleep(0.001) - end + call(jin.core.onUpdate, dt) + jin.graphics.clear() + call(jin.core.onDraw) + jin.graphics.present() + -- Sleep 1 ms + jin.time.sleep(0.001) end end @@ -86,6 +69,17 @@ end -- No game handler ------------------------------------------------------------------------- +jin.core.setHandler = function(handler) + if handler == nil then + return + end + jin.core.onLoad = handler.onLoad + jin.core.onEvent = handler.onEvent + jin.core.onUpdate = handler.onUpdate + jin.core.onDraw = handler.onDraw +end + +-- TODO: Ĭͼbase64 jin.nogame = { cs = 64, sw = jin.graphics.getWidth(), @@ -103,11 +97,12 @@ jin.nogame = { nogame.t = nogame.ww - 1 end, onEvent = function(e) - if e.type == 'quit' then + if e.type == 'Quit' then jin.core.stop() end end, onUpdate = function(dt) + print(dt) local nogame = jin.nogame nogame.t = nogame.t + dt * nogame.speed if nogame.t > nogame.ww2 then @@ -144,27 +139,29 @@ jin.nogame = { ------------------------------------------------------------------------- local function onError(msg) - local tab = ' ' - print("Error:\n" .. msg) - function jin.core.onEvent(e) - if e.type == 'quit' then - jin.core.stop() + jin.graphics.reset() + jin.graphics.setClearColor(100, 100, 100, 255) + jin.graphics.clear() + jin.graphics.print("Error:\n" .. msg .. "\n" .. debug.traceback(), 5, 5) + jin.graphics.present() + while jin.core.running() do + for _, e in pairs(jin.event.poll()) do + if e.type == "Quit" then + jin.core.stop() + end end - end - local ww, wh = jin.graphics.getSize() - function jin.core.onDraw() - jin.graphics.write("Error: ", 10, 10, 30, 3, 30) - jin.graphics.write(msg, 10, 50) - end + jin.time.sleep(0.001) + end + jin.core.quit() end local function boot() if jin.filesystem.exist("main.lua") then - -- require main game script + -- Require main game script xpcall(function() require"main" end, onError) - jin.core.run() + xpcall(function() jin.core.run() end, onError) else - -- no game + -- No game jin.core.setHandler(jin.nogame) jin.core.run() end @@ -175,4 +172,4 @@ end xpcall(boot, onError) -)"; +)";
\ No newline at end of file diff --git a/src/lua/modules/embed/embed.h b/src/lua/embed/embed.h index 18ed1d8..18373c8 100644 --- a/src/lua/modules/embed/embed.h +++ b/src/lua/embed/embed.h @@ -2,14 +2,11 @@ #define __JIN_LUA_EMBED_H #include <cstring> -namespace jin +namespace JinEngine { namespace embed { - /** - * embed lua script to context. - */ #define embed(L, script, name)\ if(luax_loadbuffer(L, script, strlen(script), name) == 0)\ lua_call(L, 0, 0); @@ -25,25 +22,25 @@ namespace embed static void boot(lua_State* L) { // embed scripts - #include "graphics.lua.h" // graphics - #include "keyboard.lua.h" // keyboard - #include "mouse.lua.h" // mouse - #include "boot.lua.h" // boot + #include "graphics.lua.h" + #include "keyboard.lua.h" + #include "mouse.lua.h" + #include "boot.lua.h" - // embed scripts + // in order const jin_Embed scripts[] = { - { "graphics.lua", graphics_lua }, - { "keyboard.lua", keyboard_lua }, - { "mouse.lua", mouse_lua }, - { "boot.lua", boot_lua }, - { 0, 0 } + { "graphics.lua", graphics_lua }, + { "keyboard.lua", keyboard_lua }, + { "mouse.lua", mouse_lua }, + { "boot.lua", boot_lua }, + { 0, 0 } }; - // load all emebd lua scripts for (int i = 0; scripts[i].file; ++i) embed(L, scripts[i].source, scripts[i].file); } -} -} + +} // embed +} // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/lua/embed/graphics.lua.h b/src/lua/embed/graphics.lua.h new file mode 100644 index 0000000..5fa5dad --- /dev/null +++ b/src/lua/embed/graphics.lua.h @@ -0,0 +1,46 @@ +/* graphics.lua */ +static const char* graphics_lua = R"( +jin.graphics = jin.graphics or {} + +local default_shader = nil +local default_shader_source = [[ +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return col * texel(tex, v.uv); +} + +#END_FRAGMENT_SHADER +]] + +local _init = jin.graphics.init + +jin.graphics.init = function(setting) + _init(setting); + default_shader = jin.graphics.newShader(default_shader_source) + jin.graphics.useShader(default_shader) +end + +jin.graphics.unuseShader = function() + jin.graphics.useShader(default_shader) +end + +-- Reset all attributes to default value. +jin.graphics.reset = function() + jin.graphics.setColor(255, 255, 255, 255) + jin.graphics.setClearColor(0, 0, 0, 255) + jin.graphics.clear() + jin.graphics.unsetFont() +end + +)"; diff --git a/src/lua/modules/embed/keyboard.lua.h b/src/lua/embed/keyboard.lua.h index 77bf3a9..ee8428f 100644 --- a/src/lua/modules/embed/keyboard.lua.h +++ b/src/lua/embed/keyboard.lua.h @@ -4,7 +4,7 @@ jin.keyboard = jin.keyboard or {} local keys = {} -function jin.keyboard.isDown(k) +function jin.keyboard.isPressed(k) return keys[k] end diff --git a/src/lua/modules/embed/mouse.lua.h b/src/lua/embed/mouse.lua.h index 3c222f3..3c222f3 100644 --- a/src/lua/modules/embed/mouse.lua.h +++ b/src/lua/embed/mouse.lua.h diff --git a/src/lua/modules/embed/net.lua.h b/src/lua/embed/net.lua.h index 4d89dc7..4d89dc7 100644 --- a/src/lua/modules/embed/net.lua.h +++ b/src/lua/embed/net.lua.h diff --git a/src/lua/modules/embed/path.lua.h b/src/lua/embed/path.lua.h index 648adf8..648adf8 100644 --- a/src/lua/modules/embed/path.lua.h +++ b/src/lua/embed/path.lua.h diff --git a/src/lua/jin.cpp b/src/lua/jin.cpp new file mode 100644 index 0000000..faae9b2 --- /dev/null +++ b/src/lua/jin.cpp @@ -0,0 +1,110 @@ +#include "jin.h" +#include "lua/modules/luax.h" +#include "embed/embed.h" + +namespace JinEngine +{ + namespace Lua + { + + extern int luaopen_core(lua_State* L); + extern int luaopen_graphics(lua_State* L); + extern int luaopen_audio(lua_State* L); + extern int luaopen_net(lua_State* L); + extern int luaopen_event(lua_State* L); + extern int luaopen_time(lua_State* L); + extern int luaopen_mouse(lua_State* L); + extern int luaopen_keyboard(lua_State* L); + extern int luaopen_filesystem(lua_State* L); + extern int luaopen_joypad(lua_State* L); + extern int luaopen_math(lua_State* L); + extern int luaopen_thread(lua_State* L); + extern int luaopen_bit(lua_State* L); + + static int l_getversion(lua_State* L) + { + luax_pushstring(L, VERSION); + return 1; + } + + static int l_getAuthor(lua_State* L) + { + luax_pushstring(L, AUTHOR); + return 1; + } + + static int l_getOS(lua_State* L) + { + #ifdef _WIN32 + luax_pushstring(L, "windows"); + #elif defined __unix__ + luax_pushstring(L, "unix"); + #elif defined __APPLE__ + luax_pushstring(L, "macos"); + #endif + return 1; + } + + static int l_revision(lua_State* L) + { + luax_pushnumber(L, REVISION); + return 1; + } + + static const luax_Str s[] = { + { "version", VERSION }, + { "author", AUTHOR }, + { "codename", CODE_NAME }, + { 0, 0 } + }; + + static const luax_Num n[] = { + { "revision", REVISION }, + { 0, 0 } + }; + + /* sub modules */ + static const luax_Ref mods[] = { + { "core", luaopen_core }, + { "event", luaopen_event }, + { "graphics", luaopen_graphics }, + { "time", luaopen_time }, + { "mouse", luaopen_mouse }, + { "keyboard", luaopen_keyboard }, + { "filesystem", luaopen_filesystem }, + { "net", luaopen_net }, + { "audio", luaopen_audio }, + { "joypad", luaopen_joypad }, + { "math", luaopen_math }, + { "thread", luaopen_thread }, + { "bit", luaopen_bit }, + //{"ai", luaopen_ai }, + { 0, 0 } + }; + + /* register jin module, keep it on the top of stack */ + int luaopen_jin(lua_State* L) + { + luax_globaltable(L, MODULE_NAME); + + /* register values */ + luax_setfieldstrings(L, s); + luax_setfieldnumbers(L, n); + + /* register submodules */ + for (int i = 0; mods[i].name; ++i) + { + mods[i].func(L); + luax_setfield(L, -2, mods[i].name); + } + + return 1; + } + + void boot(lua_State* L) + { + JinEngine::embed::boot(L); + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/jin.h b/src/lua/jin.h new file mode 100644 index 0000000..71ad51b --- /dev/null +++ b/src/lua/jin.h @@ -0,0 +1,34 @@ +/** +* Copyright (C) 2016~2018 chai +*/ + +#ifndef __JIN_M_JIN_H +#define __JIN_M_JIN_H +#include "luax.h" + +#define MODULE_NAME "jin" +#define CODE_NAME "Side Part" +#define VERSION "0.1.1" +#define REVISION_S "101" +#define REVISION 101 +#define AUTHOR "chai" + +namespace JinEngine +{ + namespace Lua + { + + /// + /// open jin module. + /// + int luaopen_jin(lua_State* L); + + /// + /// Boot jin. + /// + void boot(lua_State* L); + + } // namespace JinEngine +} // namespace Lua + +#endif // __JIN_M_JIN_H
\ No newline at end of file diff --git a/src/lua/libraries/luax/luax.h b/src/lua/libraries/luax/luax.h index 56023b3..fd10737 100644 --- a/src/lua/libraries/luax/luax.h +++ b/src/lua/libraries/luax/luax.h @@ -39,13 +39,18 @@ #define luax_dostring luaL_dostring #define luax_pcall lua_pcall #define luax_setglobal lua_setglobal +#define luax_setglobali(L, i, name)\ +lua_pushvalue(L, i);\ +lua_setglobal(L, name); #define luax_pop lua_pop #define luax_newtable lua_newtable #define luax_getglobal lua_getglobal + +#define luax_clear(L) lua_settop(L, 0) /** * */ -#define luax_setglobal_string(L, n, v) (lua_pushstring(L, v), lua_setglobal(L, n)) +#define luax_setglobalstring(L, n, v) (lua_pushstring(L, v), lua_setglobal(L, n)) /** * Get number of args @@ -82,6 +87,7 @@ inline bool luax_checkbool(lua_State *L, int numArg) /** * Oprating tables. */ +/* get value and leaves it on top of stack */ #define luax_rawgetnumber(L, i, k) (lua_rawgeti(L,i, k), lua_tonumber(L, -1)) /** @@ -104,6 +110,7 @@ inline bool luax_checkbool(lua_State *L, int numArg) #define luax_pushinteger lua_pushinteger #define luax_pushboolean lua_pushboolean #define luax_pushlightuserdata lua_pushlightuserdata +#define luax_pushnil lua_pushnil //inline void luax_pushuserdata(lua_State* L, void* p) //{ @@ -124,37 +131,38 @@ inline bool luax_checkbool(lua_State *L, int numArg) #define luax_setfield_(T, L, k, v)\ do { lua_push##T(L, v); lua_setfield(L, -2, k); } while (0) -#define luax_setfield_number(L, k, v) luax_setfield_(number, L, k, v) -#define luax_setfield_string(L, k, v) luax_setfield_(string, L, k, v) -#define luax_setfield_bool(L, k, v) luax_setfield_(boolean, L, k, v) -#define luax_setfield_udata(L, k, v) luax_setfield_(lightuserdata, L, k, v) -#define luax_setfield_cfunc(L, k, v) luax_setfield_(cfunction, L, k, v) -#define luax_setfield_fstring(L, k, ...)\ +#define luax_setfieldnumber(L, k, v) luax_setfield_(number, L, k, v) +#define luax_setfieldinteger(L, k, v) luax_setfield_(integer, L, k, v) +#define luax_setfieldstring(L, k, v) luax_setfield_(string, L, k, v) +#define luax_setfieldbool(L, k, v) luax_setfield_(boolean, L, k, v) +#define luax_setfieldudata(L, k, v) luax_setfield_(lightuserdata, L, k, v) +#define luax_setfieldcfunc(L, k, v) luax_setfield_(cfunction, L, k, v) +#define luax_setfieldfstring(L, k, ...)\ do { lua_pushfstring(L, __VA_ARGS__); lua_setfield(L, -2, k); } while (0) /** * If nosuch field push a nil at the top of stack. */ #define luax_getfield(L, I, N) lua_getfield(L, I, N) -inline float luax_getfield_number(lua_State* L, int I, const char* N) +inline float luax_getfieldnumber(lua_State* L, int I, const char* N) { luax_getfield(L, I, N); float n = luax_checknumber(L, -1); return n; } -inline int luax_getfield_integer(lua_State* L, int I, const char* N) +inline int luax_getfieldinteger(lua_State* L, int I, const char* N) { luax_getfield(L, I, N); int bin = luax_checkinteger(L, -1); return bin; } -inline const char* luax_getfield_string(lua_State* L, int I, const char* N) +inline const char* luax_getfieldstring(lua_State* L, int I, const char* N) { luax_getfield(L, I, N); const char* str = luax_checkstring(L, -1); return str; } -inline char luax_getfield_bool(lua_State* L, int I, const char* N) +inline char luax_getfieldbool(lua_State* L, int I, const char* N) { luax_getfield(L, I, N); char bin = lua_toboolean(L, -1); @@ -164,12 +172,12 @@ inline char luax_getfield_bool(lua_State* L, int I, const char* N) /** * Set raw */ -#define luax_setraw_(T, L, idx, i, v)\ +#define luax_setraw(T, L, idx, i, v)\ (lua_push##T(L, v), lua_rawseti(L, idx, i)) -#define luax_setraw_string(L, idx, i, v) luax_setraw_(string, L, idx, i, v) -#define luax_setraw_number(L, idx, i, v) luax_setraw_(number, L, idx, i, v) -#define luax_setraw_bool(L, idx, i, v) luax_setraw_(boolean, L, idx, i, v) +#define luax_setrawstring(L, idx, i, v) luax_setraw(string, L, idx, i, v) +#define luax_setrawnumber(L, idx, i, v) luax_setraw(number, L, idx, i, v) +#define luax_setrawbool(L, idx, i, v) luax_setraw(boolean, L, idx, i, v) /** * @@ -315,7 +323,7 @@ inline int luax_tableidxlen(lua_State* L, int i) } /** -* Get table hash size +* Get table hash size inline int luax_tbalehashlen(lua_State* L, int i) { @@ -323,20 +331,20 @@ inline int luax_tbalehashlen(lua_State* L, int i) */ /** -* Get table hash and index size +* Get table hash and index size inline int luax_tablelen(lua_State* L, int i) { } */ -/** -* Set value i in stack a global value called v, and -* don't pop it. -*/ -#define luax_justglobal(L, i, v) (lua_pushvalue(L, i), lua_setglobal(L, v)) +/* create a global tbale and stay it on the top of stack */ +#define luax_globaltable(L, name)\ +lua_newtable(L);\ +lua_pushvalue(L, 1);\ +lua_setglobal(L, name); -inline int luax_table_insert(lua_State * L, int tindex, int vindex, int pos) +inline int luax_tableinsert(lua_State * L, int tindex, int vindex, int pos) { if (tindex < 0) tindex = lua_gettop(L) + 1 + tindex; @@ -363,7 +371,7 @@ inline int luax_table_insert(lua_State * L, int tindex, int vindex, int pos) /** * Add the package loader to the package.loaders table. */ -inline int luax_register_searcher(lua_State * L, lua_CFunction f, int pos) +inline int luax_registersearcher(lua_State * L, lua_CFunction f, int pos) { lua_getglobal(L, "package"); @@ -376,11 +384,41 @@ inline int luax_register_searcher(lua_State * L, lua_CFunction f, int pos) return luaL_error(L, "Can't register searcher: package.loaders table does not exist."); lua_pushcfunction(L, f); - luax_table_insert(L, -2, -1, pos); + luax_tableinsert(L, -2, -1, pos); lua_pop(L, 3); return 0; } +typedef struct luax_Str +{ + const char* name; + const char* value; +} luax_Str; + +inline void luax_setfieldstrings(lua_State* L, const luax_Str* strs) +{ + for (int i = 0; strs[i].name != 0; ++i) + { + luax_setfieldstring(L, strs[i].name, strs[i].value); + } +} + +typedef struct luax_Num +{ + const char* name; + float number; +}; + +inline void luax_setfieldnumbers(lua_State* L, const luax_Num* strs) +{ + for (int i = 0; strs[i].name != 0; ++i) + { + luax_setfieldnumber(L, strs[i].name, strs[i].number); + } +} + +typedef luaL_Reg luax_Ref; + #endif // #if LUA_VERSION_NUM == 501 #endif // __LUAX_H
\ No newline at end of file diff --git a/src/lua/luax.h b/src/lua/luax.h new file mode 100644 index 0000000..89e456e --- /dev/null +++ b/src/lua/luax.h @@ -0,0 +1,7 @@ +#ifndef __JIN_LUA_LUAX_H +#define __JIN_LUA_LUAX_H + +#include "LuaJIT/lua.hpp" +#include "lua/libraries/luax/luax.h" + +#endif
\ No newline at end of file diff --git a/src/lua/main.cpp b/src/lua/main.cpp new file mode 100644 index 0000000..95862ec --- /dev/null +++ b/src/lua/main.cpp @@ -0,0 +1,44 @@ +#ifdef _WIN32 + #include <SDL2/SDL_Main.h> + #include <direct.h> +#endif + +#include "luax.h" +#include "jin.h" +#include "libjin/jin.h" +#include <Windows.h> + +using namespace JinEngine::Lua; +using namespace JinEngine::Filesystem; + +int main(int argc, char* argv[]) +{ + lua_State* L = luax_newstate(); + + /* open lua standard module */ + luax_openlibs(L); + /* open jin module */ + luaopen_jin(L); + /* add args to field */ + luax_newtable(L); + for (int i = 0; i < argc; ++i) + luax_setrawstring(L, -2, i + 1, argv[i]); + luax_setfield(L, -2, "args"); + /* push current working directory */ + /* absolute directory */ + Buffer cwd = Buffer(1024); +#ifdef _WIN32 + _getcwd((char*)&cwd, cwd.size()); +#elif defined __unix__ +#elif defined __APPLE__ +#endif + luax_setfieldstring(L, "cwd", (char*)&cwd); + luax_clear(L); + + /* boot jin and run it */ + boot(L); + + luax_close(L); + + return 0; +}
\ No newline at end of file diff --git a/src/lua/modules/audio/audio.cpp b/src/lua/modules/audio/audio.cpp index 8e11b88..198323d 100644 --- a/src/lua/modules/audio/audio.cpp +++ b/src/lua/modules/audio/audio.cpp @@ -3,108 +3,121 @@ #include "lua/common/common.h" #include "libjin/jin.h" -namespace jin +namespace JinEngine { -namespace lua -{ + namespace Lua + { - using namespace jin::audio; - using namespace jin::filesystem; + using namespace JinEngine::Audio; + using namespace JinEngine::Filesystem; - typedef SDLAudio Audio; - typedef SDLSource Source; + typedef SDLAudio Audio; + typedef SDLSource Source; - static int l_init(lua_State* L) - { - Audio::Setting setting; - setting.samplerate = 44100; - setting.samples = 44100; - if (!Audio::get()->init(&setting)) + static int l_init(lua_State* L) { - luax_error(L, "could not init audio"); - luax_pushboolean(L, false); + Audio::Setting setting; + setting.samplerate = 44100; + setting.samples = 44100; + if (!Audio::get()->init(&setting)) + { + luax_error(L, "could not init audio"); + luax_pushboolean(L, false); + return 1; + } + luax_pushboolean(L, true); return 1; } - luax_pushboolean(L, true); - return 1; - } - - static int l_play(lua_State* L) - { - Audio::get()->play(); - return 0; - } - - static int l_stop(lua_State* L) - { - Audio::get()->stop(); - return 0; - } - - static int l_pause(lua_State* L) - { - Audio::get()->pause(); - return 0; - } - - static int l_resume(lua_State* L) - { - Audio::get()->resume(); - return 0; - } - - static int l_setVolume(lua_State* L) - { - float volume = luax_checknumber(L, 1); - Audio::get()->setVolume(volume); - return 0; - } - - static int l_newSource(lua_State* L) - { - Filesystem* fs = Filesystem::get(); - const char* f = luax_checkstring(L, 1); - if (!fs->exists(f)) + + static int l_play(lua_State* L) + { + Audio::get()->play(); + return 0; + } + + static int l_stop(lua_State* L) + { + Audio::get()->stop(); + return 0; + } + + static int l_pause(lua_State* L) + { + Audio::get()->pause(); + return 0; + } + + static int l_resume(lua_State* L) + { + Audio::get()->resume(); + return 0; + } + + static int l_setVolume(lua_State* L) + { + float volume = luax_checknumber(L, 1); + Audio::get()->setVolume(volume); + return 0; + } + + static int l_newSource(lua_State* L) { - printf("Error: no such image %s\n", f); - exit(1); + AssetDatabase* fs = AssetDatabase::get(); + const char* f = luax_checkstring(L, 1); + Buffer b; + if (!fs->exists(f)) + { + error(L, "No such image %s", f); + goto fail; + } + if (!fs->read(f, b)) + { + error(L, "Failed to read source file %s", f); + goto fail; + } + Source* src = Source::createSource((void*)&b, b.size()); + if (src == nullptr) + { + error(L, "Failed to decode source file %s", f); + goto fail; + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_AUDIO_SOURCE, sizeof(Proxy)); + proxy->bind(new Ref<Source>(src, JIN_AUDIO_SOURCE)); + return 1; + fail: + luax_pushnil(L); + return 1; } - Buffer b; - fs->read(f, &b); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_AUDIO_SOURCE, sizeof(Proxy)); - Source* src = Source::createSource(b.data, b.size); - proxy->bind(new Ref<Source>(src, JIN_AUDIO_SOURCE)); - return 1; - } - static int l_destroy(lua_State* L) - { - Audio* audio = Audio::get(); - audio->quit(); - return 0; - } - - static const luaL_Reg f[] = { - { "init", l_init }, - { "play", l_play }, - { "stop", l_stop }, - { "pause", l_pause }, - { "resume", l_resume }, - { "setVolume", l_setVolume }, - { "newSource", l_newSource }, - { "destroy", l_destroy }, - { 0, 0 } - }; - - extern int luaopen_Source(lua_State* L); - - int luaopen_audio(lua_State* L) - { - luaopen_Source(L); - - luax_newlib(L, f); - - return 1; - } -} -}
\ No newline at end of file + static int l_destroy(lua_State* L) + { + Audio* audio = Audio::get(); + audio->quit(); + return 0; + } + + static const luaL_Reg f[] = { + { "init", l_init }, + { "play", l_play }, + { "stop", l_stop }, + { "pause", l_pause }, + { "resume", l_resume }, + { "setVolume", l_setVolume }, + { "newSource", l_newSource }, + { "destroy", l_destroy }, + { 0, 0 } + }; + + extern int luaopen_Source(lua_State* L); + + int luaopen_audio(lua_State* L) + { + luaopen_Source(L); + + luax_newlib(L, f); + + return 1; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/audio/source.cpp b/src/lua/modules/audio/source.cpp index 1953121..bf43ceb 100644 --- a/src/lua/modules/audio/source.cpp +++ b/src/lua/modules/audio/source.cpp @@ -3,114 +3,114 @@ #include "lua/common/common.h" #include "lua/modules/types.h" -namespace jin +namespace JinEngine { -namespace lua -{ - - using namespace jin::audio; - - typedef Ref<Source>& SourceRef; - - static inline SourceRef checkSource(lua_State* L) + namespace Lua { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_AUDIO_SOURCE); - return proxy->getRef<Source>(); - } - static int l_play(lua_State* L) - { - SourceRef ref = checkSource(L); - ref->play(); - return 0; - } - - static int l_stop(lua_State* L) - { - SourceRef ref = checkSource(L); - ref->stop(); - return 0; - } - - static int l_pause(lua_State* L) - { - SourceRef ref = checkSource(L); - ref->pause(); - return 0; - } - - static int l_rewind(lua_State* L) - { - SourceRef ref = checkSource(L); - ref->rewind(); - return 0; - } - - static int l_resume(lua_State* L) - { - SourceRef ref = checkSource(L); - ref->resume(); - return 0; - } - - static int l_isStop(lua_State* L) - { - SourceRef ref = checkSource(L); - bool isStop = ref->isStopped(); - luax_pushboolean(L, isStop); - return 1; - } - - static int l_isPaused(lua_State* L) - { - SourceRef ref = checkSource(L); - bool isPaused = ref->isPaused(); - luax_pushboolean(L, isPaused); - return 1; - } - - static int l_setVolume(lua_State* L) - { - SourceRef ref = checkSource(L); - float volume = luax_checknumber(L, 2); - ref->setVolume(volume); - return 0; - } - - static int l_setLoop(lua_State* L) - { - SourceRef ref = checkSource(L); - bool loop = luax_checkbool(L, 2); - ref->setLoop(loop); - return 0; - } - - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_AUDIO_SOURCE); - proxy->release(); - return 0; - } - - static const luaL_Reg f[] = { - { "__gc", l_gc }, - { "play", l_play }, - { "stop", l_stop }, - { "pause", l_pause }, - { "resume", l_resume }, - { "rewind", l_rewind }, - { "isStop", l_isStop }, - { "isPaused", l_isPaused }, - { "setVolume", l_setVolume }, - { "setLoop", l_setLoop }, - { 0, 0 } - }; + using namespace JinEngine::Audio; + + typedef Ref<Source>& SourceRef; + + static inline SourceRef checkSource(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_AUDIO_SOURCE); + return proxy->getRef<Source>(); + } + + static int l_play(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->play(); + return 0; + } + + static int l_stop(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->stop(); + return 0; + } + + static int l_pause(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->pause(); + return 0; + } + + static int l_rewind(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->rewind(); + return 0; + } + + static int l_resume(lua_State* L) + { + SourceRef ref = checkSource(L); + ref->resume(); + return 0; + } + + static int l_isStop(lua_State* L) + { + SourceRef ref = checkSource(L); + bool isStop = ref->isStopped(); + luax_pushboolean(L, isStop); + return 1; + } + + static int l_isPaused(lua_State* L) + { + SourceRef ref = checkSource(L); + bool isPaused = ref->isPaused(); + luax_pushboolean(L, isPaused); + return 1; + } + + static int l_setVolume(lua_State* L) + { + SourceRef ref = checkSource(L); + float volume = luax_checknumber(L, 2); + ref->setVolume(volume); + return 0; + } + + static int l_setLoop(lua_State* L) + { + SourceRef ref = checkSource(L); + bool loop = luax_checkbool(L, 2); + ref->setLoop(loop); + return 0; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_AUDIO_SOURCE); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "play", l_play }, + { "stop", l_stop }, + { "pause", l_pause }, + { "resume", l_resume }, + { "rewind", l_rewind }, + { "isStop", l_isStop }, + { "isPaused", l_isPaused }, + { "setVolume", l_setVolume }, + { "setLoop", l_setLoop }, + { 0, 0 } + }; - int luaopen_Source(lua_State* L) - { - luax_newtype(L, JIN_AUDIO_SOURCE, f); - return 0; - } - -} // lua -} // jin
\ No newline at end of file + int luaopen_Source(lua_State* L) + { + luax_newtype(L, JIN_AUDIO_SOURCE, f); + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/bit/bit.cpp b/src/lua/modules/bit/bit.cpp index 5b18125..cedd60a 100644 --- a/src/lua/modules/bit/bit.cpp +++ b/src/lua/modules/bit/bit.cpp @@ -2,83 +2,83 @@ #include "libjin/jin.h" #include <cstdlib> -namespace jin +namespace JinEngine { -namespace lua -{ - - static int l_and(lua_State* L) + namespace Lua { - int a = luax_checkinteger(L, 1); - int b = luax_checkinteger(L, 2); - luax_pushinteger(L, a & b); - return 1; - } - static int l_or(lua_State* L) - { - int a = luax_checkinteger(L, 1); - int b = luax_checkinteger(L, 2); - luax_pushinteger(L, a | b); - return 1; - } + static int l_and(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a & b); + return 1; + } - static int l_xor(lua_State* L) - { - int a = luax_checkinteger(L, 1); - int b = luax_checkinteger(L, 2); - luax_pushinteger(L, a ^ b); - return 1; - } + static int l_or(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a | b); + return 1; + } - static int l_not(lua_State* L) - { - int n = luax_checkinteger(L, 1); - luax_pushinteger(L, ~n); - return 1; - } + static int l_xor(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a ^ b); + return 1; + } - static int l_lshift(lua_State* L) - { - int a = luax_checkinteger(L, 1); - int b = luax_checkinteger(L, 2); - luax_pushinteger(L, a << b); - return 1; - } + static int l_not(lua_State* L) + { + int n = luax_checkinteger(L, 1); + luax_pushinteger(L, ~n); + return 1; + } - static int l_rshift(lua_State* L) - { - int a = luax_checkinteger(L, 1); - int b = luax_checkinteger(L, 2); - luax_pushinteger(L, a >> b); - return 1; - } + static int l_lshift(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a << b); + return 1; + } - static int l_include(lua_State* L) - { - int a = luax_checkinteger(L, 1); - int b = luax_checkinteger(L, 2); - luax_pushboolean(L, (a & b) == b); - return 1; - } + static int l_rshift(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushinteger(L, a >> b); + return 1; + } - static const luaL_Reg f[] = { - { "bAnd", l_and }, - { "bOr" , l_or }, - { "bXor", l_xor }, - { "bNot", l_not }, - { "bLs", l_lshift }, - { "bRs", l_rshift }, - { "bInc", l_include }, - { 0, 0 } - }; + static int l_include(lua_State* L) + { + int a = luax_checkinteger(L, 1); + int b = luax_checkinteger(L, 2); + luax_pushboolean(L, (a & b) == b); + return 1; + } - int luaopen_bit(lua_State* L) - { - luax_newlib(L, f); + static const luaL_Reg f[] = { + { "bAnd", l_and }, + { "bOr" , l_or }, + { "bXor", l_xor }, + { "bNot", l_not }, + { "bLs", l_lshift }, + { "bRs", l_rshift }, + { "bInc", l_include }, + { 0, 0 } + }; + + int luaopen_bit(lua_State* L) + { + luax_newlib(L, f); - return 1; - } + return 1; + } -} -}
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/core/core.cpp b/src/lua/modules/core/core.cpp index 0243554..a576bec 100644 --- a/src/lua/modules/core/core.cpp +++ b/src/lua/modules/core/core.cpp @@ -1,44 +1,46 @@ #include "lua/modules/luax.h" #include "libjin/jin.h" -namespace jin +namespace JinEngine { -namespace lua -{ - using namespace jin::core; - - static int l_running(lua_State* L) + namespace Lua { - static Game* game = Game::get(); - bool running = game->running(); - luax_pushboolean(L, running); - return 1; - } - static int l_stop(lua_State* L) - { - Game::get()->stop(); - return 0; - } + using namespace JinEngine::Core; - static int l_quit(lua_State* L) - { - Game::get()->quit(); - return 0; - } - - static const luaL_Reg f[] = { - {"running", l_running }, - {"stop", l_stop }, - {"quit", l_quit }, - {0, 0 } - }; - - int luaopen_core(lua_State* L) - { - luax_newlib(L, f); + static int l_running(lua_State* L) + { + static Game* game = Game::get(); + bool running = game->running(); + luax_pushboolean(L, running); + return 1; + } + + static int l_stop(lua_State* L) + { + Game::get()->stop(); + return 0; + } + + static int l_quit(lua_State* L) + { + Game::get()->quit(); + return 0; + } + + static const luaL_Reg f[] = { + { "running", l_running }, + { "stop", l_stop }, + { "quit", l_quit }, + { 0, 0 } + }; + + int luaopen_core(lua_State* L) + { + luax_newlib(L, f); + + return 1; + } - return 1; - } -} -}
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/embed/graphics.lua.h b/src/lua/modules/embed/graphics.lua.h deleted file mode 100644 index 1414efc..0000000 --- a/src/lua/modules/embed/graphics.lua.h +++ /dev/null @@ -1,4 +0,0 @@ -/* graphics.lua */ -static const char* graphics_lua = R"( -jin.graphics = jin.graphics or {} -)"; diff --git a/src/lua/modules/event/event.cpp b/src/lua/modules/event/event.cpp index af9f8fc..9f565d0 100644 --- a/src/lua/modules/event/event.cpp +++ b/src/lua/modules/event/event.cpp @@ -4,103 +4,127 @@ #include "lua/modules/luax.h" #include "libjin/jin.h" -namespace jin -{ -namespace lua +namespace JinEngine { + namespace Lua + { - using namespace jin::input; + using namespace JinEngine; + using namespace JinEngine::Input; - /** - * Load event poll, return a iterator(a table). - */ - static int l_event_poll(lua_State *L) - { - // table to store events - luax_newtable(L); - static Event e; - int i = 1; - poll: - while (pollEvent(&e)) + /** + * Load event poll, return a iterator(a table). + */ + static int l_event_poll(lua_State *L) { - // each event is a table + /* table to store events */ luax_newtable(L); - switch (e.type) + static Event e; + int i = 1; + poll: + while (pollEvent(&e)) { - case EventType::QUIT: - luax_setfield_string(L, "type", "quit"); - break; + /** + * TODO: ڴСıʱҪtransform + * + */ + luax_newtable(L); + switch (e.type) + { + case EventType::QUIT: + luax_setfieldstring(L, "type", "Quit"); + break; - case EventType::KEY_DOWN: - luax_setfield_string(L, "type", "keydown"); - luax_setfield_string(L, "key", getKeyName(e.key.keysym.sym)); - break; - - case EventType::KEY_UP: - luax_setfield_string(L, "type", "keyup"); - luax_setfield_string(L, "key", getKeyName(e.key.keysym.sym)); - break; + case EventType::KEY_DOWN: + case EventType::KEY_UP: + luax_setfieldstring(L, "type", e.type == EventType::KEY_DOWN ? "KeyDown" : "KeyUp"); + luax_setfieldstring(L, "key", getKeyName(e.key.keysym.sym)); + break; - case EventType::MOUSE_MOTION: - luax_setfield_string(L, "type", "mousemotion"); - luax_setfield_number(L, "x", e.motion.x); - luax_setfield_number(L, "y", e.motion.y); - break; + case EventType::MOUSE_MOTION: + luax_setfieldstring(L, "type", "MouseMotion"); + luax_setfieldnumber(L, "x", e.motion.x); + luax_setfieldnumber(L, "y", e.motion.y); + break; - case EventType::MOUSE_BUTTON_DOWN: - luax_setfield_string(L, "type", "mousebuttondown"); - luax_setfield_string(L, "button", getButtonName(e.button.button)); - luax_setfield_number(L, "x", e.button.x); - luax_setfield_number(L, "y", e.button.y); - break; + case EventType::MOUSE_BUTTON_DOWN: + case EventType::MOUSE_BUTTON_UP: + luax_setfieldstring(L, "type", e.type == EventType::MOUSE_BUTTON_DOWN ? "MouseButtonDown" : "MouseButtonUp"); + luax_setfieldstring(L, "button", getButtonName(e.button.button)); + luax_setfieldnumber(L, "x", e.button.x); + luax_setfieldnumber(L, "y", e.button.y); + break; - case EventType::MOUSE_BUTTON_UP: - luax_setfield_string(L, "type", "mousebuttonup"); - luax_setfield_string(L, "button", getButtonName(e.button.button)); - luax_setfield_number(L, "x", e.button.x); - luax_setfield_number(L, "y", e.button.y); - break; + case EventType::MOUSE_WHEEL: + luax_setfieldstring(L, "type", "Wheel"); + if(e.wheel.x == -1) + luax_setfieldstring(L, "x", "Left"); + else if(e.wheel.x == 1) + luax_setfieldstring(L, "x", "Right"); + else + luax_setfieldstring(L, "x", "None"); + if (e.wheel.y == -1) + luax_setfieldstring(L, "y", "Near"); + else if (e.wheel.y == 1) + luax_setfieldstring(L, "y", "Far"); + else + luax_setfieldstring(L, "y", "None"); + break; - case EventType::MOUSE_WHEEL: - luax_setfield_string(L, "type", "wheel"); - if(e.wheel.x == -1) - luax_setfield_string(L, "x", "left"); - else if(e.wheel.x == 1) - luax_setfield_string(L, "x", "right"); - else - luax_setfield_string(L, "x", "none"); - if (e.wheel.y == -1) - luax_setfield_string(L, "y", "near"); - else if (e.wheel.y == 1) - luax_setfield_string(L, "y", "far"); - else - luax_setfield_string(L, "y", "none"); - break; - - default: - /* ignore other events */ - luax_pop(L, 1); // pop table out - goto poll; - break; + case EventType::JOYBUTTONDOWN: + case EventType::JOYBUTTONUP: + luax_setfieldstring(L, "type", e.type == EventType::JOYBUTTONDOWN ? "JoyButtonDown" : "JoyButtonUp"); + luax_setfieldinteger(L, "which", e.jbutton.which); + luax_setfieldstring(L, "button", Input::getJoyButtonName(e.jbutton.button)); + break; + + case EventType::JOYAXISMOTION: + luax_setfieldstring(L, "type", "JoyAxisMotion"); + luax_setfieldinteger(L, "which", e.jaxis.which); + luax_setfieldfstring(L, "axis", Input::getJoyAxisName(e.jaxis.axis)); + break; + + case EventType::JOYBALLMOTION: + case EventType::JOYHATMOTION: + + case EventType::JOYDEVICEADDED: + case EventType::JOYDEVICEREMOVED: + luax_setfieldfstring(L, "type", e.type == EventType::JOYDEVICEADDED ? "JoyDeviceAdded" : "JoyDeviceRemoved"); + luax_setfieldinteger(L, "which", e.jdevice.which); + break; + + //https://stackoverflow.com/questions/50022316/what-is-sdl-joystick-and-what-is-sdl-gamecontroller-what-are-the-relationships + case EventType::CONTROLLERBUTTONDOWN: + case EventType::CONTROLLERBUTTONUP: + + + case EventType::CONTROLLERAXISMOTION: + + + default: + /* ignore other events */ + luax_pop(L, 1); // pop table out + goto poll; + break; + } + luax_rawseti(L, -2, i++); } - luax_rawseti(L, -2, i++); + return 1; } - return 1; - } - static const luaL_Reg f[] = { - { "poll", l_event_poll }, - { 0, 0 } - }; + static const luaL_Reg f[] = { + { "poll", l_event_poll }, + { 0, 0 } + }; - /** - * load event module - */ - int luaopen_event(lua_State* L) - { - luax_newlib(L, f); - return 1; - } + /** + * load event module + */ + int luaopen_event(lua_State* L) + { + luax_newlib(L, f); + return 1; + } -} // lua -} // jin
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/filesystem/filesystem.cpp b/src/lua/modules/filesystem/filesystem.cpp index 55f4c06..7466ce8 100644 --- a/src/lua/modules/filesystem/filesystem.cpp +++ b/src/lua/modules/filesystem/filesystem.cpp @@ -2,136 +2,139 @@ #include "libjin/jin.h" #include <string> -using namespace jin::filesystem; +using namespace JinEngine::Filesystem; -namespace jin +namespace JinEngine { -namespace lua -{ - - static struct + namespace Lua { - Filesystem* fs; - } context; - static int l_init(lua_State* L) - { - context.fs = Filesystem::get(); - return 0; - } - - /** - * set current game root, like - * C:/jin/games/tank/ - */ - static int l_mount(lua_State* L) - { - const char* path = luax_checkstring(L, 1); - context.fs->mount(path); - return 0; - } - - /** - * - */ - static int l_isDir(lua_State *L) - { - const char* path = luax_checkstring(L, 1); - int r = context.fs->isDir(path); - luax_pushboolean(L, r); - return 1; - } - - /** - * - */ - static int l_exist(lua_State * L) - { - const char* path = luax_checkstring(L, 1); - int r = context.fs->exists(path); - luax_pushboolean(L, r); - return 1; - } + static struct + { + AssetDatabase* fs; + } context; - static int l_isdir(lua_State* L) - { - const char* path = luax_checkstring(L, 1); - int r = context.fs->isDir(path); - luax_pushboolean(L, r); - return 1; - } - - // load but dont run it - static int loadf(lua_State* L) - { - const char* filename = lua_tostring(L, -1); - Buffer bf; - context.fs->read(filename, &bf); - luax_loadbuffer(L, (const char*)bf.data, bf.size, filename); - return 1; - } - - static int loader(lua_State* L) - { - const char * filename = lua_tostring(L, -1); + static int l_init(lua_State* L) + { + context.fs = AssetDatabase::get(); + return 0; + } - std::string tmp(filename); - tmp += ".lua"; + static int l_mount(lua_State* L) + { + const char* path = luax_checkstring(L, 1); + context.fs->mount(path); + return 0; + } - int size = tmp.size(); + static int l_exist(lua_State * L) + { + const char* path = luax_checkstring(L, 1); + int r = context.fs->exists(path); + luax_pushboolean(L, r); + return 1; + } - for (int i = 0; i<size - 4; ++i) + static int l_isDir(lua_State* L) { - if (tmp[i] == '.') - { - tmp[i] = '/'; - } + const char* path = luax_checkstring(L, 1); + int r = context.fs->isDir(path); + luax_pushboolean(L, r); + return 1; } - if (context.fs->exists(tmp.c_str())) + static int l_isFile(lua_State* L) { - lua_pop(L, 1); - lua_pushstring(L, tmp.c_str()); - return loadf(L); + const char* path = luax_checkstring(L, 1); + int r = context.fs->isFile(path); + luax_pushboolean(L, r); + return 1; } - tmp = filename; - size = tmp.size(); - for (int i = 0; i<size; ++i) + static int loadbuffer(lua_State* L) { - if (tmp[i] == '.') - tmp[i] = '/'; + const char* filename = lua_tostring(L, -1); + Buffer bf; + context.fs->read(filename, bf); + luax_loadbuffer(L, (const char*)&bf, bf.size(), filename); + return 1; } - if (context.fs->isDir(tmp.c_str())) + static int loader(lua_State* L) { - tmp += "/init.lua"; + const char * filename = lua_tostring(L, -1); + + std::string tmp(filename); + tmp += ".lua"; + + int size = tmp.size(); + + for (int i = 0; i<size - 4; ++i) + { + if (tmp[i] == '.') + { + tmp[i] = '/'; + } + } + if (context.fs->exists(tmp.c_str())) { lua_pop(L, 1); lua_pushstring(L, tmp.c_str()); - return loadf(L); + return loadbuffer(L); + } + + tmp = filename; + size = tmp.size(); + for (int i = 0; i<size; ++i) + { + if (tmp[i] == '.') + tmp[i] = '/'; } - } - lua_pushfstring(L, "\n\tno file \"%s\" in jin game directories.\n", (tmp + ".lua").c_str()); - return 1; - } + if (context.fs->isDir(tmp.c_str())) + { + tmp += "/init.lua"; + if (context.fs->exists(tmp.c_str())) + { + lua_pop(L, 1); + lua_pushstring(L, tmp.c_str()); + return loadbuffer(L); + } + } - static const luaL_Reg f[] = { - { "init", l_init }, - { "mount", l_mount }, - { "isdir", l_isDir }, - { "exist", l_exist }, - { 0, 0 } - }; + lua_pushfstring(L, "\n\tno file \"%s\" in jin game directories.\n", (tmp + ".lua").c_str()); + return 1; + } - int luaopen_filesystem(lua_State* L) - { - luax_newlib(L, f); - luax_register_searcher(L, loader, 1); - return 0; - } + static int l_read(lua_State* L) + { + AssetDatabase* fs = context.fs; + const char* file = luax_checkstring(L, 1); + unsigned int len; + Buffer buffer; + fs->read(file, buffer); + luax_pushstring(L, (char*)&buffer); + luax_pushinteger(L, buffer.size()); + return 2; + } + + static const luaL_Reg f[] = { + { "init", l_init }, + { "mount", l_mount }, + { "isDirectory", l_isDir }, + { "isFile", l_isFile }, + { "exist", l_exist }, + { "read", l_read }, + { 0, 0 } + }; + + int luaopen_filesystem(lua_State* L) + { + luax_newlib(L, f); + luax_registersearcher(L, loader, 1); + return 0; + } -} -}
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/bitmap.cpp b/src/lua/modules/graphics/bitmap.cpp new file mode 100644 index 0000000..13517f9 --- /dev/null +++ b/src/lua/modules/graphics/bitmap.cpp @@ -0,0 +1,113 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + typedef Ref<Bitmap>& BitmapRef; + + static inline BitmapRef checkBitmap(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_BITMAP); + return proxy->getRef<Bitmap>(); + } + + static int l_gc(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + ref.release(); + return 0; + } + + static int l_getWidth(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + int w = ref->getWidth(); + luax_pushinteger(L, w); + return 1; + } + + static int l_getHeight(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + int h = ref->getHeight(); + luax_pushinteger(L, h); + return 1; + } + + static int l_getSize(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + int w = ref->getWidth(); + int h = ref->getHeight(); + luax_pushinteger(L, w); + luax_pushinteger(L, h); + return 2; + } + + static int l_getPixel(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + int x = luax_checkinteger(L, 2); + int y = luax_checkinteger(L, 3); + Color col = ref->getPixel(x, y); + luax_pushinteger(L, col.r); + luax_pushinteger(L, col.g); + luax_pushinteger(L, col.b); + luax_pushinteger(L, col.a); + return 4; + } + + static int l_setPixel(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + int x = luax_checkinteger(L, 2); + int y = luax_checkinteger(L, 3); + if (!luax_istable(L, 4)) + { + luax_typerror(L, 4, "table"); + return 1; + } + unsigned int r = luax_rawgetnumber(L, 4, 1); + unsigned int g = luax_rawgetnumber(L, 4, 2); + unsigned int b = luax_rawgetnumber(L, 4, 3); + unsigned int a = luax_rawgetnumber(L, 4, 4); + ref->setPixel(Color(r, g, b, a), x, y); + return 0; + } + + static int l_clone(lua_State* L) + { + BitmapRef ref = checkBitmap(L); + Bitmap* bitmap = ref.getObject(); + Bitmap* b = Bitmap::clone(bitmap); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_BITMAP, sizeof(Proxy)); + proxy->bind(new Ref<Bitmap>(b, JIN_GRAPHICS_BITMAP)); + return 1; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "getSize", l_getSize }, + { "getPixel", l_getPixel }, + { "setPixel", l_setPixel }, + { "clone", l_clone }, + { 0, 0 } + }; + + int luaopen_Bitmap(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_BITMAP, f); + return 0; + } + + } // graphics +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/canvas.cpp b/src/lua/modules/graphics/canvas.cpp index f42dfba..e49e209 100644 --- a/src/lua/modules/graphics/canvas.cpp +++ b/src/lua/modules/graphics/canvas.cpp @@ -3,73 +3,63 @@ #include "lua/common/common.h" #include "libjin/jin.h" -namespace jin -{ -namespace lua +namespace JinEngine { + namespace Lua + { - using namespace jin::graphics; + using namespace JinEngine::Graphics; - typedef Ref<Canvas>& CanvasRef; + typedef Ref<Canvas>& CanvasRef; - static inline CanvasRef checkCanvas(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); - return proxy->getRef<Canvas>(); - } - - static int l_getWidth(lua_State* L) - { - CanvasRef ref = checkCanvas(L); - luax_pushnumber(L, ref->getWidth()); - return 1; - } + static inline CanvasRef checkCanvas(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + return proxy->getRef<Canvas>(); + } - static int l_getHeight(lua_State* L) - { - CanvasRef ref = checkCanvas(L); - luax_pushnumber(L, ref->getHeight()); - return 1; - } + static int l_getWidth(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + luax_pushnumber(L, ref->getWidth()); + return 1; + } - static int l_getSize(lua_State* L) - { - CanvasRef ref = checkCanvas(L); - luax_pushnumber(L, ref->getWidth()); - luax_pushnumber(L, ref->getHeight()); - return 2; - } + static int l_getHeight(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + luax_pushnumber(L, ref->getHeight()); + return 1; + } - static int l_setAnchor(lua_State* L) - { - CanvasRef ref = checkCanvas(L); - int x = luax_checknumber(L, 1); - int y = luax_checknumber(L, 2); - ref->setAnchor(x, y); - return 0; - } + static int l_getSize(lua_State* L) + { + CanvasRef ref = checkCanvas(L); + luax_pushnumber(L, ref->getWidth()); + luax_pushnumber(L, ref->getHeight()); + return 2; + } - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); - proxy->release(); - return 0; - } + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + proxy->release(); + return 0; + } - static const luaL_Reg f[] = { - { "__gc", l_gc }, - { "getWidth", l_getWidth }, - { "getHeight", l_getHeight }, - { "getSize", l_getSize }, - { "setAnchor", l_setAnchor }, - { 0, 0 } - }; + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "getSize", l_getSize }, + { 0, 0 } + }; - int luaopen_Canvas(lua_State* L) - { - luax_newtype(L, JIN_GRAPHICS_CANVAS, f); - return 0; - } + int luaopen_Canvas(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_CANVAS, f); + return 0; + } -}// lua -}// jin
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/font.cpp b/src/lua/modules/graphics/font.cpp deleted file mode 100644 index 926f2cc..0000000 --- a/src/lua/modules/graphics/font.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "lua/modules/luax.h" -#include "lua/modules/types.h" -#include "lua/common/common.h" -#include "libjin/jin.h" - -namespace jin -{ -namespace lua -{ - - using namespace jin::graphics; - - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_FONT); - proxy->release(); - return 0; - } - - static int l_box(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_FONT, sizeof(Proxy)); - Ref<Font>& ref = proxy->getRef<Font>(); - const char* text = luax_checkstring(L, 2); - int fheight = luax_checknumber(L, 3); - int spacing = luax_checknumber(L, 4); - int lheight = luax_checknumber(L, 5); - int w, h; - ref->box(text, fheight, lheight, spacing, &w, &h); - luax_pushnumber(L, w); - luax_pushnumber(L, h); - return 2; - } - - static const luaL_Reg f[] = { - { "__gc", l_gc }, - { "box", l_box }, - { 0, 0 } - }; - - int luaopen_Font(lua_State* L) - { - luax_newtype(L, JIN_GRAPHICS_FONT, f); - - return 0; - } - -} // lua -} // jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/graphics.cpp b/src/lua/modules/graphics/graphics.cpp index 9c1d404..8b2d7cd 100644 --- a/src/lua/modules/graphics/graphics.cpp +++ b/src/lua/modules/graphics/graphics.cpp @@ -1,516 +1,819 @@ +#include <iostream> +#include <fstream> + +#include "libjin/jin.h" #include "lua/modules/luax.h" #include "lua/modules/types.h" -#include "libjin/jin.h" #include "lua/common/common.h" -#include "lua/modules/embed/graphics.lua.h" -namespace jin -{ -namespace lua -{ - using namespace jin::graphics; - using jin::filesystem::Filesystem; - using jin::filesystem::Buffer; - - typedef Texture Image; +using namespace std; +using namespace JinEngine; +using namespace JinEngine::Graphics; +using JinEngine::Filesystem::AssetDatabase; +using JinEngine::Filesystem::Buffer; - static struct +namespace JinEngine +{ + namespace Lua { - color curRenderColor; - color curClearColor; - Font* curFont = nullptr; - Font* defaultFont = nullptr; - } context; - static int l_init(lua_State* L) - { - Window* wnd = Window::get(); - Window::Setting setting; - setting.width = luax_getfield_integer(L, 1, "width"); - setting.height = luax_getfield_integer(L, 1, "height"); - setting.title = luax_getfield_string(L, 1, "title"); - setting.vsync = luax_getfield_bool(L, 1, "vsync"); - setting.fullscreen = luax_getfield_bool(L, 1, "fullscreen"); - setting.resizable= luax_getfield_bool(L, 1, "resizable"); - if (!wnd->init(&setting)) - { - luax_pushboolean(L, false); - return 1; - } - luax_pushboolean(L, true); - return 1; - } +#include "../../resources/font.ttf.h" - static int l_destroy(lua_State* L) - { - Window* wnd = Window::get(); - wnd->quit(); - return 0; - } - - static int l_getSize(lua_State* L) - { - Window* wnd = Window::get(); - luax_pushnumber(L, wnd->getW()); - luax_pushnumber(L, wnd->getH()); - return 2; - } + static struct + { + Color curRenderColor; + Color curClearColor; + Font* curFont = nullptr; + Font* defaultFont = nullptr; + } context; - static int l_getWidth(lua_State* L) - { - Window* wnd = Window::get(); - luax_pushnumber(L, wnd->getW()); - return 1; - } + static int l_init(lua_State* L) + { + Window* wnd = Window::get(); + Window::Setting setting; + setting.width = luax_getfieldinteger(L, 1, "width"); + setting.height = luax_getfieldinteger(L, 1, "height"); + setting.title = luax_getfieldstring(L, 1, "title"); + setting.vsync = luax_getfieldbool(L, 1, "vsync"); + setting.fullscreen = luax_getfieldbool(L, 1, "fullscreen"); + setting.resizable = luax_getfieldbool(L, 1, "resizable"); + if (!wnd->init(&setting)) + { + luax_pushboolean(L, false); + return 1; + } + { + /* load default font */ + Bitmap* bitmap = Bitmap::createBitmap(default_font_bitmap, sizeof(default_font_bitmap)); + const Color* pixels = bitmap->getPixels(); + ofstream f = ofstream(); + f.open("font.pixels", ios_base::app); + for (int y = 0; y < bitmap->getHeight(); ++y) + { + for (int x = 0; x < bitmap->getWidth(); ++x) + { + Color c = pixels[x + y * bitmap->getWidth()]; + f << (int)c.r << ","; + f << (int)c.g << ","; + f << (int)c.b << ","; + f << (int)c.a << ","; + } + } + + TextureFont* tf = TextureFont::createTextureFont(bitmap, Text(Encode::UTF8, default_charset), default_font_split, bitmap->getHeight()); + context.defaultFont = tf; + delete bitmap; + } + context.curFont = context.defaultFont; - static int l_getHeight(lua_State* L) - { - Window* wnd = Window::get(); - luax_pushnumber(L, wnd->getH()); - return 1; - } + luax_pushboolean(L, true); + return 1; + } - static int l_newImage(lua_State* L) - { - Filesystem* fs = Filesystem::get(); - const char* f = luax_checkstring(L, 1); - if (!fs->exists(f)) + static int l_setTitle(lua_State* L) { - printf("Error: no such image %s\n", f); - exit(1); + Window* wnd = Window::get(); + const char* title = luax_checkstring(L, 1); + wnd->setTitle(title); + return 0; } - Buffer b; - fs->read(f, &b); - - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_IMAGE, sizeof(Proxy)); - Image* img = Image::createTexture(b.data, b.size); - proxy->bind(new Ref<Image>(img, JIN_GRAPHICS_IMAGE)); - return 1; - } - static int l_newShader(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_SHADER, sizeof(Proxy)); - const char* program = luax_checkstring(L, 1); - JSLProgram* jsl = JSLProgram::createJSLProgram(program); - proxy->bind(new Ref<JSLProgram>(jsl, JIN_GRAPHICS_SHADER)); - return 1; - } - - static int l_newCanvas(lua_State* L) - { - int w = luax_checknumber(L, 1); - int h = luax_checknumber(L, 2); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_CANVAS, sizeof(Proxy)); - Canvas* cvs = Canvas::createCanvas(w, h); - proxy->bind(new Ref<Canvas>(cvs, JIN_GRAPHICS_CANVAS)); - return 1; - } - - static int l_clear(lua_State* L) - { - if (luax_gettop(L) == 0) - { - glClearColor(0, 0, 0, 1); - } - else - { - int r = luax_checknumber(L, 1); - int g = luax_checknumber(L, 2); - int b = luax_checknumber(L, 3); - int a = luax_checknumber(L, 4); - glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); - } - glClear(GL_COLOR_BUFFER_BIT); - return 0; - } - - static int l_setClearColor(lua_State* L) - { - if (luax_gettop(L) == 0) - { - glClearColor(1, 1, 1, 1); - return 0; - } - - context.curClearColor.rgba.r = luax_checknumber(L, 1); - context.curClearColor.rgba.g = luax_checknumber(L, 2); - context.curClearColor.rgba.b = luax_checknumber(L, 3); - context.curClearColor.rgba.a = luax_checknumber(L, 4); - - glClearColor(context.curClearColor.rgba.r / 255.f, - context.curClearColor.rgba.g / 255.f, - context.curClearColor.rgba.b / 255.f, - context.curClearColor.rgba.a / 255.f); - return 0; - } - - static int l_present(lua_State* L) - { - Window::get()->swapBuffers(); - return 0; - } + static int l_destroy(lua_State* L) + { + Window* wnd = Window::get(); + wnd->quit(); + return 0; + } - static int l_draw(lua_State* L) - { - int x = luax_optnumber(L, 2, 0); - int y = luax_optnumber(L, 3, 0); - float sx = luax_optnumber(L, 4, 1); - float sy = luax_optnumber(L, 5, 1); - float r = luax_optnumber(L, 6, 0); - if (luax_istype(L, 1, JIN_GRAPHICS_IMAGE)) + static int l_getSize(lua_State* L) { - Proxy* proxy = (Proxy*)luax_toudata(L, 1); - Ref<Image>& tex = proxy->getRef<Image>(); - tex->draw(x, y, sx, sy, r); + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + luax_pushnumber(L, wnd->getH()); + return 2; } - else if (luax_istype(L, 1, JIN_GRAPHICS_CANVAS)) + + static int l_getWidth(lua_State* L) { - Proxy* proxy = (Proxy*)luax_toudata(L, 1); - Ref<Canvas>& p = proxy->getRef<Canvas>(); - p->draw(x, y, sx, sy, r); + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + return 1; } - else + + static int l_getHeight(lua_State* L) { - /* wrong type */ - luax_typerror(L, 1, "image or canvas"); + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getH()); + return 1; } - return 0; - } - static int l_setColor(lua_State* L) - { - if (luax_gettop(L) == 0) + static int l_newBitmap(lua_State* L) { - glColor4f(1, 1, 1, 1); - return 0; + Bitmap* bitmap = nullptr; + if (luax_gettop(L) == 2) + { + int w = luax_checkinteger(L, 1); + int h = luax_checkinteger(L, 2); + bitmap = Bitmap::createBitmap(w, h); + } + else if (luax_gettop(L) == 3) + { + int w = luax_checkinteger(L, 1); + int h = luax_checkinteger(L, 2); + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + unsigned int r = luax_rawgetnumber(L, 3, 1); + unsigned int g = luax_rawgetnumber(L, 3, 2); + unsigned int b = luax_rawgetnumber(L, 3, 3); + unsigned int a = luax_rawgetnumber(L, 3, 4); + bitmap = Bitmap::createBitmap(w, h, Color(r, g, b, a)); + } + else + { + const char* f = luax_checkstring(L, 1); + AssetDatabase* fs = AssetDatabase::get(); + if (!fs->exists(f)) + { + error(L, "No such image file %s", f); + goto fail; + } + Buffer b; + if (!fs->read(f, b)) + { + error(L, "Failed to read image %s", f); + goto fail; + } + bitmap = Bitmap::createBitmap(&b, b.size()); + if (bitmap == nullptr) + { + error(L, "Failed to decode image file %s", f); + goto fail; + } + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_BITMAP, sizeof(Proxy)); + proxy->bind(new Ref<Bitmap>(bitmap, JIN_GRAPHICS_BITMAP)); + return 1; + fail: + luax_pushnil(L); + return 1; } - context.curRenderColor.rgba.r = luax_checknumber(L, 1); - context.curRenderColor.rgba.g = luax_checknumber(L, 2); - context.curRenderColor.rgba.b = luax_checknumber(L, 3); - context.curRenderColor.rgba.a = luax_checknumber(L, 4); + /* jin.graphics.newTexture(bitmap) */ + static int l_newTexture(lua_State* L) + { + Texture* texture = nullptr; + if (luax_istype(L, 1, JIN_GRAPHICS_BITMAP)) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_BITMAP); + Ref<Bitmap>& refBitmap = p->getRef<Bitmap>(); + Bitmap* bitmap = refBitmap.getObject(); + texture = Texture::createTexture(bitmap); + } + else if (luax_isstring(L, 1)) + { + const char* path = luax_checkstring(L, 1); + texture = Texture::createTexture(path); + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_TEXTURE, sizeof(Proxy)); + proxy->bind(new Ref<Texture>(texture, JIN_GRAPHICS_TEXTURE)); + return 1; + } - glColor4f(context.curRenderColor.rgba.r / 255.f, - context.curRenderColor.rgba.g / 255.f, - context.curRenderColor.rgba.b / 255.f, - context.curRenderColor.rgba.a / 255.f); - return 0; - } + static int l_newShader(lua_State* L) + { + const char* program = luax_checkstring(L, 1); + Shader* jsl = Shader::createShader(program); + if (jsl == nullptr) + { + error(L, "Failed to compile shader"); + luax_pushnil(L); + return 1; + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_SHADER, sizeof(Proxy)); + proxy->bind(new Ref<Shader>(jsl, JIN_GRAPHICS_SHADER)); + return 1; + } - static int l_getColor(lua_State * L) - { - luax_pushnumber(L, context.curRenderColor.rgba.r); - luax_pushnumber(L, context.curRenderColor.rgba.g); - luax_pushnumber(L, context.curRenderColor.rgba.b); - luax_pushnumber(L, context.curRenderColor.rgba.a); - return 4; - } + static int l_newShaderf(lua_State* L) + { + const char* path = luax_checkstring(L, 1); + AssetDatabase* fs = AssetDatabase::get(); + if (!fs->exists(path)) + { + error(L, "No such shader file %s\n", path); + luax_pushnil(L); + return 1; + } + Buffer b; + fs->read(path, b); + Shader* jsl = Shader::createShader((char*)&b); + if (jsl == nullptr) + { + error(L, "Failed to compile shader"); + luax_pushnil(L); + return 1; + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_SHADER, sizeof(Proxy)); + proxy->bind(new Ref<Shader>(jsl, JIN_GRAPHICS_SHADER)); + return 1; + } + + static int l_newCanvas(lua_State* L) + { + int w = luax_checknumber(L, 1); + int h = luax_checknumber(L, 2); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_CANVAS, sizeof(Proxy)); + Canvas* cvs = Canvas::createCanvas(w, h); + proxy->bind(new Ref<Canvas>(cvs, JIN_GRAPHICS_CANVAS)); + return 1; + } - static int l_bindCanvas(lua_State* L) - { - if (luax_gettop(L) == 0) + static int l_clear(lua_State* L) { - // bind to default canvas - Canvas::unbind(); + glClear(GL_COLOR_BUFFER_BIT); return 0; } - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); - Ref<Canvas>& ref = proxy->getRef<Canvas>(); - ref->bind(); - return 0; - } - - static int l_unbindCanvas(lua_State* L) - { - Canvas::unbind(); - return 0; - } - static int l_useShader(lua_State* L) - { - if (luax_gettop(L) == 0) + static int l_setClearColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glClearColor(0, 0, 0, 1); + return 0; + } + + context.curClearColor.r = luax_checknumber(L, 1); + context.curClearColor.g = luax_checknumber(L, 2); + context.curClearColor.b = luax_checknumber(L, 3); + context.curClearColor.a = luax_checknumber(L, 4); + + gl.setClearColor(context.curClearColor.r, + context.curClearColor.g, + context.curClearColor.b, + context.curClearColor.a); + return 0; + } + + static int l_present(lua_State* L) { - JSLProgram::unuse(); + Window::get()->swapBuffers(); return 0; } - if (luax_istype(L, 1, JIN_GRAPHICS_SHADER)) + + static void l_draw_texture(lua_State* L) + { + if (!luax_istype(L, 1, JIN_GRAPHICS_TEXTURE)) + return; + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + float sx = luax_optnumber(L, 4, 1); + float sy = luax_optnumber(L, 5, 1); + float r = luax_optnumber(L, 6, 0); + float ox = luax_optnumber(L, 7, 0); + float oy = luax_optnumber(L, 8, 0); + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Texture>& tex = proxy->getRef<Texture>(); + tex->draw(x, y, sx, sy, r, ox, oy); + } + + static void l_draw_canvas(lua_State* L) + { + if (!luax_istype(L, 1, JIN_GRAPHICS_CANVAS)) + return; + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + float sx = luax_optnumber(L, 4, 1); + float sy = luax_optnumber(L, 5, 1); + float r = luax_optnumber(L, 6, 0); + float ox = luax_optnumber(L, 7, 0); + float oy = luax_optnumber(L, 8, 0); + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Canvas>& p = proxy->getRef<Canvas>(); + p->draw(x, y, sx, sy, r, ox, oy); + } + + /* jin.graphics.draw(text, font, x, y) */ + static void l_draw_text(lua_State* L) + { + if (!luax_istype(L, 1, JIN_GRAPHICS_TEXT)) + return; + Proxy* p = (Proxy*)luax_toudata(L, 1); + Text* text = p->getObject<Text>(); + int x = luax_optnumber(L, 3, 0); + int y = luax_optnumber(L, 4, 0); + int spacing = luax_optnumber(L, 6, 0); + Font* font = nullptr; + Proxy* p2 = (Proxy*)luax_toudata(L, 2); + if (luax_istype(L, 2, JIN_GRAPHICS_TEXTUREFONT)) + { + TextureFont* tf = p2->getObject<TextureFont>(); + font = tf; + } + else if (luax_istype(L, 2, JIN_GRAPHICS_TTF)) + { + TTF* ttf = p2->getObject<TTF>(); + font = ttf; + } + else + { + font = context.defaultFont; + } + int lineheight = luax_optnumber(L, 5, font->getFontSize()); + font->print(*text, x, y, lineheight, spacing); + } + + /* jin.graphics.draw(page, x, y) */ + static void l_draw_page(lua_State* L) + { + if (!luax_istype(L, 1, JIN_GRAPHICS_PAGE)) + return; + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + Proxy* p = (Proxy*)luax_toudata(L, 1); + Page* page = p->getObject<Page>(); + Font* font = page->font; + font->print(page, x, y); + } + + static int l_draw(lua_State* L) { - Proxy* proxy = (Proxy*)luax_toudata(L, 1); - Ref<JSLProgram>& jsl = proxy->getRef<JSLProgram>(); - jsl->use(); + if (luax_istype(L, 1, JIN_GRAPHICS_TEXTURE)) + l_draw_texture(L); + else if (luax_istype(L, 1, JIN_GRAPHICS_CANVAS)) + l_draw_canvas(L); + else if (luax_istype(L, 1, JIN_GRAPHICS_TEXT)) + l_draw_text(L); + else if (luax_istype(L, 1, JIN_GRAPHICS_PAGE)) + l_draw_page(L); + else + { + luax_typerror(L, 1, "texture or canvas"); + return 1; + } + return 0; } - else + + // draw(tex, quad, x, y, sx, sy, r, ax, ay) + static int l_drawq(lua_State* L) { - luax_typerror(L, 1, "JSL shader"); + if (!luax_istable(L, 2)) + { + luax_typerror(L, 2, "table"); + return 1; + } + Math::Quad q; + q.x = luax_rawgetnumber(L, 2, 1); + q.y = luax_rawgetnumber(L, 2, 2); + q.w = luax_rawgetnumber(L, 2, 3); + q.h = luax_rawgetnumber(L, 2, 4); + luax_pop(L, 4); + int x = luax_optnumber(L, 3, 0); + int y = luax_optnumber(L, 4, 0); + float sx = luax_optnumber(L, 5, 1); + float sy = luax_optnumber(L, 6, 1); + float r = luax_optnumber(L, 7, 0); + float ox = luax_optnumber(L, 8, 0); + float oy = luax_optnumber(L, 9, 0); + + if (luax_istype(L, 1, JIN_GRAPHICS_TEXTURE)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Texture>& tex = proxy->getRef<Texture>(); + tex->draw(q, x, y, sx, sy, r, ox, oy); + } + else if (luax_istype(L, 1, JIN_GRAPHICS_CANVAS)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Canvas>& p = proxy->getRef<Canvas>(); + p->draw(q, x, y, sx, sy, r, ox, oy); + } + else + { + luax_typerror(L, 1, "texture or canvas"); + } } - return 0; - } - - static int l_unuseShader(lua_State* L) - { - JSLProgram::unuse(); - return 0; - } - static int l_setBlend(lua_State* L) - { - - return 0; - } + /* print(string, x, y, lineheight, spacing) */ + /* need set font */ + static int l_print(lua_State* L) + { + Font* font = context.curFont; + if (font == nullptr) + return 0; + unsigned length; + const char* str = luax_checklstring(L, 1, &length); + Text text(Encode::UTF8, str, length); + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + int lineheight = luax_optnumber(L, 4, font->getFontSize()); + int spacing = luax_optnumber(L, 5, 0); + font->print(text, x, y, lineheight, spacing); + return 0; + } - static RENDER_MODE strtomode(const char* str) - { - std::string s = std::string(str); - if (s == "fill") return RENDER_MODE::FILL; - else if (s == "line") return RENDER_MODE::LINE; - else return RENDER_MODE::NONE; - } + static int l_setColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glColor4f(1, 1, 1, 1); + return 0; + } - static int l_drawpoint(lua_State* L) - { - int x = luax_checknumber(L, 1); - int y = luax_checknumber(L, 2); - jin::graphics::point(x, y); - - return 0; - } - - static int l_drawLine(lua_State* L) - { - int x1 = luax_checknumber(L, 1); - int y1 = luax_checknumber(L, 2); - int x2 = luax_checknumber(L, 3); - int y2 = luax_checknumber(L, 4); - jin::graphics::line(x1, y1, x2, y2); - - return 0; - } + context.curRenderColor.r = luax_checknumber(L, 1); + context.curRenderColor.g = luax_checknumber(L, 2); + context.curRenderColor.b = luax_checknumber(L, 3); + if (luax_gettop(L) == 4) + context.curRenderColor.a = luax_checknumber(L, 4); + else + context.curRenderColor.a = 255; + glColor4f(context.curRenderColor.r / 255.f, + context.curRenderColor.g / 255.f, + context.curRenderColor.b / 255.f, + context.curRenderColor.a / 255.f); + return 0; + } - static int l_drawRect(lua_State* L) - { - const char* modestr = luax_checkstring(L, 1); - RENDER_MODE mode = strtomode(modestr); - if (mode != RENDER_MODE::NONE) + static int l_getColor(lua_State * L) { - int x = luax_checknumber(L, 2); - int y = luax_checknumber(L, 3); - int w = luax_checknumber(L, 4); - int h = luax_checknumber(L, 5); - rect(mode, x, y, w, h); + luax_pushnumber(L, context.curRenderColor.r); + luax_pushnumber(L, context.curRenderColor.g); + luax_pushnumber(L, context.curRenderColor.b); + luax_pushnumber(L, context.curRenderColor.a); + return 4; } - else + + static int l_bindCanvas(lua_State* L) { - luax_typerror(L, 1, "'fill' or 'line'"); - return 1; + if (luax_gettop(L) == 0) + { + // bind to default canvas + Canvas::unbind(); + return 0; + } + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + Ref<Canvas>& ref = proxy->getRef<Canvas>(); + Canvas::bind(ref.getObject()); + return 0; } - return 0; - } + static int l_unbindCanvas(lua_State* L) + { + Canvas::unbind(); + return 0; + } - static int l_drawCircle(lua_State* L) - { - const char* modestr = luax_checkstring(L, 1); - RENDER_MODE mode = strtomode(modestr); - if (mode != RENDER_MODE::NONE) + static int l_useShader(lua_State* L) { - int x = luax_checknumber(L, 2); - int y = luax_checknumber(L, 3); - float r = luax_checknumber(L, 4); - circle(mode, x, y, r); + if (luax_gettop(L) == 0) + { + Shader::unuse(); + return 0; + } + if (luax_istype(L, 1, JIN_GRAPHICS_SHADER)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Shader>& jsl = proxy->getRef<Shader>(); + jsl->use(); + } + else + { + luax_typerror(L, 1, "JSL shader"); + } + return 0; } - else + + static int l_setBlend(lua_State* L) { - luax_typerror(L, 1, "'fill' or 'line'"); - return 1; + + return 0; } - return 0; - } + static RenderMode strtomode(const char* str) + { + std::string s = std::string(str); + if (s == "fill") return RenderMode::FILL; + else if (s == "line") return RenderMode::LINE; + else return RenderMode::NONE; + } - static int l_drawTriangle(lua_State* L) - { - const char* modestr = luax_checkstring(L, 1); - RENDER_MODE mode = strtomode(modestr); - if (mode != RENDER_MODE::NONE) + static int l_point(lua_State* L) { - int x = luax_checknumber(L, 2); - int y = luax_checknumber(L, 3); + int x = luax_checknumber(L, 1); + int y = luax_checknumber(L, 2); + JinEngine::Graphics::point(x, y); + return 0; + } + + static int l_line(lua_State* L) + { + int x1 = luax_checknumber(L, 1); + int y1 = luax_checknumber(L, 2); int x2 = luax_checknumber(L, 3); int y2 = luax_checknumber(L, 4); + JinEngine::Graphics::line(x1, y1, x2, y2); + + return 0; + } - int x3 = luax_checknumber(L, 5); - int y3 = luax_checknumber(L, 6); + static int l_rect(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RenderMode mode = strtomode(modestr); + if (mode != RenderMode::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + int w = luax_checknumber(L, 4); + int h = luax_checknumber(L, 5); + rect(mode, x, y, w, h); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } - triangle(mode, x, y, x2, y2, x3, y3); + return 0; } - else + + static int l_circle(lua_State* L) { - luax_typerror(L, 1, "'fill' or 'line'"); - return 1; + const char* modestr = luax_checkstring(L, 1); + RenderMode mode = strtomode(modestr); + if (mode != RenderMode::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + float r = luax_checknumber(L, 4); + circle(mode, x, y, r); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; } - return 0; - } - - static int l_drawPolygon(lua_State* L) - { - const char* modestr = luax_checkstring(L, 1); - int n = luax_checknumber(L, 2); - RENDER_MODE mode = strtomode(modestr); - if (mode != RENDER_MODE::NONE) + static int l_triangle(lua_State* L) { - if (!luax_istable(L, 3)) + const char* modestr = luax_checkstring(L, 1); + RenderMode mode = strtomode(modestr); + if (mode != RenderMode::NONE) { - luax_typerror(L, 3, "table"); - return 1; + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + + int x2 = luax_checknumber(L, 3); + int y2 = luax_checknumber(L, 4); + + int x3 = luax_checknumber(L, 5); + int y3 = luax_checknumber(L, 6); + + triangle(mode, x, y, x2, y2, x3, y3); } - int tn = luax_tableidxlen(L, 3); - if (tn != n * 2) + else { - static char* emsg = \ - "number of polygon vertices doesn't match " \ - "provided n, expect %d numbers but get %d"; - luax_error(L, emsg, n * 2, tn); + luax_typerror(L, 1, "'fill' or 'line'"); return 1; } - float* p = new float[2 * n]; - for (int i = 1; i <= 2 * n; ++i) - p[i - 1] = luax_rawgetnumber(L, 3, i); - polygon(mode, p, n); - delete[] p; + + return 0; } - else + + static int l_polygon(lua_State* L) { - luax_typerror(L, 1, "'fill' or 'line'"); - return 1; - } + const char* modestr = luax_checkstring(L, 1); + int n = luax_checknumber(L, 2); + RenderMode mode = strtomode(modestr); + if (mode != RenderMode::NONE) + { + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + int tn = luax_tableidxlen(L, 3); + if (tn != n * 2) + { + static char* emsg = \ + "number of polygon vertices doesn't match " \ + "provided n, expect %d numbers but get %d"; + luax_error(L, emsg, n * 2, tn); + return 1; + } + float* p = (float*)alloca(2 * n * sizeof(float)); + for (int i = 1; i <= 2 * n; ++i) + p[i - 1] = luax_rawgetnumber(L, 3, i); + polygon(mode, p, n); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } - return 0; - } + return 0; + } - static int l_newFont(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_FONT, sizeof(Proxy)); - Font* font = new Font(); + static int l_newTTFData(lua_State* L) { - const char* path = luax_checkstring(L, 1); - Filesystem* fs = Filesystem::get(); - Buffer b = {}; - if (!fs->exists(path)) + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_TTFDATA, sizeof(Proxy)); + TTFData* fd = nullptr; { - printf("Error: no such font %s\n", path); - exit(1); + const char* path = luax_checkstring(L, 1); + AssetDatabase* fs = AssetDatabase::get(); + if (!fs->exists(path)) + { + error(L, "No such font %s\n", path); + luax_pushnil(L); + return 1; + } + Buffer b; + fs->read(path, b); + fd = TTFData::createTTFData(&b, b.size()); } - fs->read(path, &b); - font->loadb((const unsigned char*)b.data); + proxy->bind(new Ref<TTFData>(fd, JIN_GRAPHICS_TTFDATA)); + return 1; } - proxy->bind(new Ref<Font>(font, JIN_GRAPHICS_FONT)); - return 1; - } - static int l_study(lua_State* L) - { - int n = luax_gettop(L); - if (n == 0) - { - if (context.defaultFont == 0) + /* newText(str[, encode]) */ + static int l_newText(lua_State* L) + { + Encode encode = Encode::UTF8; + if (luax_gettop(L) == 2) + { + const char* e = luax_checkstring(L, 2); + if (strcmp(e, "UTF8") == 0) encode = Encode::UTF8; + //else if (strcmp(e, "UTF16") == 0) encode = Encode::UTF16; + else if (strcmp(e, "ASCII") == 0) encode = Encode::ASCII; + else + { + luax_error(L, "wrong text encode %s", e); + return 0; + } + } + unsigned length; + const char* data = luax_checklstring(L, 1, &length); + Text* text = new Text(encode, data, length); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_TEXT, sizeof(Proxy)); + proxy->bind(new Ref<Text>(text, JIN_GRAPHICS_TEXT)); + return 1; + } + + /* newTextureFont(bitmap, text, color | cellw, cellh) */ + static int l_newTextureFont(lua_State* L) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_BITMAP); + Bitmap* bitmap = p->getObject<Bitmap>(); + Text* text; + if (luax_istype(L, 2, JIN_GRAPHICS_TEXT)) { - #include "lua/resources/font.ttf.h" - // load default font - context.defaultFont = new Font(); - context.defaultFont->loadb(font_ttf); + Proxy* pt = (Proxy*)luax_checktype(L, 2, JIN_GRAPHICS_TEXT); + text = pt->getObject<Text>(); } + else if (luax_isstring(L, 2)) + { + unsigned len; + const char* str = luax_checklstring(L, 2, &len); + text = new Text(Encode::UTF8, str, len); + } + else + { + luax_typerror(L, 2, "Text or string"); + return 1; + } + float cellh = luax_checknumber(L, 4); + TextureFont* textureFont = nullptr; + if (luax_istable(L, 3)) + { + unsigned int r = luax_rawgetnumber(L, 3, 1); + unsigned int g = luax_rawgetnumber(L, 3, 2); + unsigned int b = luax_rawgetnumber(L, 3, 3); + unsigned int a = luax_rawgetnumber(L, 3, 4); + textureFont = TextureFont::createTextureFont(bitmap, *text, Color(r, g, b, a), cellh); + } + else if (luax_isnumber(L, 3)) + { + float cellw = luax_checknumber(L, 3); + textureFont = TextureFont::createTextureFont(bitmap, *text, cellw, cellh); + } + else + { + luax_error(L, "bad arguments #3 to 'newTextureFont', need to be table or number"); + return 0; + } + if (luax_isstring(L, 2)) + { + // Delete temporary text. + delete text; + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_TEXTUREFONT, sizeof(Proxy)); + proxy->bind(new Ref<TextureFont>(textureFont, JIN_GRAPHICS_TEXTUREFONT)); + return 1; + } + + /* setFont(font) */ + static int l_setFont(lua_State* L) + { + if (luax_istype(L, 1, JIN_GRAPHICS_TTF)) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TTF); + TTF* ttf = p->getObject<TTF>(); + context.curFont = ttf; + } + else if (luax_istype(L, 1, JIN_GRAPHICS_TEXTUREFONT)) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TEXTUREFONT); + TextureFont* tf = p->getObject<TextureFont>(); + context.curFont = tf; + } + return 0; + } + + static int l_unsetFont(lua_State* L) + { context.curFont = context.defaultFont; return 0; } - Font* font = (Font*)luax_checktype(L, 1, JIN_GRAPHICS_FONT); - context.curFont = font; - return 0; - } - - static int l_write(lua_State* L) - { - if (context.curFont == 0) - return 0; - - const char* text = luax_checkstring(L, 1); - int x = luax_checknumber(L, 2); - int y = luax_checknumber(L, 3); - - int fh = luax_optnumber(L, 4, 15); - int spacing = luax_optnumber(L, 5, 1); - int lh = luax_optnumber(L, 6, 18); - - context.curFont->render(text, x, y, fh, spacing, lh); - return 0; - } - - static int l_box(lua_State* L) - { - const char* text = luax_checkstring(L, 1); - int fontheight = luax_checknumber(L, 2); - int spacing = luax_checknumber(L, 3); - int lineheight = luax_checknumber(L, 4); - int w, h; - context.curFont->box(text, fontheight, spacing, lineheight, &w, &h); - luax_pushnumber(L, w); - luax_pushnumber(L, h); - return 2; - } - - static const luaL_Reg f[] = { - { "init", l_init }, - { "getSize", l_getSize }, - { "getWidth", l_getWidth }, - { "getHeight", l_getHeight }, - { "newImage", l_newImage }, - { "newShader", l_newShader }, - { "newCanvas", l_newCanvas }, - { "newFont", l_newFont }, - { "box", l_box }, - { "write", l_write }, - { "setClearColor", l_setClearColor }, - { "clear", l_clear }, - { "draw", l_draw }, - { "setColor", l_setColor }, - { "palette", l_getColor }, - { "present", l_present }, - { "setFont", l_study }, - { "bindCanvas", l_bindCanvas }, - { "unbindCanvas", l_unbindCanvas }, - { "useShader", l_useShader }, - { "unuseShader", l_unuseShader }, - { "point", l_drawpoint }, - { "line", l_drawLine }, - { "rect", l_drawRect }, - { "circle", l_drawCircle }, - { "triangle", l_drawTriangle }, - { "polygon", l_drawPolygon }, - { "destroy", l_destroy }, - { 0, 0 } - }; - - extern int luaopen_Image(lua_State* L); - extern int luaopen_Font(lua_State* L); - extern int luaopen_Canvas(lua_State* L); - extern int luaopen_JSL(lua_State* L); + static const luaL_Reg f[] = { + /* window */ + { "init", l_init }, + { "setTitle", l_setTitle }, + { "getSize", l_getSize }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "destroy", l_destroy }, + /* creators */ + { "newBitmap", l_newBitmap }, + { "newTexture", l_newTexture }, + { "newShader", l_newShader }, + { "newShaderf", l_newShaderf }, + { "newCanvas", l_newCanvas }, + { "newTTFData", l_newTTFData }, + { "newText", l_newText }, + { "newTextureFont", l_newTextureFont }, + /* render */ + { "setClearColor", l_setClearColor }, + { "clear", l_clear }, + { "draw", l_draw }, + { "print", l_print }, + { "drawq", l_drawq }, + { "setColor", l_setColor }, + { "getColor", l_getColor }, + { "present", l_present }, + /* canvas */ + { "bindCanvas", l_bindCanvas }, + { "unbindCanvas", l_unbindCanvas }, + /* shader */ + { "useShader", l_useShader }, + /* shapes */ + { "point", l_point }, + { "line", l_line }, + { "rect", l_rect }, + { "circle", l_circle }, + { "triangle", l_triangle }, + { "polygon", l_polygon }, + /* font */ + { "setFont", l_setFont }, + { "unsetFont", l_unsetFont }, + { 0, 0 } + }; + + extern int luaopen_Texture(lua_State* L); + extern int luaopen_Text(lua_State* L); + extern int luaopen_TTF(lua_State* L); + extern int luaopen_TextureFont(lua_State* L); + extern int luaopen_TTFData(lua_State* L); + extern int luaopen_Page(lua_State* L); + extern int luaopen_Canvas(lua_State* L); + extern int luaopen_JSL(lua_State* L); + extern int luaopen_Bitmap(lua_State* L); - int luaopen_graphics(lua_State* L) - { - // register types - luaopen_Image(L); - luaopen_Canvas(L); - luaopen_Font(L); - luaopen_JSL(L); - - // load whole lib - luax_newlib(L, f); + int luaopen_graphics(lua_State* L) + { + // register types + luaopen_Bitmap(L); + luaopen_Texture(L); + luaopen_Canvas(L); + luaopen_TTFData(L); + luaopen_TTF(L); + luaopen_Text(L); + luaopen_TextureFont(L); + luaopen_Page(L); + luaopen_JSL(L); + + // load whole lib + luax_newlib(L, f); - return 1; - } + return 1; + } -}// lua -}// jin
\ No newline at end of file + }// lua +}// jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/image.cpp b/src/lua/modules/graphics/image.cpp deleted file mode 100644 index 5824660..0000000 --- a/src/lua/modules/graphics/image.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "lua/modules/luax.h" -#include "lua/modules/types.h" -#include "lua/common/common.h" -#include "libjin/jin.h" - -namespace jin -{ -namespace lua -{ - - using namespace jin::graphics; - - typedef Texture Image; - - static inline Ref<Image>& checkImage(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_IMAGE); - return proxy->getRef<Image>(); - } - - static int l_getWidth(lua_State* L) - { - Ref<Image>& ref = checkImage(L); - luax_pushnumber(L, ref->getWidth()); - return 1; - } - - static int l_getHeight(lua_State *L) - { - Ref<Image>& ref = checkImage(L); - luax_pushnumber(L, ref->getHeight()); - return 1; - } - - static int l_getPixel(lua_State* L) - { - Ref<Image>& ref = checkImage(L); - int x = luax_checknumber(L, 2); - int y = luax_checknumber(L, 3); - color c = ref->getPixel(x, y); - luax_pushnumber(L, c.rgba.r); - luax_pushnumber(L, c.rgba.g); - luax_pushnumber(L, c.rgba.b); - luax_pushnumber(L, c.rgba.a); - return 4; - } - - static int l_setAnchor(lua_State* L) - { - Ref<Image>& ref = checkImage(L); - int x = luax_checknumber(L, 2); - int y = luax_checknumber(L, 3); - ref->setAnchor(x, y); - return 0; - } - - static int l_getSize(lua_State* L) - { - Ref<Image>& ref = checkImage(L); - luax_pushnumber(L, ref->getWidth()); - luax_pushnumber(L, ref->getHeight()); - return 2; - } - - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_IMAGE); - proxy->release(); - return 0; - } - - static const luaL_Reg f[] = { - { "__gc", l_gc }, - { "getWidth", l_getWidth }, - { "getHeight", l_getHeight }, - { "getSize", l_getSize }, - { "getPixel", l_getPixel }, - { "setAnchor", l_setAnchor }, - { 0, 0 } - }; - - int luaopen_Image(lua_State* L) - { - luax_newtype(L, JIN_GRAPHICS_IMAGE, f); - return 0; - } - -}// graphics -}// jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/jsl.cpp b/src/lua/modules/graphics/jsl.cpp deleted file mode 100644 index ccd9ebd..0000000 --- a/src/lua/modules/graphics/jsl.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "lua/modules/luax.h" -#include "lua/modules/types.h" -#include "lua/common/common.h" -#include "libjin/jin.h" - -namespace jin -{ -namespace lua -{ - - using namespace jin::graphics; - - typedef Texture Image; - - static inline Ref<JSLProgram>& checkJSLProgram(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_SHADER); - return proxy->getRef<JSLProgram>(); - } - - static enum VARIABLE_TYPE - { - INVALID = 0, - - NUMBER, - IMAGE, - CANVAS, - VEC2, - VEC3, - VEC4, - COLOR, - }; - - static VARIABLE_TYPE strToType(const char* str) - { - std::string s = std::string(str); - if (s == "number") return NUMBER; - else if (s == "Image") return IMAGE; - else if (s == "Canvas") return CANVAS; - else if (s == "vec2") return VEC2; - else if (s == "vec3") return VEC3; - else if (s == "vec4") return VEC4; - else if (s == "Color") return COLOR; - else return INVALID; - } - - /** - * Use send function send variables to JSL program. - */ - static int l_send(lua_State* L) - { - Ref<JSLProgram>& ref = checkJSLProgram(L); - // number Image Texel - const char* typestr = luax_checkstring(L, 2); - // variable name - const char* variable = luax_checkstring(L, 3); - if (typestr != nullptr) - { - int type = strToType(typestr); - switch (type) - { - case NUMBER: - { - float number = luax_checknumber(L, 4); - ref->sendFloat(variable, number); - break; - } - case IMAGE: - { - Proxy* proxy = (Proxy*)luax_checktype(L, 4, JIN_GRAPHICS_IMAGE); - Ref<Image>& tex = proxy->getRef<Image>(); - ref->sendTexture(variable, tex.getObject()); - break; - } - case CANVAS: - { - Proxy* proxy = (Proxy*)luax_checktype(L, 4, JIN_GRAPHICS_CANVAS); - Ref<Canvas>& canvas = proxy->getRef<Canvas>(); - ref->sendCanvas(variable, canvas.getObject()); - break; - } - case VEC2: - { - float x = luax_checknumber(L, 4); - float y = luax_checknumber(L, 5); - ref->sendVec2(variable, x, y); - break; - } - case VEC3: - { - float x = luax_checknumber(L, 4); - float y = luax_checknumber(L, 5); - float z = luax_checknumber(L, 6); - ref->sendVec3(variable, x, y, z); - break; - } - case VEC4: - { - float x = luax_checknumber(L, 4); - float y = luax_checknumber(L, 5); - float z = luax_checknumber(L, 6); - float w = luax_checknumber(L, 7); - ref->sendVec4(variable, x, y, z, w); - break; - } - case COLOR: - { - color col; - col.rgba.r = luax_checkinteger(L, 4); - col.rgba.g = luax_checkinteger(L, 5); - col.rgba.b = luax_checkinteger(L, 6); - col.rgba.a = luax_checkinteger(L, 7); - ref->sendColor(variable, &col); - break; - } - default: - return 0; - } - } - return 1; - } - - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_SHADER); - proxy->release(); - return 0; - } - - static const luaL_Reg f[] = { - { "__gc", l_gc }, - { "send", l_send }, - { 0, 0 } - }; - - /** - * JSL program - */ - int luaopen_JSL(lua_State* L) - { - luax_newtype(L, JIN_GRAPHICS_SHADER, f); - return 0; - } - -} -}
\ No newline at end of file diff --git a/src/lua/modules/graphics/page.cpp b/src/lua/modules/graphics/page.cpp new file mode 100644 index 0000000..8c9e918 --- /dev/null +++ b/src/lua/modules/graphics/page.cpp @@ -0,0 +1,73 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +#include <iostream> + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + typedef Ref<Font>& FontRef; + + Page* getPage(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_PAGE); + return proxy->getObject<Page>(); + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_PAGE); + { + /* release font */ + Ref<Page>* page = &proxy->getRef<Page>(); + RefBase* font = (RefBase*)page->getUserdata(); + font->release(); + } + proxy->release(); + return 0; + } + + static int l_getSize(lua_State* L) + { + Page* page = getPage(L); + luax_pushinteger(L, page->size.w); + luax_pushinteger(L, page->size.h); + return 2; + } + + static int l_getWidth(lua_State* L) + { + Page* page = getPage(L); + luax_pushinteger(L, page->size.w); + return 1; + } + + static int l_getHeight(lua_State* L) + { + Page* page = getPage(L); + luax_pushinteger(L, page->size.h); + return 1; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "getSize", l_getSize }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { 0, 0 } + }; + + int luaopen_Page(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_PAGE, f); + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/shader.cpp b/src/lua/modules/graphics/shader.cpp new file mode 100644 index 0000000..d7733d4 --- /dev/null +++ b/src/lua/modules/graphics/shader.cpp @@ -0,0 +1,135 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + typedef Ref<Shader>& ShaderRef; + + static inline ShaderRef checkShader(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_SHADER); + return proxy->getRef<Shader>(); + } + + /** + * jsl:sendNumber("variable", 0.1) + */ + static int l_sendNumber (lua_State* L) + { + ShaderRef ref = checkShader(L); + const char* variable = luax_checkstring(L, 2); + float number = luax_checknumber(L, 3); + ref->sendFloat(variable, number); + return 0; + } + + static int l_sendTexture (lua_State* L) + { + ShaderRef ref = checkShader(L); + const char* variable = luax_checkstring(L, 2); + Proxy* proxy = (Proxy*)luax_checktype(L, 3, JIN_GRAPHICS_TEXTURE); + Ref<Texture>& tex = proxy->getRef<Texture>(); + ref->sendTexture(variable, tex.getObject()); + return 0; + } + + static int l_sendCanvas (lua_State* L) + { + ShaderRef ref = checkShader(L); + const char* variable = luax_checkstring(L, 2); + Proxy* proxy = (Proxy*)luax_checktype(L, 3, JIN_GRAPHICS_CANVAS); + Ref<Canvas>& canvas = proxy->getRef<Canvas>(); + ref->sendCanvas(variable, canvas.getObject()); + return 0; + } + + static int l_sendVec2 (lua_State* L) + { + ShaderRef ref = checkShader(L); + const char* variable = luax_checkstring(L, 2); + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + float x = luax_rawgetnumber(L, 3, 1); + float y = luax_rawgetnumber(L, 3, 2); + ref->sendVec2(variable, x, y); + return 0; + } + + static int l_sendVec3 (lua_State* L) + { + ShaderRef ref = checkShader(L); + const char* variable = luax_checkstring(L, 2); + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + float x = luax_rawgetnumber(L, 3, 1); + float y = luax_rawgetnumber(L, 3, 2); + float z = luax_rawgetnumber(L, 3, 3); + ref->sendVec3(variable, x, y, z); + return 0; + } + + static int l_sendVec4 (lua_State* L) + { + ShaderRef ref = checkShader(L); + const char* variable = luax_checkstring(L, 2); + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + float x = luax_rawgetnumber(L, 3, 1); + float y = luax_rawgetnumber(L, 3, 2); + float z = luax_rawgetnumber(L, 3, 3); + float w = luax_rawgetnumber(L, 3, 4); + ref->sendVec4(variable, x, y, z, w); + return 0; + } + + static int l_sendColor (lua_State* L) + { + return l_sendVec4(L); + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_SHADER); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "sendNumber", l_sendNumber }, + { "sendTexture", l_sendTexture }, + { "sendCanvas", l_sendCanvas }, + { "sendVec2", l_sendVec2 }, + { "sendVec3", l_sendVec3 }, + { "sendVec4", l_sendVec4 }, + { "sendColor", l_sendColor }, + { 0, 0 } + }; + + /** + * JSL program + */ + int luaopen_JSL(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_SHADER, f); + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/text.cpp b/src/lua/modules/graphics/text.cpp new file mode 100644 index 0000000..cbc82f1 --- /dev/null +++ b/src/lua/modules/graphics/text.cpp @@ -0,0 +1,32 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + static int l_gc(lua_State* L) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TEXT); + p->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { 0, 0 } + }; + + int luaopen_Text(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_TEXT, f); + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/texture.cpp b/src/lua/modules/graphics/texture.cpp new file mode 100644 index 0000000..61bfaee --- /dev/null +++ b/src/lua/modules/graphics/texture.cpp @@ -0,0 +1,65 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + typedef Ref<Texture>& TextureRef; + + static inline TextureRef checkTexture(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TEXTURE); + return proxy->getRef<Texture>(); + } + + static int l_getWidth(lua_State* L) + { + TextureRef ref = checkTexture(L); + luax_pushnumber(L, ref->getWidth()); + return 1; + } + + static int l_getHeight(lua_State *L) + { + TextureRef ref = checkTexture(L); + luax_pushnumber(L, ref->getHeight()); + return 1; + } + + static int l_getSize(lua_State* L) + { + TextureRef ref = checkTexture(L); + luax_pushnumber(L, ref->getWidth()); + luax_pushnumber(L, ref->getHeight()); + return 2; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TEXTURE); + proxy->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "getSize", l_getSize }, + { 0, 0 } + }; + + int luaopen_Texture(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_TEXTURE, f); + return 0; + } + + }// lua +}// jin
\ No newline at end of file diff --git a/src/lua/modules/graphics/texture_font.cpp b/src/lua/modules/graphics/texture_font.cpp new file mode 100644 index 0000000..a2e88ba --- /dev/null +++ b/src/lua/modules/graphics/texture_font.cpp @@ -0,0 +1,67 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TEXTUREFONT); + proxy->release(); + return 0; + } + + /* typeset(Text | string, lineheight, spacing) */ + static int l_typeset(lua_State* L) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TEXTUREFONT); + TextureFont* tf = p->getObject<TextureFont>(); + int lineheight = luax_checkinteger(L, 3); + int spacing = luax_optnumber(L, 4, 0); + Page* page = nullptr; + if (luax_isstring(L, 2)) + { + unsigned length; + const char* str = luax_checklstring(L, 2, &length); + Text text(Encode::UTF8, str, length); + page = tf->typeset(text, lineheight, spacing); + } + else if (luax_istype(L, 2, JIN_GRAPHICS_TEXT)) + { + Proxy* p2 = (Proxy*)luax_checktype(L, 2, JIN_GRAPHICS_TEXT); + Text* text = p2->getObject<Text>(); + page = tf->typeset(*text, lineheight, spacing); + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_PAGE, sizeof(Proxy)); + Ref<Page>* refPage = new Ref<Page>(page, JIN_GRAPHICS_PAGE); + { + /* retain related ttf */ + Ref<TextureFont>& refTF = p->getRef<TextureFont>(); + refTF.retain(); + refPage->setUserdata(&refTF); + } + proxy->bind(refPage); + return 1; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "typeset", l_typeset }, + { 0, 0 } + }; + + int luaopen_TextureFont(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_TEXTUREFONT, f); + + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/ttf.cpp b/src/lua/modules/graphics/ttf.cpp new file mode 100644 index 0000000..414c7eb --- /dev/null +++ b/src/lua/modules/graphics/ttf.cpp @@ -0,0 +1,73 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TTF); + { + /* release ttf data */ + Ref<TTF>* ttf = &proxy->getRef<TTF>(); + RefBase* data = (RefBase*)ttf->getUserdata(); + data->release(); + } + proxy->release(); + return 0; + } + + /* typeset(Text | string, lineheight, spacing) */ + static int l_typeset(lua_State* L) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TTF); + TTF* ttf = p->getObject<TTF>(); + int lineheight = luax_optnumber(L, 3, ttf->getFontSize()); + int spacing = luax_optnumber(L, 4, 0); + Page* page = nullptr; + if (luax_isstring(L, 2)) + { + unsigned length; + const char* str = luax_checklstring(L, 2, &length); + Text text(Encode::UTF8, str, length); + page = ttf->typeset(text, lineheight, spacing); + } + else if (luax_istype(L, 2, JIN_GRAPHICS_TEXT)) + { + Proxy* p2 = (Proxy*)luax_checktype(L, 2, JIN_GRAPHICS_TEXT); + Text* text = p2->getObject<Text>(); + page = ttf->typeset(*text, lineheight, spacing); + } + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_PAGE, sizeof(Proxy)); + Ref<Page>* refPage = new Ref<Page>(page, JIN_GRAPHICS_PAGE); + { + /* retain related ttf */ + Ref<TTF>& refTTF = p->getRef<TTF>(); + refTTF.retain(); + refPage->setUserdata(&refTTF); + } + proxy->bind(refPage); + return 1; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "typeset", l_typeset }, + { 0, 0 } + }; + + int luaopen_TTF(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_TTF, f); + + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/graphics/ttfData.cpp b/src/lua/modules/graphics/ttfData.cpp new file mode 100644 index 0000000..43c3613 --- /dev/null +++ b/src/lua/modules/graphics/ttfData.cpp @@ -0,0 +1,51 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "lua/common/common.h" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + using namespace JinEngine::Graphics; + + static int l_newTTF(lua_State* L) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TTFDATA); + int fontsize = luax_checkinteger(L, 2); + Ref<TTFData>& refFontData = p->getRef<TTFData>(); + TTFData* fontData = refFontData.getObject(); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_TTF, sizeof(Proxy)); + TTF* font = fontData->createTTF(fontsize); + Ref<TTF>* refTTF = new Ref<TTF>(font, JIN_GRAPHICS_TTF); + { + Ref<TTFData>& refTTFData = p->getRef<TTFData>(); + refTTFData.retain(); + refTTF->setUserdata(&refTTFData); + } + proxy->bind(refTTF); + return 1; + } + + static int l_gc(lua_State* L) + { + Proxy* p = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_TTFDATA); + p->release(); + return 0; + } + + static const luaL_Reg f[] = { + { "__gc", l_gc }, + { "newTTF", l_newTTF }, + { 0, 0 } + }; + + int luaopen_TTFData(lua_State* L) + { + luax_newtype(L, JIN_GRAPHICS_TTFDATA, f); + return 0; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/jin.cpp b/src/lua/modules/jin.cpp deleted file mode 100644 index a25ec6c..0000000 --- a/src/lua/modules/jin.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "jin.h" -#include "lua/modules/luax.h" -#include "embed/embed.h" - -namespace jin -{ -namespace lua -{ - - extern int luaopen_core(lua_State* L); - extern int luaopen_graphics(lua_State* L); - extern int luaopen_audio(lua_State* L); - extern int luaopen_net(lua_State* L); - extern int luaopen_event(lua_State* L); - extern int luaopen_time(lua_State* L); - extern int luaopen_mouse(lua_State* L); - extern int luaopen_keyboard(lua_State* L); - extern int luaopen_filesystem(lua_State* L); - extern int luaopen_joypad(lua_State* L); - extern int luaopen_math(lua_State* L); - extern int luaopen_thread(lua_State* L); - extern int luaopen_bit(lua_State* L); - - static int l_getversion(lua_State* L) - { - luax_pushstring(L, VERSION); - return 1; - } - - static int l_getAuthor(lua_State* L) - { - luax_pushstring(L, AUTHOR); - return 1; - } - - static int l_getOS(lua_State* L) - { - #ifdef _WIN32 - luax_pushstring(L, "windows"); - #elif defined __unix__ - luax_pushstring(L, "unix"); - #elif defined __APPLE__ - luax_pushstring(L, "macos"); - #endif - return 1; - } - - static int l_revision(lua_State* L) - { - luax_pushnumber(L, REVISION); - return 1; - } - - static const luaL_Reg f[] = { - { "version", l_getversion }, - { "revision", l_revision }, - { "author", l_getAuthor }, - { "os", l_getOS }, - { 0, 0 } - }; - - // submodules - static const luaL_Reg mods[] = { - { "core", luaopen_core }, - { "event", luaopen_event }, - { "graphics", luaopen_graphics }, - { "time", luaopen_time }, - { "mouse", luaopen_mouse }, - { "keyboard", luaopen_keyboard }, - { "filesystem", luaopen_filesystem }, - { "net", luaopen_net }, - { "audio", luaopen_audio }, - { "joypad", luaopen_joypad }, - { "math", luaopen_math }, - { "thread", luaopen_thread }, - { "bit", luaopen_bit }, - { 0, 0 } - }; - - int luaopen_jin(lua_State* L) - { - // jin module is on top of the stack - luax_newlib(L, f); - - // set to global field - luax_justglobal(L, -1, MODULE_NAME); - - // register submodules - for (int i = 0; mods[i].name; ++i) - { - mods[i].func(L); - luax_setfield(L, -2, mods[i].name); - } - - return 1; - } - - void boot(lua_State* L) - { - jin::embed::boot(L); - } - -} // lua -} // jin
\ No newline at end of file diff --git a/src/lua/modules/jin.h b/src/lua/modules/jin.h deleted file mode 100644 index 07531b2..0000000 --- a/src/lua/modules/jin.h +++ /dev/null @@ -1,42 +0,0 @@ -/** -* Copyright (C) 2016~2018 chai -* -* Permission is hereby granted, free of charge, to any person obtaining a copyof -* this software and associated documentation files (the "Software"), to deal in -* the Software without restriction, including without limitation the rights to use, -* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -* Software, and to permit persons to whom the Software is furnished to do so, -* subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all -* copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef __JIN_M_JIN_H -#define __JIN_M_JIN_H -#include "luax.h" - -#define MODULE_NAME "jin" -#define VERSION "0.1.1" -#define REVISION 101 -#define AUTHOR "chai" - -namespace jin -{ -namespace lua -{ - - int luaopen_jin(lua_State* L); - void boot(lua_State* L); - -} // jin -} // lua - -#endif // __JIN_M_JIN_H
\ No newline at end of file diff --git a/src/lua/modules/joypad/joypad.cpp b/src/lua/modules/joypad/joypad.cpp index d305878..d67a624 100644 --- a/src/lua/modules/joypad/joypad.cpp +++ b/src/lua/modules/joypad/joypad.cpp @@ -1,21 +1,21 @@ #include "libjin/jin.h" #include "lua/modules/luax.h" -namespace jin +namespace JinEngine { -namespace lua -{ - - static const luaL_Reg f[] = { - { 0, 0 } - }; - - int luaopen_joypad(lua_State* L) + namespace Lua { - luax_newlib(L, f); - return 1; - } + static const luaL_Reg f[] = { + { 0, 0 } + }; + + int luaopen_joypad(lua_State* L) + { + luax_newlib(L, f); -} -}
\ No newline at end of file + return 1; + } + /*SDL_JoystickGetButton*/ + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/keyboard/keyboard.cpp b/src/lua/modules/keyboard/keyboard.cpp index 9d27a4f..727a51e 100644 --- a/src/lua/modules/keyboard/keyboard.cpp +++ b/src/lua/modules/keyboard/keyboard.cpp @@ -1,16 +1,16 @@ #include "lua/modules/luax.h" -#include "lua/modules/embed/keyboard.lua.h" -namespace jin +namespace JinEngine { -namespace lua -{ - - int luaopen_keyboard(lua_State* L) + namespace Lua { - luax_newlib(L, 0); - return 1; - } + //https://wiki.libsdl.org/SDL_Keycode + + int luaopen_keyboard(lua_State* L) + { + luax_newlib(L, 0); + return 1; + } -} -}
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/luax.h b/src/lua/modules/luax.h index 89e456e..f45af39 100644 --- a/src/lua/modules/luax.h +++ b/src/lua/modules/luax.h @@ -1,7 +1,6 @@ -#ifndef __JIN_LUA_LUAX_H -#define __JIN_LUA_LUAX_H +#ifndef __JIN_MODULES_LUAX_H +#define __JIN_MODULES_LUAX_H -#include "LuaJIT/lua.hpp" -#include "lua/libraries/luax/luax.h" +#include "../luax.h" #endif
\ No newline at end of file diff --git a/src/lua/modules/math/math.cpp b/src/lua/modules/math/math.cpp index fa59e04..4891762 100644 --- a/src/lua/modules/math/math.cpp +++ b/src/lua/modules/math/math.cpp @@ -1,30 +1,30 @@ #include "lua/modules/luax.h" #include "libjin/jin.h" -namespace jin +namespace JinEngine { -namespace lua -{ - - static int l_mod(lua_State* L) + namespace Lua { - int n = luax_checkinteger(L, 1); - int m = luax_checkinteger(L, 2); - int mod = n % m; - luax_pushinteger(L, mod); - return 1; - } - static const luaL_Reg f[] = { - { "mod", l_mod }, - { 0, 0 } - }; + static int l_mod(lua_State* L) + { + int n = luax_checkinteger(L, 1); + int m = luax_checkinteger(L, 2); + int mod = n % m; + luax_pushinteger(L, mod); + return 1; + } - int luaopen_math(lua_State* L) - { - luax_newlib(L, f); - return 1; - } + static const luaL_Reg f[] = { + { "mod", l_mod }, + { 0, 0 } + }; + + int luaopen_math(lua_State* L) + { + luax_newlib(L, f); + return 1; + } -} -}
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/mouse/mouse.cpp b/src/lua/modules/mouse/mouse.cpp index f907abb..9d45178 100644 --- a/src/lua/modules/mouse/mouse.cpp +++ b/src/lua/modules/mouse/mouse.cpp @@ -1,31 +1,42 @@ #include "lua/modules/luax.h" #include "libjin/jin.h" -namespace jin +namespace JinEngine { -namespace lua -{ - using namespace jin::input; - - static int l_pos(lua_State* L) + namespace Lua { - static Mouse* mouse = Mouse::get(); - int x, y; - mouse->getState(&x, &y); - luax_pushnumber(L, x); - luax_pushnumber(L, y); - return 2; - } - static const luaL_Reg f[] = { - { "position", l_pos }, - { 0, 0 } - }; + using namespace JinEngine::Input; + + static int l_pos(lua_State* L) + { + static Mouse* mouse = Mouse::get(); + int x, y; + mouse->getState(&x, &y); + luax_pushnumber(L, x); + luax_pushnumber(L, y); + return 2; + } + + static int l_setVisible(lua_State* L) + { + bool visible = luax_checkbool(L, 1); + Mouse* mouse = Mouse::get(); + mouse->setVisible(visible); + return 0; + } + + static const luaL_Reg f[] = { + { "position", l_pos }, + { "setVisible", l_setVisible }, + { 0, 0 } + }; - int luaopen_mouse(lua_State* L) - { - luax_newlib(L, f); - return 1; - } -} -}
\ No newline at end of file + int luaopen_mouse(lua_State* L) + { + luax_newlib(L, f); + return 1; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/net/Buffer.cpp b/src/lua/modules/net/Buffer.cpp index 3354518..ddfbd6b 100644 --- a/src/lua/modules/net/Buffer.cpp +++ b/src/lua/modules/net/Buffer.cpp @@ -4,133 +4,139 @@ #include "libjin/jin.h" #include "Buffer.h" -namespace jin +namespace JinEngine { -namespace lua -{ -namespace net -{ - - static inline Ref<Buffer>& checkNetBuffer(lua_State* L) + namespace Lua { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_BUFFER); - return proxy->getRef<Buffer>(); - } - - // net.Buffer:append(value) -> value_length - static int l_append(lua_State* L) - { - Ref<Buffer>& ref = checkNetBuffer(L); - const int vp = 2; - if (luax_isintegerstrict(L, vp)) - { - int n = luax_checkinteger(L, vp); - int size = sizeof(n); - ref->append(&n, size); - luax_pushinteger(L, size); - return 1; - } - else if (luax_isfloatstrict(L, vp)) - { - float n = luax_checknumber(L, vp); - int size = sizeof(n); - ref->append(&n, size); - luax_pushinteger(L, size); - return 1; - } - else if (luax_isbooleanstrict(L, vp)) - { - bool n = luax_checkbool(L, vp); - int size = sizeof(n); - ref->append(&n, size); - luax_pushinteger(L, size); - return 1; - } - else if (luax_isstringstrict(L, vp)) + namespace Net { - const char* str = luax_checkstring(L, vp); - int size = strlen(str) + 1; - ref->append(str, size); - luax_pushinteger(L, size); - return 1; - } - else - { - luax_typerror(L, vp, "number, bool or string"); - return 0; - } - } - // net.Buffer:grabString(offset) -> string, length - static int l_grabString(lua_State* L) - { - Ref<Buffer>& ref = checkNetBuffer(L); - int offset = luax_checkinteger(L, 2); - int len; - const char* str = ref->grabString(&len, offset); - luax_pushstring(L, str); - luax_pushinteger(L, len); - return 2; - } + using namespace JinEngine; - // net.Buffer:grabInteger(offset) -> integer, length - static int l_grabInteger(lua_State* L) - { - Ref<Buffer>& ref = checkNetBuffer(L); - int offset = luax_checkinteger(L, 2); - int len; - int integer = ref->grabInteger(&len, offset); - luax_pushinteger(L, integer); - luax_pushinteger(L, len); - return 2; - } + typedef Ref<Buffer>& BufferRef; - static int l_grabFloat(lua_State* L) - { - Ref<Buffer>& ref = checkNetBuffer(L); - int offset = luax_checkinteger(L, 2); - int len; - float floatv = ref->grabFloat(&len, offset); - luax_pushnumber(L, floatv); - luax_pushinteger(L, len); - return 2; - } + static inline BufferRef checkNetBuffer(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_BUFFER); + return proxy->getRef<Buffer>(); + } - static int l_grabBoolean(lua_State* L) - { - Ref<Buffer>& ref = checkNetBuffer(L); - int offset = luax_checkinteger(L, 2); - int len; - bool boolean = ref->grabBoolean(&len, offset); - luax_pushboolean(L, boolean); - luax_pushinteger(L, len); - return 2; - } + // net.Buffer:append(value) -> value_length + static int l_append(lua_State* L) + { + BufferRef ref = checkNetBuffer(L); + const int vp = 2; + if (luax_isintegerstrict(L, vp)) + { + int n = luax_checkinteger(L, vp); + int size = sizeof(n); + ref->append(&n, size); + luax_pushinteger(L, size); + return 1; + } + else if (luax_isfloatstrict(L, vp)) + { + float n = luax_checknumber(L, vp); + int size = sizeof(n); + ref->append(&n, size); + luax_pushinteger(L, size); + return 1; + } + else if (luax_isbooleanstrict(L, vp)) + { + bool n = luax_checkbool(L, vp); + int size = sizeof(n); + ref->append(&n, size); + luax_pushinteger(L, size); + return 1; + } + else if (luax_isstringstrict(L, vp)) + { + const char* str = luax_checkstring(L, vp); + int size = strlen(str) + 1; + ref->append(str, size); + luax_pushinteger(L, size); + return 1; + } + else + { + luax_typerror(L, vp, "number, bool or string"); + return 0; + } + } - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_BUFFER); - proxy->release(); - return 0; - } + // net.Buffer:grabString(offset) -> string, length + static int l_grabString(lua_State* L) + { + BufferRef ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + unsigned int len; + char* data = ref->grabString(&len, offset); + Array<char> str; + str.bind(data, len); + luax_pushstring(L, &str); + luax_pushinteger(L, str.count()); + return 2; + } - static const luaL_Reg netbuffer_function[] = { - { "__gc", l_gc }, - { "append", l_append }, - { "grabString", l_grabString }, - { "grabInteger", l_grabInteger }, - { "grabBoolean", l_grabBoolean }, - { "grabFloat", l_grabFloat }, - { 0, 0 } - }; + // net.Buffer:grabInteger(offset) -> integer, length + static int l_grabInteger(lua_State* L) + { + BufferRef ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + int integer = ref->grabInteger(&len, offset); + luax_pushinteger(L, integer); + luax_pushinteger(L, len); + return 2; + } -} // net + static int l_grabFloat(lua_State* L) + { + BufferRef ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + float floatv = ref->grabFloat(&len, offset); + luax_pushnumber(L, floatv); + luax_pushinteger(L, len); + return 2; + } - int luaopen_Buffer(lua_State* L) - { - luax_newtype(L, JIN_NETWORK_BUFFER, net::netbuffer_function); - return 0; - } + static int l_grabBoolean(lua_State* L) + { + BufferRef ref = checkNetBuffer(L); + int offset = luax_checkinteger(L, 2); + int len; + bool boolean = ref->grabBoolean(&len, offset); + luax_pushboolean(L, boolean); + luax_pushinteger(L, len); + return 2; + } + + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_BUFFER); + proxy->release(); + return 0; + } + + static const luaL_Reg netbuffer_function[] = { + { "__gc", l_gc }, + { "append", l_append }, + { "grabString", l_grabString }, + { "grabInteger", l_grabInteger }, + { "grabBoolean", l_grabBoolean }, + { "grabFloat", l_grabFloat }, + { 0, 0 } + }; + + } // namespace Net + + int luaopen_Buffer(lua_State* L) + { + luax_newtype(L, JIN_NETWORK_BUFFER, Net::netbuffer_function); + return 0; + } -} // lua -} // jin
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/net/Buffer.h b/src/lua/modules/net/Buffer.h index 31e6df8..8733778 100644 --- a/src/lua/modules/net/Buffer.h +++ b/src/lua/modules/net/Buffer.h @@ -5,92 +5,93 @@ #include <cstdlib> #include "lua/common/common.h" -namespace jin +namespace JinEngine { -namespace lua -{ -namespace net -{ - - class Buffer + namespace Lua { - public: - Buffer(size_t s = 0) - : size(s) + namespace Net { - buffer = new char[size]; - memset(buffer, 0, size); - } - Buffer(const char* data, size_t s) - : size(s) - { - buffer = new char[size]; - memcpy(buffer, data, size); - } - - ~Buffer() - { - if (buffer != nullptr) + class Buffer { - delete[] buffer; - buffer = nullptr; - size = 0; - } - } + public: + Buffer(size_t s = 0) + : size(s) + { + buffer = new char[size]; + memset(buffer, 0, size); + } - void append(const void* data, size_t s) - { - if (data == nullptr) - return; - char* buf = buffer; - buffer = new char[size + s]; - memcpy(buffer, buf, size); - memcpy(buffer + size, data, s); - delete[] buf; - size += s; - return; - } + Buffer(const char* data, size_t s) + : size(s) + { + buffer = new char[size]; + memcpy(buffer, data, size); + } - const char* grabString(int* length, int offset = 0) - { - int l = offset; - for (; l < size; ++l) - { - if (buffer[l] == 0) - break; - } - *length = l - offset + 1; - char* str = (char*)malloc(*length); - memcpy(str, buffer + offset, *length); - return str; - } + ~Buffer() + { + if (buffer != nullptr) + { + delete[] buffer; + buffer = nullptr; + size = 0; + } + } - int grabInteger(int* length, int offset = 0) - { - *length = sizeof(int); - return *((int*)(buffer + offset)); - } + void append(const void* data, size_t s) + { + if (data == nullptr) + return; + char* buf = buffer; + buffer = new char[size + s]; + memcpy(buffer, buf, size); + memcpy(buffer + size, data, s); + delete[] buf; + size += s; + return; + } - float grabFloat(int* length, int offset = 0) - { - *length = sizeof(float); - return *((float*)(buffer + offset)); - } + /* grab and create a string */ + char* grabString(unsigned int* length, int offset = 0) + { + int l = offset; + for (; l < size; ++l) + { + if (buffer[l] == 0) + break; + } + *length = l - offset + 1; + char* str = (char*)malloc(*length); + memcpy(str, buffer + offset, *length); + return str; + } - bool grabBoolean(int* length, int offset = 0) - { - *length = sizeof(bool); - return *((bool*)(buffer + offset)); - } + int grabInteger(int* length, int offset = 0) + { + *length = sizeof(int); + return *((int*)(buffer + offset)); + } + + float grabFloat(int* length, int offset = 0) + { + *length = sizeof(float); + return *((float*)(buffer + offset)); + } + + bool grabBoolean(int* length, int offset = 0) + { + *length = sizeof(bool); + return *((bool*)(buffer + offset)); + } - char* buffer; - size_t size; + char* buffer; + size_t size; - }; + }; -} // net -} // lua -} // jin + } // namespace Net + } // namespace Lua +} // namespace JinEngine #endif
\ No newline at end of file diff --git a/src/lua/modules/net/net.cpp b/src/lua/modules/net/net.cpp index a984920..4ef9ece 100644 --- a/src/lua/modules/net/net.cpp +++ b/src/lua/modules/net/net.cpp @@ -4,16 +4,17 @@ #include "lua/common/common.h" #include "Buffer.h" -namespace jin +namespace JinEngine { -namespace lua +namespace Lua { - using namespace jin::lua::net; - using namespace jin::net; + + using namespace JinEngine::Lua::Net; + using namespace JinEngine::Net; static int l_initNetwork(lua_State* L) { - jin::net::Net::get()->init(); + JinEngine::Net::NetManager::get()->init(); return 1; } @@ -56,7 +57,7 @@ namespace lua { int size = luax_checkinteger(L, 1); Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); - net::Buffer* buffer = new net::Buffer(size); + Net::Buffer* buffer = new Net::Buffer(size); proxy->bind(new Ref<Buffer>(buffer, JIN_NETWORK_BUFFER)); return 1; } @@ -81,5 +82,5 @@ namespace lua return 1; } -} // lua -} // jin
\ No newline at end of file +} // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/net/socket.cpp b/src/lua/modules/net/socket.cpp index 6d3fdfb..d6de730 100644 --- a/src/lua/modules/net/socket.cpp +++ b/src/lua/modules/net/socket.cpp @@ -4,124 +4,126 @@ #include "libjin/jin.h" #include "Buffer.h" -namespace jin -{ -namespace lua +namespace JinEngine { + namespace Lua + { - using namespace jin::net; - using namespace lua::net; + using namespace JinEngine::Net; + using namespace Lua::Net; - const int BUFFER_SIZE = 1024; + typedef Ref<Socket>& SocketRef; - static inline Ref<Socket>& checkSocket(lua_State* L, int pos = 1) - { - Proxy* proxy = (Proxy*)luax_checktype(L, pos, JIN_NETWORK_SOCKET); - return proxy->getRef<Socket>(); - } + const int BUFFER_SIZE = 1024; - static inline Ref<Buffer>& checkNetBuffer(lua_State* L, int pos = 1) - { - Proxy* proxy = (Proxy*)luax_checktype(L, pos, JIN_NETWORK_BUFFER); - return proxy->getRef<Buffer>(); - } + static inline SocketRef checkSocket(lua_State* L, int pos = 1) + { + Proxy* proxy = (Proxy*)luax_checktype(L, pos, JIN_NETWORK_SOCKET); + return proxy->getRef<Socket>(); + } - // return net.Socket - static int l_accept(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - Socket* client = socket->accept(); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_SOCKET, sizeof(Proxy)); - proxy->bind(new Ref<Socket>(client, JIN_NETWORK_SOCKET)); - return 1; - } + static inline Ref<Buffer>& checkNetBuffer(lua_State* L, int pos = 1) + { + Proxy* proxy = (Proxy*)luax_checktype(L, pos, JIN_NETWORK_BUFFER); + return proxy->getRef<Buffer>(); + } + + // return net.Socket + static int l_accept(lua_State* L) + { + SocketRef socket = checkSocket(L); + Socket* client = socket->accept(); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_SOCKET, sizeof(Proxy)); + proxy->bind(new Ref<Socket>(client, JIN_NETWORK_SOCKET)); + return 1; + } - // return net.Buffer - static int l_receive(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - char buffer[BUFFER_SIZE] = {0}; - int size = socket->receive(buffer, BUFFER_SIZE); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); - net::Buffer* netBuffer = new net::Buffer(buffer, size); - proxy->bind(new Ref<Buffer>(netBuffer, JIN_NETWORK_BUFFER)); - return 1; - } + // return net.Buffer + static int l_receive(lua_State* L) + { + SocketRef socket = checkSocket(L); + char buffer[BUFFER_SIZE] = {0}; + int size = socket->receive(buffer, BUFFER_SIZE); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); + Net::Buffer* netBuffer = new Net::Buffer(buffer, size); + proxy->bind(new Ref<Buffer>(netBuffer, JIN_NETWORK_BUFFER)); + return 1; + } - // Socket:receiveFrom(address, port) - static int l_receiveFrom(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - int address = luax_checkinteger(L, 2); - int port = luax_checkinteger(L, 3); - char buffer[BUFFER_SIZE]; - int size = socket->receiveFrom(buffer, BUFFER_SIZE, address, port); - net::Buffer* netBuffer = new net::Buffer(buffer, size); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); - proxy->bind(new Ref<Buffer>(netBuffer, JIN_NETWORK_BUFFER)); - return 1; - } + // Socket:receiveFrom(address, port) + static int l_receiveFrom(lua_State* L) + { + SocketRef socket = checkSocket(L); + int address = luax_checkinteger(L, 2); + int port = luax_checkinteger(L, 3); + char buffer[BUFFER_SIZE]; + int size = socket->receiveFrom(buffer, BUFFER_SIZE, address, port); + Net::Buffer* netBuffer = new Net::Buffer(buffer, size); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_NETWORK_BUFFER, sizeof(Proxy)); + proxy->bind(new Ref<Buffer>(netBuffer, JIN_NETWORK_BUFFER)); + return 1; + } - // Socket:send(net.Buffer) -> data_length - static int l_send(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - Ref<Buffer>& ref = checkNetBuffer(L, 2); - int len = socket->send(ref->buffer, ref->size); - luax_pushinteger(L, len); - return 1; - } + // Socket:send(net.Buffer) -> data_length + static int l_send(lua_State* L) + { + SocketRef socket = checkSocket(L); + Ref<Buffer>& ref = checkNetBuffer(L, 2); + int len = socket->send(ref->buffer, ref->size); + luax_pushinteger(L, len); + return 1; + } - // Socket:sendTo(address, port, net.Buffer) - static int l_sendTo(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - int address = luax_checkinteger(L, 2); - int port = luax_checkinteger(L, 3); - Ref<Buffer>& buffer = checkNetBuffer(L, 4); - socket->sendTo(buffer->buffer, buffer->size, address, port); - return 0; - } + // Socket:sendTo(address, port, net.Buffer) + static int l_sendTo(lua_State* L) + { + SocketRef socket = checkSocket(L); + int address = luax_checkinteger(L, 2); + int port = luax_checkinteger(L, 3); + Ref<Buffer>& buffer = checkNetBuffer(L, 4); + socket->sendTo(buffer->buffer, buffer->size, address, port); + return 0; + } - static int l_close(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - socket->close(); - return 0; - } + static int l_close(lua_State* L) + { + SocketRef socket = checkSocket(L); + socket->close(); + return 0; + } - static int l_configBlocking(lua_State* L) - { - Ref<Socket>& socket = checkSocket(L); - bool blocking = luax_checkbool(L, 2); - socket->configureBlocking(blocking); - return 0; - } + static int l_configBlocking(lua_State* L) + { + SocketRef socket = checkSocket(L); + bool blocking = luax_checkbool(L, 2); + socket->configureBlocking(blocking); + return 0; + } - static int l_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_SOCKET); - proxy->release(); - return 0; - } + static int l_gc(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_NETWORK_SOCKET); + proxy->release(); + return 0; + } - static const luaL_Reg socket_function[] = { - { "__gc", l_gc }, - { "accept", l_accept }, - { "receive", l_receive }, - { "receiveFrom", l_receiveFrom }, - { "send", l_send }, - { "sendTo", l_sendTo }, - { "close", l_close }, - { "configBlocking", l_configBlocking }, - { 0, 0 } - }; + static const luaL_Reg socket_function[] = { + { "__gc", l_gc }, + { "accept", l_accept }, + { "receive", l_receive }, + { "receiveFrom", l_receiveFrom }, + { "send", l_send }, + { "sendTo", l_sendTo }, + { "close", l_close }, + { "configBlocking", l_configBlocking }, + { 0, 0 } + }; - int luaopen_Socket(lua_State* L) - { - luax_newtype(L, JIN_NETWORK_SOCKET, socket_function); - return 0; - } + int luaopen_Socket(lua_State* L) + { + luax_newtype(L, JIN_NETWORK_SOCKET, socket_function); + return 0; + } -} // lua -} // jin
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/physics/physics.cpp b/src/lua/modules/physics/physics.cpp deleted file mode 100644 index a5b9162..0000000 --- a/src/lua/modules/physics/physics.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "../luax.h" -#include "libjin/Physics/Physics.h" - -namespace jin -{ -namespace lua -{ - - using namespace jin::physics; - - int luaopen_physics(lua_State* L) - { - } - -} // physics -} // jin
\ No newline at end of file diff --git a/src/lua/modules/thread/Thread.cpp b/src/lua/modules/thread/Thread.cpp index 5c9cb1f..e1c5a92 100644 --- a/src/lua/modules/thread/Thread.cpp +++ b/src/lua/modules/thread/Thread.cpp @@ -1,249 +1,252 @@ #include "lua/modules/luax.h" #include "lua/modules/types.h" #include "libjin/jin.h" -#include "lua/modules/jin.h" +#include "lua/jin.h" #include "lua/common/common.h" #include "thread.h" -namespace jin +namespace JinEngine { -namespace lua -{ - - using thread::Thread; - - int luaopen_thread(lua_State* L); - - static inline Ref<Thread>& checkThread(lua_State* L) + namespace Lua { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD); - return proxy->getRef<Thread>(); - } - static int threadRunner(void* t) - { - Ref<Thread>& ref = *(Ref<Thread>*)t; - lua_State* L = lua_open(); - luax_openlibs(L); - luaopen_jin(L); - luax_getglobal(L, MODULE_NAME); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_THREAD_THREAD, sizeof(Proxy)); - ref.retain(); - proxy->bind(&ref); - luax_setfield(L, -2, "_curThread"); - luax_dostring(L, ref->code.c_str()); - luax_close(L); - return 0; - } - - static int l_thread_gc(lua_State* L) - { - Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD); - proxy->release(); - return 0; - } + using thread::Thread; - static int l_start(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - bool result = ref->start(&ref); - luax_pushboolean(L, result); - return 1; - } + typedef Ref<Thread>& ThreadRef; - static int l_wait(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - ref->wait(); - return 0; - } + int luaopen_thread(lua_State* L); - static int l_send(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - int slot = luax_checkinteger(L, 2); - const int vp = 3; - if (luax_isnumberstrict(L, vp)) + static inline ThreadRef checkThread(lua_State* L) { - float real = luax_checknumber(L, vp); - ref->send(slot, real); + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD); + return proxy->getRef<Thread>(); } - else if (luax_isbooleanstrict(L, vp)) + + static int threadRunner(void* t) { - bool bol = luax_checkbool(L, vp); - ref->send(slot, bol); + ThreadRef ref = *(Ref<Thread>*)t; + lua_State* L = lua_open(); + luax_openlibs(L); + luaopen_jin(L); + luax_getglobal(L, MODULE_NAME); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_THREAD_THREAD, sizeof(Proxy)); + ref.retain(); + proxy->bind(&ref); + luax_setfield(L, -2, "_curThread"); + luax_dostring(L, ref->code.c_str()); + luax_close(L); + return 0; } - else if (luax_isstringstrict(L, vp)) + + static int l_thread_gc(lua_State* L) { - const char* str = luax_checkstring(L, vp); - ref->send(slot, str); + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_THREAD_THREAD); + proxy->release(); + return 0; } - else if (luax_isuserdata(L, vp)) + + static int l_start(lua_State* L) { - void* p = luax_touserdata(L, vp); - ref->send(slot, p); + ThreadRef ref = checkThread(L); + bool result = ref->start(&ref); + luax_pushboolean(L, result); + return 1; } - else if (luax_islightuserdata(L, vp)) + + static int l_wait(lua_State* L) { - void* p = luax_tolightuserdata(L, vp); - ref->send(slot, p); + ThreadRef ref = checkThread(L); + ref->wait(); + return 0; } - return 0; - } - static int l_receive(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - int slot = luax_checkinteger(L, 2); - bool result = ref->receive(slot); - luax_pushboolean(L, result); - return 1; - } - - static int l_fetch(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - int slot = luax_checkinteger(L, 2); - Thread::Variant v = ref->fetch(slot); - switch (v.type) + static int l_send(lua_State* L) { - case thread::Thread::Variant::INTERGER: - luax_pushinteger(L, v.integer); - break; - - case thread::Thread::Variant::BOOLEAN: - luax_pushboolean(L, v.boolean); - break; - - case thread::Thread::Variant::CSTRING: - luax_pushstring(L, v.cstring); - break; - - case thread::Thread::Variant::REAL: - luax_pushnumber(L, v.real); - break; + ThreadRef ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + const int vp = 3; + if (luax_isnumberstrict(L, vp)) + { + float real = luax_checknumber(L, vp); + ref->send(slot, real); + } + else if (luax_isbooleanstrict(L, vp)) + { + bool bol = luax_checkbool(L, vp); + ref->send(slot, bol); + } + else if (luax_isstringstrict(L, vp)) + { + const char* str = luax_checkstring(L, vp); + ref->send(slot, str); + } + else if (luax_isuserdata(L, vp)) + { + void* p = luax_touserdata(L, vp); + ref->send(slot, p); + } + else if (luax_islightuserdata(L, vp)) + { + void* p = luax_tolightuserdata(L, vp); + ref->send(slot, p); + } + return 0; + } - case thread::Thread::Variant::POINTER: - Proxy* p = (Proxy*)v.pointer; - Proxy* proxy = (Proxy*)luax_newinstance(L, p->getObjectType(), sizeof(Proxy)); - p->reference->retain(); - proxy->bind(p->reference); - break; + static int l_receive(lua_State* L) + { + ThreadRef ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + bool result = ref->receive(slot); + luax_pushboolean(L, result); + return 1; + } + static int l_fetch(lua_State* L) + { + ThreadRef ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + Thread::Variant v = ref->fetch(slot); + switch (v.type) + { + case thread::Thread::Variant::INTERGER: + luax_pushinteger(L, v.integer); + break; + + case thread::Thread::Variant::BOOLEAN: + luax_pushboolean(L, v.boolean); + break; + + case thread::Thread::Variant::CSTRING: + luax_pushstring(L, v.cstring); + break; + + case thread::Thread::Variant::REAL: + luax_pushnumber(L, v.real); + break; + + case thread::Thread::Variant::POINTER: + Proxy* p = (Proxy*)v.pointer; + Proxy* proxy = (Proxy*)luax_newinstance(L, p->getObjectType(), sizeof(Proxy)); + p->reference->retain(); + proxy->bind(p->reference); + break; + + } + return 1; } - return 1; - } - static int l_demand(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - int slot = luax_checkinteger(L, 2); - Thread::Variant v = ref->demand(slot); - switch (v.type) + static int l_demand(lua_State* L) { - case thread::Thread::Variant::INTERGER: - luax_pushinteger(L, v.integer); - break; + ThreadRef ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + Thread::Variant v = ref->demand(slot); + switch (v.type) + { + case thread::Thread::Variant::INTERGER: + luax_pushinteger(L, v.integer); + break; + + case thread::Thread::Variant::BOOLEAN: + luax_pushboolean(L, v.boolean); + break; + + case thread::Thread::Variant::CSTRING: + luax_pushstring(L, v.cstring); + break; + + case thread::Thread::Variant::REAL: + luax_pushnumber(L, v.real); + break; + + case thread::Thread::Variant::POINTER: + Proxy* p = (Proxy*)v.pointer; + const char* objType = p->getObjectType(); + Proxy* proxy = (Proxy*)luax_newinstance(L, objType, sizeof(Proxy)); + p->reference->retain(); + proxy->bind(p->reference); + break; + + } + return 1; + } - case thread::Thread::Variant::BOOLEAN: - luax_pushboolean(L, v.boolean); - break; + static int l_remove(lua_State* L) + { + ThreadRef ref = checkThread(L); + int slot = luax_checkinteger(L, 2); + ref->remove(slot); + return 0; + } - case thread::Thread::Variant::CSTRING: - luax_pushstring(L, v.cstring); - break; + static int l_getName(lua_State* L) + { + ThreadRef ref = checkThread(L); + const char* name = ref->getName(); + luax_pushstring(L, name); + return 1; + } - case thread::Thread::Variant::REAL: - luax_pushnumber(L, v.real); - break; + static int l_isRunning(lua_State* L) + { + ThreadRef ref = checkThread(L); + bool running = ref->isRunning(); + luax_pushboolean(L, running); + return 1; + } - case thread::Thread::Variant::POINTER: - Proxy* p = (Proxy*)v.pointer; - Proxy* proxy = (Proxy*)luax_newinstance(L, p->getObjectType(), sizeof(Proxy)); - p->reference->retain(); - proxy->bind(p->reference); - break; + static const luaL_Reg thread_function[] = { + { "__gc", l_thread_gc }, + { "start", l_start }, + { "wait", l_wait }, + { "send", l_send }, + { "receive", l_receive }, + { "fetch", l_fetch }, + { "demand", l_demand }, + { "remove", l_remove }, + { "getName", l_getName }, + { "isRunning", l_isRunning }, + { 0, 0 } + }; + + static int luaopen_Thread(lua_State* L) + { + luax_newtype(L, JIN_THREAD_THREAD, thread_function); + return 0; + } + + static int l_newThread(lua_State* L) + { + const char* name = luax_checkstring(L, 1); + const char* code = luax_checkstring(L, 2); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_THREAD_THREAD, sizeof(Proxy)); + Thread* thread = new Thread(name, code, threadRunner); + proxy->bind(new Ref<Thread>(thread, JIN_THREAD_THREAD)); + return 1; } - return 1; - } - - static int l_remove(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - int slot = luax_checkinteger(L, 2); - ref->remove(slot); - return 0; - } - static int l_getName(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - const char* name = ref->getName(); - luax_pushstring(L, name); - return 1; - } + static int l_getThread(lua_State* L) + { + luax_getglobal(L, MODULE_NAME); + luax_getfield(L, -1, "_curThread"); + return 1; + } - static int l_isRunning(lua_State* L) - { - Ref<Thread>& ref = checkThread(L); - bool running = ref->isRunning(); - luax_pushboolean(L, running); - return 1; - } - - static const luaL_Reg thread_function[] = { - { "__gc", l_thread_gc }, - { "start", l_start }, - { "wait", l_wait }, - { "send", l_send }, - { "receive", l_receive }, - { "fetch", l_fetch }, - { "demand", l_demand }, - { "remove", l_remove }, - { "getName", l_getName }, - { "isRunning", l_isRunning }, - { 0, 0 } - }; - - static int luaopen_Thread(lua_State* L) - { - luax_newtype(L, JIN_THREAD_THREAD, thread_function); + static const luaL_Reg f[] = { + { "newThread", l_newThread }, + { "getThread", l_getThread }, + { 0, 0 } + }; - return 0; - } - - static int l_newThread(lua_State* L) - { - const char* name = luax_checkstring(L, 1); - const char* code = luax_checkstring(L, 2); - Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_THREAD_THREAD, sizeof(Proxy)); - Thread* thread = new Thread(name, code, threadRunner); - proxy->bind(new Ref<Thread>(thread, JIN_THREAD_THREAD)); - return 1; - } - - static int l_getThread(lua_State* L) - { - luax_getglobal(L, MODULE_NAME); - luax_getfield(L, -1, "_curThread"); - return 1; - } - - static const luaL_Reg f[] = { - { "newThread", l_newThread }, - { "getThread", l_getThread }, - { 0, 0 } - }; - - int luaopen_thread(lua_State* L) - { - luaopen_Thread(L); + int luaopen_thread(lua_State* L) + { + luaopen_Thread(L); - luax_newlib(L, f); + luax_newlib(L, f); - return 1; - } + return 1; + } -} // lua -} // jin
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/thread/Thread.h b/src/lua/modules/thread/Thread.h index 645d4a1..60d588a 100644 --- a/src/lua/modules/thread/Thread.h +++ b/src/lua/modules/thread/Thread.h @@ -1,94 +1,94 @@ #include "libjin/jin.h" #include "lua/common/common.h" -namespace jin +namespace JinEngine { -namespace lua -{ -namespace thread -{ - - class Thread + namespace Lua { - public: - typedef jin::thread::Thread::Variant Variant; - typedef jin::thread::Thread::ThreadRunner ThreadRunner; - - Thread(std::string _name, std::string _code, ThreadRunner runner) - : name(_name) - , code(_code) - { - thread = new jin::thread::Thread(_name, runner); - } - - ~Thread() - { - delete thread; - } - - bool start(void* p) - { - return thread->start(p); - } - - void wait() - { - thread->wait(); - } - - void send(int slot, const Variant& value) - { - thread->send(slot, value); - } - - bool receive(int slot) - { - return thread->receive(slot); - } - - Variant fetch(int slot) + namespace thread { - return thread->fetch(slot); - } - - Variant demand(int slot) - { - return thread->demand(slot); - } - - void remove(int slot) - { - thread->remove(slot); - } - - const char* getName() - { - return name.c_str(); - } - - bool isRunning() - { - return thread->isRunning(); - } - - void lock() - { - thread->lock(); - } - - void unlock() - { - thread->unlock(); - } - - const std::string name; - const std::string code; - - private: - jin::thread::Thread* thread; - - }; -} // thread -} // lua -} // jin
\ No newline at end of file + class Thread + { + public: + typedef JinEngine::MultiThread::Thread::Variant Variant; + typedef JinEngine::MultiThread::Thread::ThreadRunner ThreadRunner; + + Thread(std::string _name, std::string _code, ThreadRunner runner) + : name(_name) + , code(_code) + { + thread = new JinEngine::MultiThread::Thread(_name, runner); + } + + ~Thread() + { + delete thread; + } + + bool start(void* p) + { + return thread->start(p); + } + + void wait() + { + thread->wait(); + } + + void send(int slot, const Variant& value) + { + thread->send(slot, value); + } + + bool receive(int slot) + { + return thread->receive(slot); + } + + Variant fetch(int slot) + { + return thread->fetch(slot); + } + + Variant demand(int slot) + { + return thread->demand(slot); + } + + void remove(int slot) + { + thread->remove(slot); + } + + const char* getName() + { + return name.c_str(); + } + + bool isRunning() + { + return thread->isRunning(); + } + + void lock() + { + thread->lock(); + } + + void unlock() + { + thread->unlock(); + } + + const std::string name; + const std::string code; + + private: + JinEngine::MultiThread::Thread* thread; + + }; + + } // thread + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/time/time.cpp b/src/lua/modules/time/time.cpp index 39743b4..f6e6f26 100644 --- a/src/lua/modules/time/time.cpp +++ b/src/lua/modules/time/time.cpp @@ -2,37 +2,37 @@ #include <SDL2/SDL.h> #include "libjin/jin.h" -namespace jin -{ -namespace lua +namespace JinEngine { + namespace Lua + { - using namespace jin::time; + using namespace JinEngine::Time; - static int l_sec(lua_State* L) - { - luax_pushnumber(L, getSecond()); - return 1; - } + static int l_sec(lua_State* L) + { + luax_pushnumber(L, getSecond()); + return 1; + } - static int l_sleep(lua_State* L) - { - double sec = luax_checknumber(L, 1); - sleep(sec * 1000.0f); - return 0; - } + static int l_sleep(lua_State* L) + { + double sec = luax_checknumber(L, 1); + sleep(sec * 1000.0f); + return 0; + } - static const luaL_Reg f[] = { - { "second", l_sec }, - { "sleep", l_sleep }, - { 0, 0 }, - }; + static const luaL_Reg f[] = { + { "second", l_sec }, + { "sleep", l_sleep }, + { 0, 0 }, + }; - int luaopen_time(lua_State* L) - { - luax_newlib(L, f); - return 1; - } + int luaopen_time(lua_State* L) + { + luax_newlib(L, f); + return 1; + } -} // lua -} // jin
\ No newline at end of file + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file diff --git a/src/lua/modules/types.h b/src/lua/modules/types.h index 318f5fa..123604e 100644 --- a/src/lua/modules/types.h +++ b/src/lua/modules/types.h @@ -1,20 +1,25 @@ #ifndef __JIN_MODULES_TYPES_H #define __JIN_MODULES_TYPES_H -// graphics module -#define JIN_GRAPHICS_IMAGE "jin.graphics.Image" -#define JIN_GRAPHICS_SHADER "jin.graphics.Shader" -#define JIN_GRAPHICS_CANVAS "jin.graphics.Canvas" -#define JIN_GRAPHICS_FONT "jin.graphics.Font" - -// audio module -#define JIN_AUDIO_SOURCE "jin.Audio.Source" - -// thread module -#define JIN_THREAD_THREAD "jin.thread.Thread" - -// network module -#define JIN_NETWORK_SOCKET "jin.net.Socket" -#define JIN_NETWORK_BUFFER "jin.net.Buffer" +// graphics module +#define JIN_GRAPHICS_TEXTURE "Texture" +#define JIN_GRAPHICS_SHADER "Shader" +#define JIN_GRAPHICS_CANVAS "Canvas" +#define JIN_GRAPHICS_TEXT "Text" +#define JIN_GRAPHICS_TTFDATA "TTFData" +#define JIN_GRAPHICS_TTF "TTF" +#define JIN_GRAPHICS_TEXTUREFONT "TextureFont" +#define JIN_GRAPHICS_PAGE "Page" +#define JIN_GRAPHICS_BITMAP "Bitmap" + +// audio module +#define JIN_AUDIO_SOURCE "Source" + +// thread module +#define JIN_THREAD_THREAD "Thread" + +// network module +#define JIN_NETWORK_SOCKET "Socket" +#define JIN_NETWORK_BUFFER "Buffer" #endif
\ No newline at end of file diff --git a/src/lua/resources/font.ttf.h b/src/lua/resources/font.ttf.h index 519d723..bb0734f 100644 --- a/src/lua/resources/font.ttf.h +++ b/src/lua/resources/font.ttf.h @@ -1,3291 +1,365 @@ -/* font.ttf */ -static const unsigned char font_ttf[] = -{0,1,0,0,0,15,0,128,0,3,0,112,71,68,69,70,6,99,6,86,0,1,47,228,0,0,0,48,71,80, -79,83,21,171,160,97,0,1,48,20,0,0,25,64,71,83,85,66,114,98,110,249,0,1,73,84, -0,0,1,0,79,83,47,50,184,195,53,95,0,0,1,120,0,0,0,96,86,68,77,88,110,234,118, -79,0,0,16,160,0,0,5,224,99,109,97,112,181,231,186,55,0,0,22,128,0,0,14,170, -103,108,121,102,106,45,90,154,0,0,37,44,0,0,193,8,104,101,97,100,247,103,158, -41,0,0,0,252,0,0,0,54,104,104,101,97,16,38,141,60,0,0,1,52,0,0,0,36,104,109, -116,120,249,22,238,10,0,0,1,216,0,0,14,200,107,101,114,110,54,23,29,253,0,0, -237,156,0,0,32,214,108,111,99,97,165,22,115,246,0,0,230,52,0,0,7,102,109,97, -120,112,3,209,0,248,0,0,1,88,0,0,0,32,110,97,109,101,115,18,167,225,0,1,14, -116,0,0,3,36,112,111,115,116,65,210,41,113,0,1,17,152,0,0,30,73,0,1,0,0,0,1,0, -0,56,128,33,235,95,15,60,245,0,9,8,0,0,0,0,0,196,240,17,46,0,0,0,0,202,162,65, -188,255,85,253,206,9,99,8,115,0,0,0,9,0,2,0,0,0,0,0,0,0,1,0,0,7,108,254,12,0, -0,9,129,255,85,129,252,9,99,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,178,0,1,0,0,3, -178,0,151,0,22,0,95,0,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,3,3,147,1,144,0, -5,0,4,5,154,5,51,0,0,1,31,5,154,5,51,0,0,3,209,0,102,2,0,0,0,0,0,0,0,0,0,0,0, -0,0,224,0,2,239,72,0,32,91,20,160,0,32,0,0,0,0,112,121,114,115,0,64,0,32,255, -253,6,0,254,0,0,102,7,154,2,0,32,0,1,159,79,1,0,0,4,58,5,176,0,0,0,32,0,2,1, -253,0,0,0,0,0,0,1,253,0,0,1,253,0,0,4,169,0,127,5,218,0,104,4,252,0,64,1,189, -0,126,2,167,0,132,2,175,0,6,3,116,0,88,4,138,0,78,1,199,0,117,3,155,0,167,2, -36,0,161,3,82,0,16,4,129,0,113,4,129,0,195,4,129,0,133,4,129,0,115,4,129,0,72, -4,129,0,152,4,129,0,137,4,129,0,97,4,129,0,102,4,129,0,93,2,5,0,161,2,13,0, -162,4,16,0,71,4,129,0,152,4,48,0,136,3,206,0,58,7,41,0,96,5,15,0,43,5,15,0, -163,5,17,0,118,5,106,0,169,4,99,0,163,4,99,0,163,5,107,0,121,5,159,0,169,2,65, -0,190,4,99,0,74,5,15,0,163,4,99,0,168,6,229,0,163,5,159,0,169,5,116,0,113,5, -15,0,163,5,147,0,113,5,17,0,165,4,228,0,121,4,201,0,37,5,106,0,147,5,15,0,22, -6,227,0,37,5,15,0,66,5,15,0,40,4,201,0,97,2,40,0,143,3,78,0,39,2,40,0,11,3,88, -0,61,3,163,0,4,2,129,0,82,4,102,0,106,4,140,0,143,4,48,0,97,4,140,0,98,4,48,0, -97,2,112,0,28,4,140,0,108,4,140,0,143,2,4,0,159,2,18,255,190,4,26,0,144,2,4,0, -159,6,254,0,143,4,140,0,143,4,140,0,97,4,140,0,143,4,140,0,98,2,205,0,143,4, -47,0,103,2,141,0,26,4,140,0,139,4,6,0,46,6,14,0,45,4,6,0,46,4,6,0,26,4,6,0,94, -2,184,0,63,1,251,0,145,2,184,0,21,5,111,0,128,1,252,0,144,4,98,0,97,4,170,0, -70,5,176,0,104,4,219,0,30,1,243,0,145,4,235,0,90,4,21,0,160,6,68,0,88,3,149,0, -120,3,198,0,77,4,113,0,127,6,68,0,88,3,182,0,103,2,251,0,128,4,73,0,99,3,100, -0,113,3,108,0,106,2,142,0,131,4,140,0,153,3,238,0,63,2,28,0,161,1,253,0,119,2, -45,0,95,3,165,0,120,3,198,0,166,5,175,0,184,6,172,0,184,6,245,0,122,3,246,0, -117,7,207,0,14,4,72,0,88,5,106,0,108,4,185,0,163,4,170,0,137,6,253,0,88,4,178, -0,72,4,146,0,71,4,142,0,97,4,162,0,153,5,162,0,30,2,3,0,153,4,120,0,153,4,53, -0,40,2,46,0,37,5,136,0,160,4,140,0,143,7,168,0,104,7,113,0,97,2,165,0,19,2,4, -0,159,2,191,255,233,5,243,0,108,4,207,0,97,6,97,0,147,5,186,0,139,2,11,255, -188,3,211,0,110,3,154,0,85,3,108,0,129,2,44,0,160,2,184,0,165,2,50,0,18,3,211, -0,135,2,250,0,100,2,161,0,182,2,14,0,36,2,14,0,210,3,191,0,135,0,0,255,187,2, -14,0,148,4,21,0,161,2,29,0,161,4,99,0,163,5,167,0,30,5,116,0,113,5,65,0,49,4, -149,0,123,5,159,0,168,4,149,0,70,5,159,0,84,5,136,0,87,5,86,0,112,4,134,0,98, -4,189,0,157,4,7,0,46,4,140,0,97,4,79,0,98,4,47,0,115,4,140,0,143,4,141,0,119, -2,160,0,197,4,140,0,56,4,19,0,45,4,165,0,79,4,140,0,143,4,78,0,98,4,140,0,97, -4,48,0,81,4,140,0,141,5,170,0,83,5,160,0,91,6,205,0,108,5,234,0,57,5,106,0, -135,8,153,0,69,8,153,0,168,5,254,0,73,5,160,0,169,5,12,0,163,6,39,0,54,6,151, -0,26,5,105,0,120,5,159,0,173,5,159,0,69,5,17,0,66,5,253,0,161,5,117,0,147,8, -31,0,164,8,100,0,164,5,171,0,1,6,213,0,163,5,10,0,163,5,105,0,181,7,33,0,190, -4,187,0,44,4,109,0,97,4,140,0,144,2,231,0,143,5,17,0,69,5,193,0,26,4,79,0,100, -4,140,0,143,4,96,0,153,4,109,0,65,5,248,0,153,4,140,0,143,4,140,0,143,4,24,0, -71,7,34,0,98,4,194,0,143,4,107,0,115,6,109,0,143,6,196,0,143,4,119,255,244,6, -81,0,153,4,89,0,153,4,78,0,99,6,135,0,153,4,139,0,117,4,140,255,242,4,79,0,97, -6,246,0,65,6,245,0,143,4,140,255,242,4,140,0,143,6,206,0,108,6,88,0,127,5,117, -0,113,4,141,0,97,4,141,0,212,4,185,0,251,4,175,1,231,4,174,1,231,4,170,0,105, -4,170,0,105,5,136,0,179,6,124,0,187,2,12,0,145,2,4,0,160,2,28,0,168,1,188,0, -85,3,97,0,145,3,97,0,160,3,88,0,176,4,105,0,70,4,146,0,87,2,183,0,137,5,100,0, -161,7,164,0,64,2,103,0,88,2,103,0,144,3,165,0,59,3,173,0,71,4,170,0,70,4,64,0, -79,5,4,0,103,6,191,0,107,7,86,0,110,7,134,0,111,6,223,0,107,4,162,0,72,5,156, -0,168,4,178,0,70,4,146,0,168,4,215,0,63,8,47,0,104,2,14,255,188,4,48,0,152,4, -56,0,158,4,64,0,154,0,0,0,169,0,0,0,93,4,9,0,125,4,10,255,85,4,15,0,110,4,10, -0,110,3,164,0,129,3,164,0,129,3,165,0,129,1,145,0,96,2,4,0,161,2,4,255,190,3, -12,255,160,3,38,0,113,4,69,0,83,4,170,0,105,4,170,0,73,4,170,0,132,4,170,0, -142,3,251,0,37,4,170,0,130,4,170,0,92,4,170,0,123,4,186,0,39,3,165,0,109,4, -121,0,153,4,146,0,112,4,170,0,153,4,71,0,153,4,31,0,153,4,211,0,112,4,251,0, -153,2,3,0,153,4,15,0,64,4,97,0,153,3,189,0,153,5,248,0,153,5,28,0,153,4,203,0, -112,4,121,0,153,4,227,0,112,4,173,0,153,4,113,0,93,4,48,0,71,5,4,0,137,4,187, -0,39,6,2,0,63,4,137,0,55,4,97,0,30,4,64,0,78,4,121,0,120,2,94,0,78,3,229,0,89, -4,22,0,90,4,104,0,71,4,31,0,90,4,48,0,120,3,189,0,71,4,48,0,88,4,40,0,71,3, -165,0,120,2,45,0,95,3,91,0,113,3,108,0,106,3,148,0,87,3,124,0,114,3,124,0,120, -3,17,0,95,3,132,0,112,3,108,0,104,2,8,0,120,5,15,0,22,4,7,0,46,5,56,0,118,4, -75,0,98,5,15,0,163,4,96,0,153,4,214,0,163,4,8,0,143,8,38,0,168,6,252,0,143,5, -145,0,89,4,66,0,94,7,185,0,169,5,176,0,143,7,55,0,63,5,147,0,73,6,203,0,77,4, -191,255,223,5,118,0,138,3,160,0,116,6,211,0,74,5,199,0,49,7,45,0,191,5,250,0, -151,4,211,0,43,4,73,0,13,8,3,0,169,6,162,0,143,6,118,0,65,7,194,0,69,4,247,0, -118,4,30,0,98,5,174,0,36,5,33,0,70,6,164,0,91,6,229,0,98,6,87,0,54,5,44,0,49, -4,75,0,80,4,9,0,123,5,7,0,91,5,105,0,156,4,100,0,163,3,99,0,143,4,8,0,41,5,15, -0,163,4,104,0,153,5,118,0,147,4,108,0,115,4,140,0,143,5,159,0,169,4,37,0,74,3, -218,0,73,7,13,0,209,6,13,0,186,5,13,0,163,4,139,0,143,4,140,0,95,2,7,0,160,6, -72,0,78,4,65,255,234,5,116,0,113,4,140,0,97,6,210,0,108,6,91,0,127,6,223,0, -149,5,236,0,149,9,22,0,190,7,227,0,153,4,20,0,0,8,41,0,0,4,20,0,0,8,41,0,0,2, -185,0,0,2,10,0,0,1,92,0,0,4,127,0,0,2,48,0,0,1,162,0,0,0,209,0,0,8,52,0,91,8, -53,0,92,3,167,0,5,5,116,0,113,4,140,0,97,0,0,0,0,0,0,0,0,4,241,0,113,5,2,0, -112,8,28,0,59,7,216,0,77,3,96,0,122,5,24,0,152,3,78,0,105,5,233,0,124,8,204,0, -169,3,210,0,106,6,146,0,164,4,140,0,98,3,202,0,161,3,108,0,129,1,253,127,255, -5,106,0,34,5,106,0,34,4,140,0,18,4,201,0,37,3,155,0,167,5,15,0,43,5,15,0,43,5, -15,0,43,5,15,0,43,5,15,0,43,5,15,0,43,5,15,0,43,5,17,0,118,4,99,0,163,4,99,0, -163,4,99,0,163,4,99,0,163,2,65,255,221,2,65,0,190,2,65,255,179,2,65,255,192,5, -159,0,169,5,116,0,113,5,116,0,113,5,116,0,113,5,116,0,113,5,116,0,113,5,106,0, -147,5,106,0,147,5,106,0,147,5,106,0,147,5,15,0,40,4,102,0,106,4,102,0,106,4, -102,0,106,4,102,0,106,4,102,0,106,4,102,0,106,4,102,0,106,4,48,0,97,4,48,0,97, -4,48,0,97,4,48,0,97,4,48,0,97,2,3,255,184,2,3,0,153,2,3,255,142,2,3,255,155,4, -140,0,143,4,140,0,97,4,140,0,97,4,140,0,97,4,140,0,97,4,140,0,97,4,140,0,139, -4,140,0,139,4,140,0,139,4,140,0,139,4,6,0,26,4,6,0,26,5,15,0,43,4,102,0,106,5, -15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,5,17,0,118,4,48,0,97,5,17,0,118,4, -48,0,97,5,17,0,118,4,48,0,97,5,17,0,118,4,48,0,97,5,106,0,169,4,140,0,98,4,99, -0,163,4,48,0,97,4,99,0,163,4,48,0,97,4,99,0,163,4,48,0,97,4,99,0,163,4,48,0, -97,4,99,0,163,4,48,0,97,5,107,0,121,4,140,0,108,5,107,0,121,4,140,0,108,5,107, -0,121,4,140,0,108,5,107,0,121,4,140,0,108,5,159,0,169,4,140,255,127,2,65,255, -199,2,3,255,162,2,65,255,171,2,3,255,134,2,65,255,247,2,3,255,210,2,65,0,57,2, -4,0,27,2,65,0,180,6,164,0,190,4,22,0,159,4,99,0,74,2,11,255,160,5,15,0,163,4, -26,0,144,4,99,0,168,2,4,0,159,4,99,0,168,2,4,0,121,4,99,0,168,2,4,0,159,4,99, -0,156,2,4,0,150,5,159,0,169,4,140,0,143,5,159,0,169,4,140,0,143,5,159,0,169,4, -140,0,143,4,140,0,143,5,116,0,113,4,140,0,97,5,116,0,113,4,140,0,97,5,116,0, -113,4,140,0,97,5,17,0,165,2,205,0,143,5,17,0,165,2,205,0,119,5,17,0,165,2,205, -0,45,4,228,0,121,4,47,0,103,4,228,0,121,4,47,0,103,4,228,0,121,4,47,0,103,4, -228,0,121,4,47,0,103,4,201,0,37,2,141,0,26,4,201,0,37,2,141,0,26,5,106,0,147, -4,140,0,139,5,106,0,147,4,140,0,139,5,106,0,147,4,140,0,139,5,106,0,147,4,140, -0,139,5,106,0,147,4,140,0,139,5,106,0,147,4,140,0,139,6,227,0,37,6,14,0,45,5, -15,0,40,4,6,0,26,5,15,0,40,4,201,0,97,4,6,0,94,4,201,0,97,4,6,0,94,4,201,0,97, -4,6,0,94,7,207,0,14,6,253,0,88,5,106,0,108,4,142,0,97,4,228,0,121,4,47,0,103, -5,15,0,43,4,99,0,163,5,159,0,169,2,65,0,185,5,116,0,113,5,15,0,40,5,86,0,112, -2,160,255,204,5,15,0,43,5,15,0,163,4,99,0,163,4,201,0,97,5,159,0,169,2,65,0, -190,5,15,0,163,6,229,0,163,5,159,0,169,5,116,0,113,5,15,0,163,4,201,0,37,5,15, -0,40,5,15,0,66,2,65,255,192,5,15,0,40,4,134,0,98,4,79,0,98,4,140,0,143,2,160, -0,197,4,140,0,141,4,120,0,153,4,140,0,97,4,140,0,153,4,6,0,46,2,160,255,205,4, -140,0,141,4,140,0,97,4,140,0,141,6,205,0,108,4,99,0,163,4,99,0,163,4,228,0, -121,2,65,0,190,2,65,255,192,4,99,0,74,2,142,0,131,5,17,0,66,5,15,0,163,5,15,0, -43,5,15,0,163,4,99,0,163,4,99,0,163,5,159,0,173,6,229,0,163,5,159,0,169,5,116, -0,113,5,159,0,168,5,15,0,163,5,17,0,118,4,201,0,37,5,159,0,84,5,15,0,66,4,102, -0,106,4,48,0,97,4,140,0,143,4,140,0,97,4,140,0,143,4,48,0,97,4,6,0,26,4,6,0, -46,4,48,0,97,2,231,0,143,4,47,0,103,2,4,0,159,2,3,255,155,2,18,255,190,4,96,0, -153,4,6,0,26,6,227,0,37,6,14,0,45,6,227,0,37,6,14,0,45,6,227,0,37,6,14,0,45,5, -15,0,40,4,6,0,26,1,189,0,126,2,221,0,126,4,54,0,171,4,116,0,28,4,116,0,28,2, -11,255,158,2,4,0,160,6,229,0,163,6,254,0,143,5,15,0,43,4,102,0,106,5,116,0, -113,6,228,0,28,6,228,0,28,4,99,0,163,5,159,0,173,4,48,0,97,4,140,0,143,5,136, -0,87,5,160,0,91,5,15,0,22,4,7,0,46,8,116,0,97,9,129,0,113,5,105,0,120,4,79,0, -100,5,17,0,118,4,48,0,97,5,15,0,40,4,7,0,46,2,65,0,190,6,151,0,26,5,193,0,26, -2,65,0,190,5,15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,7,207,0,14,6,253,0,88, -4,99,0,163,4,48,0,97,5,145,0,89,4,66,0,94,6,151,0,26,5,193,0,26,5,105,0,120,4, -79,0,100,5,159,0,173,4,140,0,143,5,159,0,173,4,140,0,143,5,116,0,113,4,140,0, -97,5,117,0,113,4,141,0,97,5,117,0,113,4,141,0,97,5,105,0,181,4,78,0,99,5,17,0, -66,4,6,0,26,5,17,0,66,4,6,0,26,5,17,0,66,4,6,0,26,5,117,0,147,4,107,0,115,6, -213,0,163,6,81,0,153,5,15,0,66,4,6,0,46,4,140,0,98,5,159,0,69,4,109,0,65,5,15, -0,43,4,102,0,106,5,15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,5,15,0,0,4,102, -255,163,5,15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,5, -15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,5,15,0,43,4,102,0,106,5,15,0,43,4, -102,0,106,5,15,0,43,4,102,0,106,4,99,0,163,4,48,0,97,4,99,0,163,4,48,0,97,4, -99,0,163,4,48,0,97,4,99,0,163,4,48,0,97,4,99,255,220,4,48,255,165,4,99,0,163, -4,48,0,97,4,99,0,163,4,48,0,97,4,99,0,163,4,48,0,97,2,65,0,190,2,3,0,153,2,65, -0,180,2,4,0,149,5,116,0,113,4,140,0,97,5,116,0,113,4,140,0,97,5,116,0,113,4, -140,0,97,5,116,0,51,4,140,255,190,5,116,0,113,4,140,0,97,5,116,0,113,4,140,0, -97,5,116,0,113,4,140,0,97,5,243,0,108,4,207,0,97,5,243,0,108,4,207,0,97,5,243, -0,108,4,207,0,97,5,243,0,108,4,140,0,97,5,243,0,108,4,207,0,97,5,106,0,147,4, -140,0,139,5,106,0,147,4,140,0,139,6,97,0,147,5,186,0,139,6,97,0,147,5,186,0, -139,6,97,0,147,5,186,0,139,6,97,0,147,5,186,0,139,6,97,0,147,5,186,0,139,5,15, -0,40,4,6,0,26,5,15,0,40,4,6,0,26,5,15,0,40,4,6,0,26,4,140,0,98,5,15,0,163,4, -24,0,71,5,159,0,169,4,140,0,143,4,201,0,37,4,24,0,71,5,15,0,66,4,6,0,46,5,117, -0,147,4,107,0,115,5,117,0,147,4,107,0,115,4,99,0,163,2,231,0,143,6,151,0,26,5, -193,0,26,6,203,0,77,4,191,255,223,4,140,0,143,4,89,255,156,5,10,255,175,4,89, -255,156,5,10,255,175,4,99,255,205,2,231,255,213,5,15,255,179,4,26,255,157,5, -159,0,173,4,140,0,143,5,159,0,169,4,140,0,143,6,229,0,163,5,248,0,153,4,109,0, -65,5,159,0,69,5,15,0,40,4,7,0,46,5,15,0,66,4,6,0,46,4,99,255,206,2,231,255, -214,6,206,0,108,6,88,0,127,4,79,0,98,4,99,255,237,6,124,0,187,4,252,0,70,2,27, -0,171,2,221,0,126,0,0,0,1,0,1,1,1,1,1,0,12,0,248,8,255,0,8,0,8,255,254,0,9,0, -9,255,253,0,10,0,10,255,253,0,11,0,11,255,253,0,12,0,12,255,253,0,13,0,13,255, -252,0,14,0,14,255,252,0,15,0,15,255,252,0,16,0,16,255,252,0,17,0,17,255,251,0, -18,0,18,255,251,0,19,0,19,255,251,0,20,0,20,255,251,0,21,0,20,255,250,0,22,0, -21,255,250,0,23,0,22,255,250,0,24,0,23,255,250,0,25,0,24,255,249,0,26,0,25, -255,249,0,27,0,26,255,249,0,28,0,27,255,249,0,29,0,28,255,248,0,30,0,29,255, -248,0,31,0,30,255,248,0,32,0,31,255,248,0,33,0,32,255,247,0,34,0,33,255,247,0, -35,0,34,255,247,0,36,0,35,255,247,0,37,0,36,255,246,0,38,0,37,255,246,0,39,0, -38,255,246,0,40,0,39,255,246,0,41,0,39,255,245,0,42,0,40,255,245,0,43,0,41, -255,245,0,44,0,42,255,245,0,45,0,43,255,244,0,46,0,44,255,244,0,47,0,45,255, -244,0,48,0,46,255,244,0,49,0,47,255,243,0,50,0,48,255,243,0,51,0,49,255,243,0, -52,0,50,255,243,0,53,0,51,255,242,0,54,0,52,255,242,0,55,0,53,255,242,0,56,0, -54,255,242,0,57,0,55,255,241,0,58,0,56,255,241,0,59,0,57,255,241,0,60,0,58, -255,241,0,61,0,58,255,240,0,62,0,59,255,240,0,63,0,60,255,240,0,64,0,61,255, -240,0,65,0,62,255,239,0,66,0,63,255,239,0,67,0,64,255,239,0,68,0,65,255,239,0, -69,0,66,255,238,0,70,0,67,255,238,0,71,0,68,255,238,0,72,0,69,255,238,0,73,0, -70,255,237,0,74,0,71,255,237,0,75,0,72,255,237,0,76,0,73,255,237,0,77,0,74, -255,236,0,78,0,75,255,236,0,79,0,76,255,236,0,80,0,77,255,236,0,81,0,77,255, -235,0,82,0,78,255,235,0,83,0,79,255,235,0,84,0,80,255,235,0,85,0,81,255,234,0, -86,0,82,255,234,0,87,0,83,255,234,0,88,0,84,255,234,0,89,0,85,255,233,0,90,0, -86,255,233,0,91,0,87,255,233,0,92,0,88,255,233,0,93,0,89,255,232,0,94,0,90, -255,232,0,95,0,91,255,232,0,96,0,92,255,232,0,97,0,93,255,231,0,98,0,94,255, -231,0,99,0,95,255,231,0,100,0,96,255,231,0,101,0,96,255,230,0,102,0,97,255, -230,0,103,0,98,255,230,0,104,0,99,255,230,0,105,0,100,255,229,0,106,0,101,255, -229,0,107,0,102,255,229,0,108,0,103,255,229,0,109,0,104,255,228,0,110,0,105, -255,228,0,111,0,106,255,228,0,112,0,107,255,228,0,113,0,108,255,227,0,114,0, -109,255,227,0,115,0,110,255,227,0,116,0,111,255,227,0,117,0,112,255,226,0,118, -0,113,255,226,0,119,0,114,255,226,0,120,0,115,255,226,0,121,0,115,255,225,0, -122,0,116,255,225,0,123,0,117,255,225,0,124,0,118,255,225,0,125,0,119,255,224, -0,126,0,120,255,224,0,127,0,121,255,224,0,128,0,122,255,224,0,129,0,123,255, -223,0,130,0,124,255,223,0,131,0,125,255,223,0,132,0,126,255,223,0,133,0,127, -255,222,0,134,0,128,255,222,0,135,0,129,255,222,0,136,0,130,255,222,0,137,0, -131,255,221,0,138,0,132,255,221,0,139,0,133,255,221,0,140,0,134,255,221,0,141, -0,134,255,220,0,142,0,135,255,220,0,143,0,136,255,220,0,144,0,137,255,220,0, -145,0,138,255,219,0,146,0,139,255,219,0,147,0,140,255,219,0,148,0,141,255,219, -0,149,0,142,255,218,0,150,0,143,255,218,0,151,0,144,255,218,0,152,0,145,255, -218,0,153,0,146,255,217,0,154,0,147,255,217,0,155,0,148,255,217,0,156,0,149, -255,217,0,157,0,150,255,216,0,158,0,151,255,216,0,159,0,152,255,216,0,160,0, -153,255,216,0,161,0,153,255,215,0,162,0,154,255,215,0,163,0,155,255,215,0,164, -0,156,255,215,0,165,0,157,255,214,0,166,0,158,255,214,0,167,0,159,255,214,0, -168,0,160,255,214,0,169,0,161,255,213,0,170,0,162,255,213,0,171,0,163,255,213, -0,172,0,164,255,213,0,173,0,165,255,212,0,174,0,166,255,212,0,175,0,167,255, -212,0,176,0,168,255,212,0,177,0,169,255,211,0,178,0,170,255,211,0,179,0,171, -255,211,0,180,0,172,255,211,0,181,0,172,255,210,0,182,0,173,255,210,0,183,0, -174,255,210,0,184,0,175,255,210,0,185,0,176,255,209,0,186,0,177,255,209,0,187, -0,178,255,209,0,188,0,179,255,209,0,189,0,180,255,208,0,190,0,181,255,208,0, -191,0,182,255,208,0,192,0,183,255,208,0,193,0,184,255,207,0,194,0,185,255,207, -0,195,0,186,255,207,0,196,0,187,255,207,0,197,0,188,255,206,0,198,0,189,255, -206,0,199,0,190,255,206,0,200,0,191,255,206,0,201,0,191,255,205,0,202,0,192, -255,205,0,203,0,193,255,205,0,204,0,194,255,205,0,205,0,195,255,204,0,206,0, -196,255,204,0,207,0,197,255,204,0,208,0,198,255,204,0,209,0,199,255,203,0,210, -0,200,255,203,0,211,0,201,255,203,0,212,0,202,255,203,0,213,0,203,255,202,0, -214,0,204,255,202,0,215,0,205,255,202,0,216,0,206,255,202,0,217,0,207,255,201, -0,218,0,208,255,201,0,219,0,209,255,201,0,220,0,210,255,201,0,221,0,210,255, -200,0,222,0,211,255,200,0,223,0,212,255,200,0,224,0,213,255,200,0,225,0,214, -255,199,0,226,0,215,255,199,0,227,0,216,255,199,0,228,0,217,255,199,0,229,0, -218,255,198,0,230,0,219,255,198,0,231,0,220,255,198,0,232,0,221,255,198,0,233, -0,222,255,197,0,234,0,223,255,197,0,235,0,224,255,197,0,236,0,225,255,197,0, -237,0,226,255,196,0,238,0,227,255,196,0,239,0,228,255,196,0,240,0,229,255,196, -0,241,0,229,255,195,0,242,0,230,255,195,0,243,0,231,255,195,0,244,0,232,255, -195,0,245,0,233,255,194,0,246,0,234,255,194,0,247,0,235,255,194,0,248,0,236, -255,194,0,249,0,237,255,193,0,250,0,238,255,193,0,251,0,239,255,193,0,252,0, -240,255,193,0,253,0,241,255,192,0,254,0,242,255,192,0,255,0,243,255,192,0,0,0, -3,0,0,0,3,0,0,8,104,0,1,0,0,0,0,0,28,0,3,0,1,0,0,2,38,0,6,2,10,0,0,0,0,1,0,0, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,3,3,176,3,177,3,175,0,4,0,5, -0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0, -22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37, -0,38,0,39,0,40,0,41,0,42,0,43,0,44,0,45,0,46,0,47,0,48,0,49,0,50,0,51,0,52,0, -53,0,54,0,55,0,56,0,57,0,58,0,59,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68, -0,69,0,70,0,71,0,72,0,73,0,74,0,75,0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0, -84,0,85,0,86,0,87,0,88,0,89,0,90,0,91,0,92,0,93,0,94,0,0,1,222,1,223,1,225,1, -227,1,234,1,239,1,243,1,246,1,245,1,247,1,249,1,248,1,250,1,252,1,254,1,253,1, -255,2,0,2,2,2,1,2,3,2,4,2,5,2,7,2,6,2,8,2,10,2,9,2,12,2,11,2,13,2,14,1,14,0, -109,0,96,0,97,0,101,1,16,0,115,0,129,0,107,0,103,1,25,0,113,0,102,1,37,0,125, -0,127,1,35,0,110,1,38,1,39,0,99,0,114,1,30,1,32,1,31,0,189,1,36,0,104,0,119,0, -177,0,130,0,133,0,124,0,95,0,106,1,34,0,146,0,0,0,169,0,105,0,120,1,17,0,3,1, -218,1,221,1,238,0,142,0,143,1,5,1,6,1,11,1,12,1,7,1,8,0,132,1,155,2,16,2,123, -1,21,1,24,1,19,1,20,2,224,2,225,1,15,0,116,1,9,1,13,1,18,1,220,1,228,1,219,1, -229,1,226,1,231,1,232,1,233,1,230,1,236,1,237,0,0,1,235,1,241,1,242,1,240,0, -136,0,152,0,158,0,108,0,154,0,155,0,156,0,117,0,159,0,157,0,153,0,4,6,66,0,0, -0,210,0,128,0,6,0,82,0,35,0,126,0,160,0,172,0,173,0,191,0,198,0,207,0,230,0, -239,0,254,1,15,1,17,1,37,1,39,1,48,1,56,1,64,1,83,1,101,1,103,1,126,1,127,1, -146,1,161,1,176,1,240,1,251,1,255,2,25,2,55,2,188,2,199,2,221,2,243,3,1,3,3,3, -15,3,138,3,140,3,146,3,161,3,176,3,185,3,201,3,206,3,210,3,214,4,37,4,47,4,69, -4,79,4,130,4,134,4,206,4,215,4,225,4,245,5,19,30,1,30,63,30,133,30,241,30,243, -30,249,31,77,32,10,32,11,32,21,32,23,32,30,32,34,32,38,32,48,32,51,32,58,32, -60,32,68,32,116,32,127,32,164,32,167,32,172,33,5,33,19,33,22,33,34,33,38,33, -46,33,94,34,2,34,6,34,15,34,18,34,26,34,30,34,43,34,96,34,101,37,202,251,2, -251,4,254,255,255,253,255,255,0,0,0,32,0,36,0,160,0,161,0,173,0,174,0,192,0, -199,0,208,0,231,0,240,0,255,1,16,1,18,1,38,1,40,1,49,1,57,1,65,1,84,1,102,1, -104,1,127,1,146,1,160,1,175,1,240,1,250,1,252,2,24,2,55,2,188,2,198,2,216,2, -243,3,0,3,3,3,15,3,132,3,140,3,142,3,147,3,163,3,177,3,186,3,202,3,209,3,214, -4,0,4,38,4,48,4,70,4,80,4,131,4,136,4,207,4,216,4,226,4,246,30,0,30,62,30,128, -30,160,30,242,30,244,31,77,32,0,32,11,32,19,32,23,32,24,32,32,32,37,32,48,32, -50,32,57,32,60,32,68,32,116,32,127,32,163,32,167,32,171,33,5,33,19,33,22,33, -34,33,38,33,46,33,91,34,2,34,6,34,15,34,17,34,26,34,30,34,43,34,96,34,100,37, -202,251,1,251,3,254,255,255,252,255,255,0,0,255,224,0,0,255,190,0,0,255,189,0, -0,1,26,0,0,1,21,0,0,1,17,0,0,1,15,0,0,1,13,0,0,1,11,0,0,1,5,0,0,1,3,0,0,255,0, -254,243,254,230,0,242,0,0,0,134,0,110,254,96,0,39,253,210,253,194,253,173,253, -161,253,160,253,149,0,0,255,0,254,255,0,0,0,0,253,1,0,0,254,223,0,0,253,212,0, -0,252,173,0,0,252,165,0,0,252,124,0,0,254,47,0,0,254,43,0,0,228,230,228,166, -228,85,228,136,227,233,228,134,227,155,225,180,225,185,0,0,0,0,224,239,224, -238,0,0,224,226,226,171,224,218,226,163,224,209,224,162,225,75,0,0,225,41,0,0, -224,200,224,188,224,184,223,247,223,139,224,157,223,191,223,28,222,163,223,16, -223,15,223,8,223,5,222,249,222,197,222,194,219,209,7,223,7,230,2,198,1,195,0, -1,0,210,0,0,0,214,0,0,0,212,0,0,0,210,0,0,0,220,0,0,1,6,0,0,1,32,0,0,1,32,0,0, -1,32,0,0,1,44,0,0,1,78,0,0,1,78,0,0,0,0,0,0,0,0,1,70,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1,52,0,0,0,0,1,60,1,88,0,0,1,112,0,0,1,140,0,0,1,140,0,0,1, -212,0,0,1,252,0,0,2,94,0,0,2,232,0,0,2,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,32,3,36,0,0,0,0,3,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,20,0,0,3,20,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,3,3,176,3,177,3,175,1,212,1,217,1,218,1,219,1,220,1,221,1,222,1,223,0,125,1, -214,1,234,1,235,1,236,1,237,1,238,1,239,0,126,0,127,1,240,1,241,1,242,1,243,1, -244,0,128,0,129,1,245,1,246,1,247,1,248,1,249,1,250,0,130,0,131,2,5,2,6,2,7,2, -8,2,9,2,10,0,132,0,133,2,11,2,12,2,13,2,14,2,15,0,134,1,213,1,209,0,135,1,215, -0,136,2,62,2,63,2,64,2,65,2,66,2,67,0,137,0,138,0,139,2,76,2,77,2,78,2,79,2, -80,2,81,2,82,0,140,0,141,2,83,2,84,2,85,2,86,2,87,2,88,0,142,0,143,1,216,0, -144,0,145,1,224,1,251,0,165,0,166,2,136,0,167,2,137,2,138,2,139,0,168,0,169,2, -146,2,147,2,148,0,170,2,149,2,150,0,171,2,151,2,152,0,172,2,153,0,173,2,154,0, -174,2,155,2,156,0,175,2,157,0,176,0,177,2,158,2,159,2,160,2,161,2,162,2,163,2, -164,2,165,0,187,2,167,2,168,0,188,2,166,0,189,0,190,0,191,0,192,0,193,0,194,0, -195,1,168,0,196,0,197,1,198,1,171,2,235,2,174,0,198,2,175,0,199,2,176,2,177,2, -178,2,179,0,200,0,201,0,202,2,180,2,236,2,181,0,203,2,183,0,204,2,184,2,185,0, -205,2,186,0,206,0,207,0,208,2,187,2,182,0,209,2,188,2,189,2,190,2,191,2,192,2, -193,2,194,0,210,2,195,2,196,2,197,0,221,0,222,0,223,0,224,2,198,0,225,0,226,0, -227,2,199,0,228,0,229,0,230,0,231,2,200,0,232,2,201,2,202,0,233,2,203,0,234,2, -204,2,237,2,205,0,245,2,206,0,246,2,207,2,208,2,209,2,210,0,247,0,248,0,249,2, -211,2,238,2,212,0,250,0,251,0,252,3,151,3,150,1,133,1,134,1,135,1,136,1,164,1, -165,1,176,1,177,1,178,1,179,1,162,1,163,2,239,2,240,0,253,0,254,1,111,1,112,2, -241,2,242,2,244,2,243,1,172,1,173,3,170,3,171,1,174,1,175,1,113,1,114,1,199,1, -200,1,201,3,156,3,157,3,149,3,148,1,166,1,167,1,153,1,154,3,152,3,153,1,117,1, -118,3,143,3,144,2,245,2,246,3,129,3,130,1,156,1,157,3,154,3,155,1,131,1,132,3, -131,3,132,1,123,1,124,1,119,1,120,1,194,1,195,2,247,2,248,3,133,3,134,2,249,2, -250,3,164,3,165,3,135,3,136,1,125,1,126,3,137,3,138,1,158,1,159,1,129,3,147,1, -127,1,128,3,145,3,146,2,251,2,252,2,253,1,115,1,116,3,162,3,163,1,161,1,160,3, -158,3,159,3,139,3,140,3,160,3,161,1,121,1,122,3,7,3,8,3,9,3,10,3,11,3,12,1,3, -1,4,3,141,3,142,3,33,3,34,3,168,3,169,3,35,3,36,3,166,3,167,1,151,3,37,1,145, -1,146,1,147,1,148,1,149,1,150,1,140,1,139,1,137,1,138,1,141,1,142,1,143,1,144, -1,152,3,172,3,38,3,39,1,5,1,6,3,174,1,193,1,210,1,17,3,173,1,23,3,128,1,24,0, -4,6,66,0,0,0,210,0,128,0,6,0,82,0,35,0,126,0,160,0,172,0,173,0,191,0,198,0, -207,0,230,0,239,0,254,1,15,1,17,1,37,1,39,1,48,1,56,1,64,1,83,1,101,1,103,1, -126,1,127,1,146,1,161,1,176,1,240,1,251,1,255,2,25,2,55,2,188,2,199,2,221,2, -243,3,1,3,3,3,15,3,138,3,140,3,146,3,161,3,176,3,185,3,201,3,206,3,210,3,214, -4,37,4,47,4,69,4,79,4,130,4,134,4,206,4,215,4,225,4,245,5,19,30,1,30,63,30, -133,30,241,30,243,30,249,31,77,32,10,32,11,32,21,32,23,32,30,32,34,32,38,32, -48,32,51,32,58,32,60,32,68,32,116,32,127,32,164,32,167,32,172,33,5,33,19,33, -22,33,34,33,38,33,46,33,94,34,2,34,6,34,15,34,18,34,26,34,30,34,43,34,96,34, -101,37,202,251,2,251,4,254,255,255,253,255,255,0,0,0,32,0,36,0,160,0,161,0, -173,0,174,0,192,0,199,0,208,0,231,0,240,0,255,1,16,1,18,1,38,1,40,1,49,1,57,1, -65,1,84,1,102,1,104,1,127,1,146,1,160,1,175,1,240,1,250,1,252,2,24,2,55,2,188, -2,198,2,216,2,243,3,0,3,3,3,15,3,132,3,140,3,142,3,147,3,163,3,177,3,186,3, -202,3,209,3,214,4,0,4,38,4,48,4,70,4,80,4,131,4,136,4,207,4,216,4,226,4,246, -30,0,30,62,30,128,30,160,30,242,30,244,31,77,32,0,32,11,32,19,32,23,32,24,32, -32,32,37,32,48,32,50,32,57,32,60,32,68,32,116,32,127,32,163,32,167,32,171,33, -5,33,19,33,22,33,34,33,38,33,46,33,91,34,2,34,6,34,15,34,17,34,26,34,30,34,43, -34,96,34,100,37,202,251,1,251,3,254,255,255,252,255,255,0,0,255,224,0,0,255, -190,0,0,255,189,0,0,1,26,0,0,1,21,0,0,1,17,0,0,1,15,0,0,1,13,0,0,1,11,0,0,1,5, -0,0,1,3,0,0,255,0,254,243,254,230,0,242,0,0,0,134,0,110,254,96,0,39,253,210, -253,194,253,173,253,161,253,160,253,149,0,0,255,0,254,255,0,0,0,0,253,1,0,0, -254,223,0,0,253,212,0,0,252,173,0,0,252,165,0,0,252,124,0,0,254,47,0,0,254,43, -0,0,228,230,228,166,228,85,228,136,227,233,228,134,227,155,225,180,225,185,0, -0,0,0,224,239,224,238,0,0,224,226,226,171,224,218,226,163,224,209,224,162,225, -75,0,0,225,41,0,0,224,200,224,188,224,184,223,247,223,139,224,157,223,191,223, -28,222,163,223,16,223,15,223,8,223,5,222,249,222,197,222,194,219,209,7,223,7, -230,2,198,1,195,0,1,0,210,0,0,0,214,0,0,0,212,0,0,0,210,0,0,0,220,0,0,1,6,0,0, -1,32,0,0,1,32,0,0,1,32,0,0,1,44,0,0,1,78,0,0,1,78,0,0,0,0,0,0,0,0,1,70,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,52,0,0,0,0,1,60,1,88,0,0,1,112,0,0,1,140, -0,0,1,140,0,0,1,212,0,0,1,252,0,0,2,94,0,0,2,232,0,0,2,248,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,3,32,3,36,0,0,0,0,3,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,20,0,0, -3,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,3,3,176,3,177,3,175,1,212,1,217,1,218,1,219,1,220,1,221,1, -222,1,223,0,125,1,214,1,234,1,235,1,236,1,237,1,238,1,239,0,126,0,127,1,240,1, -241,1,242,1,243,1,244,0,128,0,129,1,245,1,246,1,247,1,248,1,249,1,250,0,130,0, -131,2,5,2,6,2,7,2,8,2,9,2,10,0,132,0,133,2,11,2,12,2,13,2,14,2,15,0,134,1,213, -1,209,0,135,1,215,0,136,2,62,2,63,2,64,2,65,2,66,2,67,0,137,0,138,0,139,2,76, -2,77,2,78,2,79,2,80,2,81,2,82,0,140,0,141,2,83,2,84,2,85,2,86,2,87,2,88,0,142, -0,143,1,216,0,144,0,145,1,224,1,251,0,165,0,166,2,136,0,167,2,137,2,138,2,139, -0,168,0,169,2,146,2,147,2,148,0,170,2,149,2,150,0,171,2,151,2,152,0,172,2,153, -0,173,2,154,0,174,2,155,2,156,0,175,2,157,0,176,0,177,2,158,2,159,2,160,2,161, -2,162,2,163,2,164,2,165,0,187,2,167,2,168,0,188,2,166,0,189,0,190,0,191,0,192, -0,193,0,194,0,195,1,168,0,196,0,197,1,198,1,171,2,235,2,174,0,198,2,175,0,199, -2,176,2,177,2,178,2,179,0,200,0,201,0,202,2,180,2,236,2,181,0,203,2,183,0,204, -2,184,2,185,0,205,2,186,0,206,0,207,0,208,2,187,2,182,0,209,2,188,2,189,2,190, -2,191,2,192,2,193,2,194,0,210,2,195,2,196,2,197,0,221,0,222,0,223,0,224,2,198, -0,225,0,226,0,227,2,199,0,228,0,229,0,230,0,231,2,200,0,232,2,201,2,202,0,233, -2,203,0,234,2,204,2,237,2,205,0,245,2,206,0,246,2,207,2,208,2,209,2,210,0,247, -0,248,0,249,2,211,2,238,2,212,0,250,0,251,0,252,3,151,3,150,1,133,1,134,1,135, -1,136,1,164,1,165,1,176,1,177,1,178,1,179,1,162,1,163,2,239,2,240,0,253,0,254, -1,111,1,112,2,241,2,242,2,244,2,243,1,172,1,173,3,170,3,171,1,174,1,175,1,113, -1,114,1,199,1,200,1,201,3,156,3,157,3,149,3,148,1,166,1,167,1,153,1,154,3,152, -3,153,1,117,1,118,3,143,3,144,2,245,2,246,3,129,3,130,1,156,1,157,3,154,3,155, -1,131,1,132,3,131,3,132,1,123,1,124,1,119,1,120,1,194,1,195,2,247,2,248,3,133, -3,134,2,249,2,250,3,164,3,165,3,135,3,136,1,125,1,126,3,137,3,138,1,158,1,159, -1,129,3,147,1,127,1,128,3,145,3,146,2,251,2,252,2,253,1,115,1,116,3,162,3,163, -1,161,1,160,3,158,3,159,3,139,3,140,3,160,3,161,1,121,1,122,3,7,3,8,3,9,3,10, -3,11,3,12,1,3,1,4,3,141,3,142,3,33,3,34,3,168,3,169,3,35,3,36,3,166,3,167,1, -151,3,37,1,145,1,146,1,147,1,148,1,149,1,150,1,140,1,139,1,137,1,138,1,141,1, -142,1,143,1,144,1,152,3,172,3,38,3,39,1,5,1,6,3,174,1,193,1,210,1,17,3,173,1, -23,3,128,1,24,0,0,0,1,0,127,255,48,4,38,6,157,0,44,0,0,1,52,38,39,46,1,53,52, -54,55,53,51,21,30,1,21,35,52,38,35,34,6,21,20,22,23,30,1,21,20,6,7,21,35,53, -46,1,63,1,51,20,22,51,50,54,3,97,127,147,202,206,190,166,158,167,185,196,126, -111,118,118,122,158,204,198,206,180,157,172,220,4,2,190,156,112,129,145,1,120, -90,127,50,61,204,170,165,208,21,221,222,22,230,193,127,158,123,107,97,120,54, -66,197,169,172,203,19,192,191,18,215,208,5,154,131,123,0,0,0,0,5,0,104,255, -235,5,131,5,197,0,13,0,27,0,41,0,55,0,59,0,0,19,52,54,51,50,22,29,1,20,6,35, -34,38,53,51,20,22,51,50,54,61,1,52,38,35,34,6,21,1,52,54,51,50,22,29,1,20,6, -35,34,38,53,51,20,22,51,50,54,61,1,52,38,35,34,6,21,5,39,1,23,104,164,137,137, -164,163,136,138,165,146,81,76,73,80,81,74,75,80,2,47,164,137,136,165,164,135, -138,165,146,81,76,73,80,82,73,74,81,254,15,109,2,199,109,4,152,127,174,173, -128,77,127,172,172,127,74,103,102,75,77,74,105,105,74,252,205,127,173,173,127, -78,128,172,172,128,75,103,103,75,78,74,104,104,74,247,67,4,114,67,0,0,0,3,0, -64,255,235,4,208,5,197,0,33,0,44,0,57,0,0,19,52,54,55,46,1,53,52,54,51,50,22, -21,20,6,15,1,1,62,1,53,51,20,6,7,23,7,35,39,14,1,35,34,36,5,50,54,55,1,7,14,1, -21,20,22,3,20,22,23,55,62,1,53,52,38,35,34,6,64,141,140,78,76,195,171,158,198, -105,103,109,1,84,41,46,176,78,74,185,2,229,85,80,194,104,217,254,255,1,218,72, -140,62,254,151,40,91,59,142,15,54,54,138,57,41,97,78,81,88,1,136,122,183,92, -99,155,82,169,183,182,128,98,143,75,80,254,103,65,158,88,132,224,89,223,5,102, -60,63,230,76,49,46,1,179,29,68,124,50,113,146,3,226,53,115,68,95,38,89,54,61, -94,113,0,0,1,0,126,3,183,1,68,5,176,0,5,0,0,1,3,35,19,53,51,1,68,101,97,1,197, -4,209,254,230,1,9,240,0,0,0,0,1,0,132,254,49,2,157,6,100,0,17,0,0,19,16,0,55, -31,1,6,2,17,21,16,18,23,7,35,38,0,17,132,1,62,175,6,38,137,203,202,138,38,6, -175,254,194,2,79,1,138,2,46,93,1,116,107,254,40,254,165,13,254,165,254,40,116, -108,93,2,45,1,139,0,0,0,0,1,0,6,254,49,2,31,6,100,0,17,0,0,1,16,0,7,35,39,54, -18,17,53,16,2,39,55,51,22,0,17,2,31,254,193,174,6,38,135,205,211,129,38,6,174, -1,63,2,70,254,117,253,211,93,108,105,1,225,1,93,13,1,86,1,227,110,108,93,253, -210,254,118,0,0,0,0,1,0,88,1,134,3,27,4,57,0,14,0,0,1,39,55,23,39,51,3,55,23, -7,23,7,39,7,39,1,68,236,49,236,10,161,10,233,48,242,153,132,140,135,133,2,184, -67,154,90,254,254,252,89,156,68,200,96,218,210,92,0,0,0,0,1,0,78,0,146,4,52,4, -182,0,11,0,0,1,33,21,33,17,35,17,33,53,33,17,51,2,165,1,143,254,113,197,254, -110,1,146,197,3,15,178,254,53,1,203,178,1,167,0,1,0,117,254,254,1,59,0,221,0, -5,0,0,5,7,35,19,53,51,1,59,101,97,1,197,8,250,1,3,220,0,0,1,0,167,2,26,2,245, -2,180,0,3,0,0,1,33,53,33,2,245,253,178,2,78,2,26,154,0,0,1,0,161,0,0,1,102,0, -202,0,3,0,0,33,35,53,51,1,102,197,197,202,0,0,1,0,16,255,131,3,23,5,176,0,3,0, -0,23,35,1,51,184,168,2,96,167,125,6,45,0,0,0,2,0,113,255,235,4,16,5,197,0,13, -0,27,0,0,1,20,2,35,34,2,53,17,52,18,51,50,18,21,39,52,38,35,34,6,21,17,20,22, -51,50,54,53,4,16,251,212,211,253,251,211,212,253,197,140,128,127,138,141,126, -128,138,2,2,247,254,224,1,32,247,1,172,245,1,34,254,222,245,41,157,182,182, -157,254,3,157,184,183,158,0,0,0,1,0,195,0,0,2,198,5,197,0,5,0,0,33,35,17,5,53, -37,2,198,198,254,195,2,3,4,250,3,152,54,0,1,0,133,0,0,4,30,5,197,0,26,0,0,41, -1,53,1,62,1,53,52,38,35,34,6,21,35,39,38,54,51,50,22,21,20,6,7,1,23,33,4,30, -252,120,1,201,122,87,118,104,129,135,190,2,5,248,213,195,224,127,130,254,145, -2,2,151,135,2,33,148,175,89,101,129,158,118,6,178,247,216,171,115,220,166,254, -82,5,0,1,0,115,255,235,4,15,5,197,0,42,0,0,1,50,54,53,52,38,35,34,6,21,35,39, -38,36,51,50,22,21,20,6,7,30,1,21,20,6,35,34,36,63,1,51,20,22,51,50,54,53,52, -38,43,1,53,2,67,132,109,119,117,114,149,188,3,5,1,2,201,203,230,107,96,110, -115,253,202,186,254,229,5,2,188,153,121,120,138,127,136,162,3,60,131,118,110, -135,141,106,6,164,232,205,199,102,168,47,44,179,127,200,227,219,180,6,106,145, -149,120,137,136,153,0,0,2,0,72,0,0,4,70,5,176,0,10,0,15,0,0,1,51,21,35,17,35, -17,33,53,1,51,1,33,17,39,7,3,125,201,201,196,253,143,2,101,208,253,158,1,158, -6,19,1,234,154,254,176,1,80,111,3,241,252,58,2,171,1,50,0,1,0,152,255,235,4, -19,5,176,0,31,0,0,27,1,33,21,33,3,62,1,55,54,18,21,20,2,35,34,38,63,1,51,20, -22,51,50,54,53,52,38,35,34,6,7,175,84,2,217,253,205,47,47,114,73,202,229,235, -225,185,246,5,2,178,137,109,125,138,139,124,116,104,25,2,135,3,41,175,254,93, -35,45,1,2,254,255,224,219,254,246,202,196,6,119,131,176,153,139,172,70,73,0,0, -0,2,0,137,255,235,4,40,5,197,0,26,0,39,0,0,1,50,22,23,7,46,1,35,34,6,29,1,62, -1,51,50,22,21,20,2,35,34,0,25,1,16,0,19,34,6,7,21,20,22,51,50,54,53,52,38,2, -129,86,168,55,42,57,126,84,137,171,61,167,96,188,219,245,208,202,254,240,1,35, -166,93,133,35,161,117,123,133,143,5,197,34,26,151,25,31,234,179,113,61,70,252, -205,224,254,245,1,51,1,10,1,79,1,0,1,78,253,71,79,67,101,185,215,187,150,142, -168,0,0,0,1,0,97,0,0,4,39,5,176,0,12,0,0,1,0,2,17,21,35,53,16,18,19,33,53,33, -4,39,254,236,194,197,243,230,252,252,3,198,5,21,254,184,254,10,254,200,159, -159,1,74,2,17,1,27,155,0,3,0,102,255,235,4,26,5,197,0,23,0,35,0,47,0,0,1,20,6, -7,30,1,21,20,4,35,34,36,53,52,54,55,46,1,53,52,54,51,50,22,3,52,38,35,34,6,21, -20,22,51,50,54,3,52,38,35,34,6,21,20,22,51,50,54,3,242,128,106,124,150,254, -251,202,214,254,241,153,130,112,130,245,197,186,239,156,155,114,124,162,161, -127,114,153,41,131,97,107,138,140,107,97,129,4,60,114,173,43,43,188,123,201, -220,220,201,123,188,44,42,173,114,191,202,203,252,154,119,154,154,119,123,148, -149,3,31,105,136,131,110,111,138,138,0,0,2,0,93,255,235,3,248,5,197,0,26,0,39, -0,0,37,50,54,61,1,14,1,35,34,2,53,52,18,51,50,0,21,17,20,0,35,34,38,39,55,30, -1,19,50,54,55,53,52,38,35,34,6,21,20,22,1,245,142,175,48,143,85,210,239,254, -187,218,1,8,254,224,227,77,161,70,30,66,127,126,103,141,32,146,132,107,143, -132,133,196,180,124,71,73,1,3,230,220,1,23,254,238,250,254,70,251,254,231,32, -31,150,32,27,1,254,94,73,172,163,177,191,153,150,185,255,255,0,161,0,0,1,102, -4,54,0,38,0,14,0,0,0,7,0,14,0,0,3,108,255,255,0,162,254,254,1,110,4,54,0,39,0, -14,0,1,3,108,0,6,0,12,51,0,0,1,0,71,0,107,3,119,3,245,0,9,0,0,1,7,21,23,5,21, -1,53,1,21,1,72,85,85,2,47,252,208,3,48,2,67,18,6,19,228,201,1,123,149,1,122, -201,0,0,2,0,152,1,151,3,218,3,219,0,3,0,7,0,0,1,33,53,33,17,33,53,33,3,218, -252,190,3,66,252,190,3,66,3,55,164,253,188,164,0,1,0,136,0,87,3,224,3,225,0,9, -0,0,19,53,1,21,1,53,37,55,53,39,136,3,88,252,168,2,86,85,85,3,30,195,254,134, -149,254,133,196,238,17,6,20,0,0,0,2,0,58,0,0,3,118,5,197,0,26,0,30,0,0,1,62,1, -55,62,1,53,52,38,35,34,6,21,35,39,38,54,51,50,22,21,20,6,7,14,1,21,19,35,53, -51,1,99,1,48,102,99,84,113,105,91,128,188,3,3,233,180,197,218,141,116,54,23,7, -206,206,1,154,145,112,92,117,126,89,106,114,99,96,6,161,194,201,180,129,214, -112,54,86,91,254,102,208,0,0,0,2,0,96,254,59,6,213,5,151,0,51,0,67,0,0,1,6,2, -35,34,38,39,14,1,35,34,38,55,26,1,51,50,22,23,7,51,3,6,22,51,50,54,55,18,0,33, -32,0,3,2,0,33,50,54,55,23,14,1,35,32,0,19,18,0,33,32,0,1,6,22,51,50,54,55,38, -54,55,19,46,1,35,34,6,6,196,9,222,221,73,106,23,50,144,96,125,138,18,23,229, -165,105,128,75,4,6,51,9,61,51,123,148,8,16,254,192,254,176,254,204,254,137,15, -18,1,80,1,58,88,181,62,38,67,207,99,254,132,254,97,18,19,1,204,1,116,1,123,1, -149,251,251,11,65,74,64,106,44,1,1,2,47,26,57,31,125,132,1,246,214,254,203,83, -76,80,79,241,196,1,3,1,57,52,54,4,253,183,110,83,227,175,1,126,1,171,254,50, -254,141,254,136,254,75,43,35,107,42,47,1,243,1,176,1,167,2,18,254,12,253,253, -142,148,49,63,12,27,16,2,26,12,14,219,0,0,2,0,43,0,0,4,227,5,176,0,7,0,11,0,0, -1,33,3,35,1,51,1,35,1,33,3,35,3,154,253,220,130,201,2,13,169,2,2,201,253,149, -1,179,212,6,1,119,254,137,5,176,250,80,2,28,2,113,0,0,0,3,0,163,0,0,4,198,5, -176,0,14,0,24,0,33,0,0,51,17,33,50,4,21,20,6,7,30,1,21,20,4,35,1,17,33,50,54, -53,52,38,39,35,37,33,50,54,53,52,38,35,33,163,1,219,228,1,2,116,96,143,167, -254,252,222,254,132,1,124,135,149,152,129,13,254,142,1,63,110,138,149,140,254, -234,5,176,197,197,94,149,39,20,208,141,200,211,2,171,253,239,133,122,121,148, -5,154,121,108,118,117,0,0,0,1,0,118,255,235,4,191,5,197,0,29,0,0,1,23,22,0,35, -34,0,25,1,16,0,51,50,0,15,1,35,52,38,35,34,2,21,17,20,18,51,50,54,53,4,185,2, -4,254,216,243,247,254,201,1,55,247,247,1,36,4,2,189,180,164,165,196,196,165, -164,180,1,210,6,205,254,236,1,94,1,13,1,3,1,13,1,95,254,249,217,6,153,178,254, -246,197,254,251,199,254,246,177,156,0,0,2,0,169,0,0,4,235,5,176,0,9,0,19,0,0, -51,17,33,32,0,17,21,16,0,33,1,17,33,50,18,61,1,52,2,35,169,1,202,1,29,1,91, -254,165,254,227,254,251,1,5,202,233,233,202,5,176,254,161,254,234,199,254,233, -254,163,5,21,251,133,1,10,208,201,206,1,10,0,0,0,0,1,0,163,0,0,4,36,5,176,0, -11,0,0,1,33,17,33,21,33,17,33,21,33,17,33,3,190,253,170,2,188,252,127,3,118, -253,79,2,86,2,163,253,247,154,5,176,155,254,41,0,0,0,1,0,163,0,0,4,52,5,176,0, -9,0,0,1,33,17,35,17,33,21,33,17,33,3,206,253,154,197,3,145,253,52,2,102,2,132, -253,124,5,176,155,254,10,0,1,0,121,255,235,4,193,5,197,0,32,0,0,37,6,4,35,34, -0,25,1,16,0,51,50,0,15,1,35,52,38,35,34,6,21,17,20,22,51,50,54,55,17,33,53,33, -4,193,52,254,255,205,252,254,182,1,62,251,243,1,26,4,2,189,172,158,167,204, -216,168,129,151,37,254,182,2,15,196,81,136,1,78,1,9,1,44,1,9,1,78,254,253,200, -6,133,177,250,192,254,210,194,251,67,46,1,72,154,0,1,0,169,0,0,4,246,5,176,0, -11,0,0,33,35,17,33,17,35,17,51,17,33,17,51,4,246,197,253,61,197,197,2,195,197, -2,131,253,125,5,176,253,110,2,146,0,0,0,1,0,190,0,0,1,132,5,176,0,3,0,0,33,35, -17,51,1,132,198,198,5,176,0,1,0,74,255,235,3,188,5,176,0,16,0,0,1,51,17,20,6, -35,34,38,63,1,51,20,22,51,50,54,53,2,247,197,247,197,201,237,5,2,189,126,116, -109,138,5,176,251,246,203,240,213,203,6,136,132,158,131,0,0,0,1,0,163,0,0,4, -251,5,176,0,14,0,0,1,35,17,35,17,51,17,51,1,51,23,9,1,7,35,1,251,147,197,197, -128,2,8,222,2,253,196,2,103,3,239,2,146,253,110,5,176,253,124,2,132,5,253,80, -253,10,5,0,0,0,0,1,0,168,0,0,4,51,5,176,0,5,0,0,37,33,21,33,17,51,1,109,2,198, -252,117,197,154,154,5,176,0,0,1,0,163,0,0,6,65,5,176,0,15,0,0,1,51,1,51,17,35, -17,39,1,35,1,7,17,35,17,33,3,117,6,1,209,245,197,6,254,71,137,254,58,6,197,1, -3,1,17,4,159,250,80,4,67,1,251,188,4,104,1,251,153,5,176,0,0,0,0,1,0,169,0,0, -4,246,5,176,0,11,0,0,33,35,1,7,17,35,17,51,1,55,17,51,4,246,197,253,67,6,197, -197,2,189,6,197,4,88,2,251,170,5,176,251,169,2,4,85,0,0,0,2,0,113,255,235,5,2, -5,197,0,13,0,27,0,0,1,16,0,33,34,0,25,1,16,0,51,32,0,17,39,52,2,35,34,2,21,17, -20,18,51,50,54,53,5,2,254,181,254,248,255,254,193,1,63,255,1,8,1,75,197,216, -182,172,205,205,172,183,215,2,86,254,245,254,160,1,96,1,11,1,3,1,10,1,98,254, -159,254,245,2,200,1,0,255,0,200,254,251,202,255,0,255,203,0,0,2,0,163,0,0,4, -188,5,176,0,10,0,19,0,0,1,17,35,17,33,50,4,21,20,4,35,37,33,50,54,53,52,38,35, -33,1,104,197,2,45,233,1,3,254,253,233,254,152,1,104,148,146,147,147,254,152,2, -72,253,184,5,176,240,196,198,238,154,159,121,121,162,0,2,0,113,255,113,5,90,5, -197,0,19,0,33,0,0,1,20,6,7,23,7,39,14,1,35,34,0,25,1,16,0,51,32,0,17,39,52,2, -35,34,2,21,17,20,18,51,50,54,53,5,2,67,62,217,135,222,70,164,92,255,254,193,1, -63,255,1,8,1,75,197,216,182,172,205,205,172,183,215,2,86,115,205,81,211,129, -213,45,46,1,96,1,11,1,3,1,10,1,98,254,159,254,245,2,200,1,0,255,0,200,254,251, -202,255,0,255,203,0,0,0,0,2,0,165,0,0,4,213,5,175,0,26,0,35,0,0,1,17,35,17,33, -50,22,21,20,6,7,30,1,29,1,20,22,23,21,35,46,1,61,1,52,38,35,37,33,50,54,53,52, -38,35,33,1,106,197,2,5,239,253,117,112,120,105,30,37,203,39,22,138,116,254, -155,1,45,167,147,143,152,254,192,2,119,253,137,5,175,212,202,112,166,49,39, -175,129,137,68,108,34,24,34,132,70,133,118,144,155,127,130,123,135,0,0,0,1,0, -121,255,235,4,131,5,197,0,39,0,0,1,52,38,39,46,1,53,52,36,51,50,0,15,1,35,52, -38,35,34,6,21,20,22,23,30,1,21,20,4,35,34,36,63,1,51,20,22,51,50,54,3,190,144, -185,220,243,1,4,212,230,1,17,4,3,188,173,135,137,138,155,179,225,233,254,233, -221,211,254,189,5,2,188,208,131,138,165,1,130,95,118,48,54,214,163,172,227, -254,251,174,6,124,162,133,108,96,127,47,59,204,160,178,231,236,198,6,137,149, -143,0,0,0,1,0,37,0,0,4,164,5,176,0,7,0,0,1,33,17,35,17,33,53,33,4,164,254,32, -197,254,38,4,127,5,21,250,235,5,21,155,0,0,0,1,0,147,255,235,4,220,5,176,0,17, -0,0,1,17,20,0,35,34,0,53,17,51,17,20,22,51,50,54,53,17,4,220,254,200,246,237, -254,210,197,191,151,160,201,5,176,252,57,240,254,242,1,15,239,3,199,252,57, -167,189,189,167,3,199,0,0,0,0,1,0,22,0,0,4,249,5,176,0,9,0,0,1,23,51,55,1,51, -1,35,1,51,2,100,33,6,33,1,120,213,253,227,169,253,227,214,1,126,121,121,4,50, -250,80,5,176,0,1,0,37,0,0,6,191,5,176,0,21,0,0,1,31,1,55,1,51,1,23,51,55,19, -51,1,35,1,39,35,7,1,35,1,51,1,206,25,6,34,1,2,193,1,4,34,6,27,208,214,254,160, -176,254,221,22,6,21,254,217,176,254,161,213,1,249,191,1,192,3,183,252,73,195, -195,3,183,250,80,3,242,131,131,252,14,5,176,0,1,0,66,0,0,4,214,5,176,0,11,0,0, -9,1,51,9,1,35,9,1,35,9,1,51,2,138,1,84,238,254,50,1,216,235,254,163,254,162, -238,1,216,254,50,236,3,120,2,56,253,46,253,34,2,66,253,190,2,222,2,210,0,0,0, -1,0,40,0,0,4,226,5,176,0,8,0,0,9,1,51,1,17,35,17,1,51,2,133,1,124,225,254,1, -196,254,9,225,2,204,2,228,252,80,254,0,2,15,3,161,0,0,0,1,0,97,0,0,4,109,5, -176,0,9,0,0,37,33,21,33,53,1,33,53,33,21,1,63,3,46,251,244,3,10,253,1,3,224, -154,154,146,4,131,155,141,0,0,1,0,143,254,200,2,16,6,128,0,7,0,0,1,35,17,51, -21,33,17,33,2,16,188,188,254,127,1,129,5,229,249,126,155,7,184,0,0,0,0,1,0,39, -255,131,3,65,5,176,0,3,0,0,19,51,1,35,39,186,2,96,186,5,176,249,211,0,0,1,0, -11,254,200,1,141,6,128,0,7,0,0,19,33,17,33,53,51,17,35,11,1,130,254,126,189, -189,6,128,248,72,155,6,130,0,1,0,61,2,217,3,24,5,176,0,9,0,0,19,35,1,51,1,35, -3,39,35,7,244,183,1,43,134,1,42,181,166,16,6,16,2,217,2,215,253,41,1,163,70, -70,0,0,0,1,0,4,255,102,3,159,0,0,0,3,0,0,5,33,53,33,3,159,252,101,3,155,154, -154,0,0,0,1,0,82,4,228,1,234,5,238,0,4,0,0,1,35,3,55,51,1,234,158,250,3,230,4, -228,1,4,6,0,0,0,2,0,106,255,235,3,243,4,78,0,32,0,43,0,0,33,46,1,39,14,1,35, -34,38,53,52,54,59,1,53,52,38,35,34,6,21,7,39,38,54,51,50,22,21,17,20,22,23,37, -50,54,55,53,35,34,6,21,20,22,3,40,10,11,1,55,177,102,169,177,251,215,214,116, -106,96,118,187,2,7,235,186,184,224,12,16,253,238,107,172,26,221,119,143,90,49, -75,38,78,105,173,152,155,175,107,95,111,96,67,2,6,118,196,187,176,253,247,58, -108,52,144,110,71,176,120,81,72,84,0,2,0,143,255,235,4,43,6,24,0,17,0,31,0,0, -1,20,2,35,34,38,39,7,35,17,51,17,62,1,51,50,18,17,35,52,38,35,34,6,7,17,30,1, -51,50,54,53,4,43,225,197,108,159,52,32,151,197,51,151,101,200,224,197,137,140, -91,125,37,38,123,94,139,136,1,244,234,254,225,85,83,147,6,24,253,162,72,76, -254,192,254,251,186,235,89,75,254,43,80,90,198,163,0,0,0,1,0,97,255,235,3,217, -4,78,0,29,0,0,37,50,54,53,51,23,22,6,35,34,2,61,1,52,18,51,50,22,15,1,35,52, -38,35,34,6,29,1,20,22,2,61,91,136,178,3,4,248,164,228,248,249,227,181,231,4,2, -179,129,98,145,133,131,133,121,88,6,140,217,1,54,231,42,229,1,55,224,163,6,99, -139,225,160,42,163,224,0,0,0,2,0,98,255,235,3,245,6,24,0,17,0,31,0,0,19,16,18, -51,50,22,23,17,51,17,35,39,14,1,35,34,2,53,51,20,22,51,50,54,55,17,46,1,35,34, -6,21,98,223,201,95,147,52,197,151,30,53,156,103,198,224,197,134,141,88,120,38, -38,121,85,142,135,2,9,1,5,1,64,70,67,2,83,249,232,137,78,80,1,31,234,164,197, -80,72,1,249,67,79,234,187,0,0,0,0,2,0,97,255,235,3,226,4,78,0,22,0,31,0,0,5, -34,0,61,1,52,0,51,50,18,29,1,33,7,6,22,51,50,54,55,23,14,1,3,34,6,7,23,33,53, -52,38,2,100,242,254,239,1,13,194,217,217,253,76,2,1,155,158,98,116,79,49,54, -155,185,103,135,15,2,1,232,116,21,1,43,242,44,233,1,49,254,242,224,104,5,162, -204,41,42,139,39,59,3,200,159,124,5,16,118,154,0,0,0,1,0,28,0,0,2,173,6,45,0, -23,0,0,51,17,35,53,51,53,52,54,51,50,22,23,7,46,1,35,34,6,29,1,51,21,35,17, -198,170,170,180,162,34,69,42,24,18,51,27,87,83,196,196,3,168,146,137,173,189, -11,10,150,4,6,103,98,137,146,252,88,0,0,2,0,108,254,75,4,0,4,78,0,29,0,43,0,0, -19,16,18,51,50,22,23,55,51,17,20,6,35,34,38,39,55,30,1,51,50,54,61,1,14,1,35, -34,2,53,51,20,22,51,50,54,55,17,46,1,35,34,6,21,108,223,200,103,156,53,24,157, -242,228,78,181,69,30,57,161,78,144,131,53,148,97,198,223,197,134,140,89,120, -39,38,122,86,141,135,2,9,1,5,1,64,83,78,141,251,192,208,223,43,37,153,30,37, -131,134,123,68,70,1,31,234,163,198,81,74,1,242,69,81,234,187,0,0,1,0,143,0,0, -4,0,6,24,0,19,0,0,1,62,1,51,50,22,21,17,35,17,52,38,35,34,6,7,17,35,17,51,1, -84,56,163,99,173,193,197,115,114,88,130,40,197,197,3,169,78,87,208,216,253,90, -2,168,134,128,69,62,252,213,6,24,0,0,2,0,159,0,0,1,100,6,24,0,3,0,7,0,0,33,35, -17,51,17,35,53,51,1,100,197,197,197,197,4,58,1,21,201,0,0,2,255,190,254,75,1, -114,6,24,0,15,0,19,0,0,1,17,20,6,35,34,38,39,55,30,1,51,50,54,53,17,19,35,53, -51,1,114,172,153,31,51,29,14,14,52,17,65,77,191,197,197,4,58,251,109,167,181, -9,9,155,5,7,88,99,4,147,1,25,197,0,0,0,1,0,144,0,0,4,11,6,24,0,12,0,0,1,35,17, -35,17,51,17,51,1,51,9,1,35,1,206,121,197,197,119,1,49,236,254,137,1,153,233,1, -243,254,13,6,24,252,120,1,170,254,14,253,184,0,0,1,0,159,0,0,1,100,6,24,0,3,0, -0,33,35,17,51,1,100,197,197,6,24,0,1,0,143,0,0,6,111,4,78,0,35,0,0,1,23,62,1, -51,50,22,23,62,1,51,50,22,21,17,35,17,52,38,35,34,6,7,21,17,35,17,52,38,35,34, -6,7,17,35,17,1,63,14,53,163,108,108,155,39,52,167,112,165,192,197,110,109,101, -125,11,198,113,106,90,116,31,197,4,58,142,77,85,100,100,93,107,227,228,253, -121,2,137,160,133,140,107,8,253,81,2,137,152,141,74,67,252,223,4,58,0,0,0,0,1, -0,143,0,0,3,253,4,78,0,19,0,0,1,23,62,1,51,50,22,21,17,35,17,52,38,35,34,6,7, -17,35,17,1,63,14,54,163,104,175,192,197,113,116,91,127,37,197,4,58,161,86,95, -205,214,253,85,2,167,143,120,73,66,252,221,4,58,0,2,0,97,255,235,4,42,4,78,0, -13,0,27,0,0,19,52,0,51,50,0,29,1,20,0,35,34,0,53,51,20,22,51,50,54,61,1,52,38, -35,34,6,21,97,1,4,223,225,1,5,254,252,224,224,254,251,197,145,143,141,146,147, -142,141,145,2,39,240,1,55,254,202,241,22,242,254,204,1,53,241,172,224,224,172, -22,170,226,226,170,0,0,0,2,0,143,254,96,4,41,4,78,0,17,0,31,0,0,1,20,2,35,34, -38,39,17,35,17,51,23,62,1,51,50,18,17,35,52,38,35,34,6,7,17,30,1,51,50,54,53, -4,41,224,197,100,151,53,197,151,31,53,158,105,201,223,197,145,141,85,120,37, -37,120,87,140,144,1,244,234,254,225,67,67,253,239,5,218,140,78,82,254,193,254, -250,184,237,77,67,253,245,67,75,205,162,0,0,0,2,0,98,254,96,3,234,4,78,0,17,0, -31,0,0,19,16,18,51,50,22,23,55,51,17,35,17,14,1,35,34,2,53,51,20,22,51,50,54, -55,17,46,1,35,34,6,21,98,223,201,98,150,53,28,151,197,52,142,91,198,224,197, -135,140,81,115,39,39,115,79,141,136,2,9,1,5,1,64,75,71,126,250,38,2,6,61,62,1, -31,234,164,203,72,65,2,34,61,70,239,187,0,0,0,0,1,0,143,0,0,2,170,4,78,0,15,0, -0,1,39,34,6,7,17,35,17,51,23,62,1,51,50,22,23,2,143,101,78,107,29,197,176,14, -45,138,91,22,40,13,3,140,6,74,67,252,251,4,58,168,88,100,7,4,0,0,1,0,103,255, -235,3,201,4,78,0,39,0,0,1,52,38,39,46,1,53,52,54,51,50,22,15,1,35,52,38,35,34, -6,21,20,22,23,30,1,21,20,6,35,34,38,63,1,51,30,1,51,50,54,3,4,99,138,191,205, -225,179,184,228,5,2,188,123,94,104,103,89,139,199,206,233,188,207,238,6,2,188, -5,146,98,105,119,1,35,65,82,31,41,148,124,132,188,200,133,6,70,114,94,65,64, -70,29,42,154,124,144,182,210,140,6,105,97,89,0,0,0,1,0,26,255,235,2,98,5,63,0, -23,0,0,1,17,51,21,35,17,20,22,51,50,54,55,23,14,1,35,34,38,53,17,35,53,51,17, -1,138,205,205,63,52,17,41,16,27,23,86,42,119,143,171,171,5,63,254,251,146,253, -111,76,62,8,6,135,18,23,145,155,2,145,146,1,5,0,1,0,139,255,235,3,252,4,58,0, -19,0,0,37,14,1,35,34,38,53,17,51,17,20,22,51,50,54,55,17,51,17,35,3,62,51,161, -104,177,198,197,102,108,105,137,35,197,177,161,87,95,226,239,2,126,253,128, -173,130,86,79,3,10,251,198,0,0,0,1,0,46,0,0,3,228,4,58,0,9,0,0,1,23,51,55,19, -51,1,35,1,51,1,248,17,6,19,249,201,254,114,149,254,109,202,1,63,76,76,2,251, -251,198,4,58,0,0,1,0,45,0,0,5,220,4,58,0,21,0,0,1,23,51,55,19,51,19,23,51,55, -19,51,1,35,3,39,35,7,3,35,1,51,1,164,25,6,26,216,158,217,28,6,32,160,206,254, -198,159,214,41,6,38,210,159,254,198,205,1,138,139,139,2,176,253,80,155,155,2, -176,251,198,2,147,172,172,253,109,4,58,0,0,1,0,46,0,0,3,212,4,58,0,11,0,0,1, -19,51,9,1,35,11,1,35,9,1,51,1,254,230,230,254,161,1,105,226,240,240,228,1,105, -254,161,227,2,171,1,143,253,233,253,221,1,153,254,103,2,35,2,23,0,0,1,0,26, -254,75,3,232,4,58,0,21,0,0,1,23,51,1,51,1,14,1,35,34,38,39,55,38,22,51,50,54, -63,1,1,51,1,218,35,6,1,10,219,254,57,41,153,130,24,74,20,20,6,83,11,63,80,27, -47,254,110,220,1,145,136,3,49,251,32,109,162,11,5,155,1,6,112,68,113,4,36,0,0, -0,0,1,0,94,0,0,3,186,4,58,0,9,0,0,37,33,21,33,53,1,33,53,33,21,1,73,2,113,252, -164,2,73,253,190,3,51,154,154,138,3,20,156,134,0,0,1,0,63,254,148,2,159,6,61, -0,30,0,0,1,46,1,61,1,52,38,35,53,50,54,61,1,52,54,55,23,14,1,29,1,20,6,7,30,1, -29,1,20,22,23,2,119,195,164,103,106,106,103,164,195,40,110,92,85,85,85,85,92, -110,254,148,55,240,170,205,112,125,147,123,113,206,171,239,55,117,35,181,132, -206,105,160,45,46,161,103,205,132,179,36,0,0,0,1,0,145,254,242,1,86,5,176,0,3, -0,0,1,35,17,51,1,86,197,197,254,242,6,190,0,0,0,1,0,21,254,148,2,118,6,61,0, -30,0,0,23,62,1,61,1,52,54,55,46,1,61,1,52,38,39,55,30,1,29,1,20,22,51,21,34,6, -29,1,20,6,7,21,109,94,90,94,94,90,94,109,41,194,165,101,108,108,101,165,194, -246,36,179,132,205,107,160,43,41,160,109,206,132,181,35,117,55,239,171,206, -113,123,147,125,112,205,170,240,55,0,1,0,128,1,145,4,240,3,35,0,25,0,0,1,20,6, -35,34,38,39,46,1,35,34,6,21,39,52,54,51,50,22,23,30,1,51,50,54,53,4,240,174, -130,90,147,85,59,98,50,67,95,141,171,132,88,150,85,58,96,52,66,97,2,228,137, -202,66,74,48,48,106,75,18,136,193,69,70,51,46,114,77,0,0,255,255,0,144,254, -138,1,86,4,58,0,71,3,176,255,229,4,58,64,0,192,1,0,0,0,1,0,97,255,11,3,218,5, -38,0,35,0,0,37,50,54,53,51,23,22,6,7,21,35,53,38,2,61,1,52,18,55,53,51,21,30, -1,15,1,35,52,38,35,34,6,29,1,20,22,2,61,91,136,180,2,3,178,131,198,184,197, -198,183,198,140,170,3,3,180,129,98,145,133,131,133,121,88,5,116,198,31,237, -233,31,1,40,205,42,202,1,40,33,225,227,30,209,138,5,99,139,225,160,42,163,224, -0,0,0,1,0,70,0,0,4,87,5,197,0,34,0,0,1,23,20,6,7,33,7,33,53,51,62,1,53,39,35, -53,51,3,52,54,51,50,22,15,1,35,52,38,35,34,6,21,19,33,21,1,174,6,31,29,2,223, -1,252,48,10,48,48,6,164,158,10,224,188,200,220,4,2,190,126,98,99,116,10,1,162, -2,103,149,90,163,59,154,154,13,196,103,149,155,1,14,204,233,209,172,6,118,114, -149,133,254,242,155,0,0,2,0,104,255,229,5,90,4,241,0,35,0,47,0,0,37,14,1,35, -34,38,39,7,39,55,46,1,53,52,54,55,39,55,23,62,1,51,50,22,23,55,23,7,30,1,21, -20,6,7,23,7,1,20,18,51,50,18,53,52,2,35,34,2,4,73,77,185,101,101,185,75,130, -139,138,50,53,57,54,146,139,143,74,178,96,97,178,75,146,140,150,52,57,53,48, -142,140,252,115,241,172,170,241,241,170,172,241,108,62,66,65,61,132,138,140, -76,181,99,102,188,78,149,139,146,55,61,62,56,149,140,153,78,185,101,98,179,76, -143,139,2,123,188,254,247,1,9,188,186,1,8,254,248,0,1,0,30,0,0,4,175,5,176,0, -22,0,0,9,1,51,1,33,21,33,21,33,21,33,17,35,17,33,53,33,53,33,53,33,1,51,2,103, -1,104,224,254,94,1,56,254,129,1,127,254,129,197,254,137,1,119,254,137,1,55, -254,93,226,3,25,2,151,253,50,123,167,122,254,186,1,70,122,167,123,2,206,0,0,0, -2,0,145,254,242,1,86,5,176,0,3,0,7,0,0,19,17,51,25,1,35,17,51,145,197,197,197, -254,242,3,24,252,232,3,200,2,246,0,0,0,2,0,90,254,17,4,124,5,197,0,51,0,69,0, -0,1,20,6,7,30,1,21,20,4,35,34,36,63,2,20,22,51,50,54,53,52,38,39,46,1,53,52, -54,55,46,1,53,52,36,51,50,4,15,1,35,52,38,35,34,6,21,20,22,23,30,1,37,46,1,39, -14,1,21,20,22,23,30,1,23,62,1,53,52,38,4,124,96,87,69,70,254,246,225,221,254, -210,5,2,188,193,135,137,157,144,204,239,226,94,87,68,68,1,12,224,233,1,4,4,3, -188,158,140,145,150,134,211,244,223,253,223,47,83,36,73,73,136,210,56,74,33, -72,80,147,1,175,94,140,40,51,136,98,172,195,205,220,6,2,143,135,119,91,91,101, -63,63,186,177,91,141,41,50,139,97,166,201,223,202,6,118,158,119,91,99,99,58, -69,181,83,12,25,15,19,100,69,100,103,59,17,22,12,20,99,69,91,107,0,0,0,2,0, -160,4,232,3,101,5,176,0,3,0,7,0,0,1,35,53,51,5,35,53,51,3,101,219,219,254,22, -219,219,4,232,200,200,200,0,0,0,0,3,0,88,255,235,5,227,5,196,0,29,0,41,0,53,0, -0,1,23,22,6,35,34,38,61,1,52,54,51,50,22,15,1,35,52,38,35,34,6,29,1,20,22,51, -50,54,53,37,16,0,51,50,0,17,16,0,35,34,0,3,16,0,33,32,0,17,16,0,33,32,0,4,87, -2,4,176,157,160,188,188,160,157,177,4,2,146,91,91,94,102,102,94,91,90,253,12, -1,87,246,245,1,88,254,168,245,246,254,169,121,1,158,1,40,1,39,1,158,254,97, -254,218,254,216,254,98,2,84,6,151,157,213,174,119,173,214,158,149,6,95,87,141, -114,120,117,140,86,98,133,254,247,254,148,1,108,1,9,1,7,1,106,254,150,254,249, -1,59,1,176,254,80,254,197,254,196,254,78,1,178,0,0,2,0,120,2,180,3,19,5,197,0, -32,0,43,0,0,1,46,1,39,14,1,35,34,38,53,52,54,59,1,53,52,38,35,34,6,21,47,1,38, -54,51,50,22,21,17,20,22,23,37,50,54,55,53,35,34,6,21,20,22,2,101,8,10,3,33, -113,77,119,130,169,161,139,60,58,67,73,162,1,6,169,140,134,156,12,14,254,136, -51,109,18,138,75,83,58,2,194,21,48,26,47,62,122,106,110,120,52,63,68,54,49,13, -6,98,130,142,134,254,198,50,88,43,125,60,35,110,66,46,45,48,0,0,255,255,0,77, -0,37,3,30,3,125,0,38,1,19,245,221,0,7,1,19,1,68,255,221,0,1,0,127,1,119,3,194, -3,34,0,5,0,0,1,35,17,33,53,33,3,194,198,253,131,3,67,1,119,1,6,165,0,4,0,88, -255,235,5,227,5,196,0,11,0,23,0,50,0,59,0,0,19,16,0,33,32,0,17,16,0,33,32,0, -19,16,0,51,50,0,17,16,0,35,34,0,1,17,35,17,33,50,22,21,20,6,7,30,1,29,1,20,22, -23,21,35,46,1,61,1,52,38,35,39,51,62,1,53,52,38,43,1,88,1,158,1,40,1,39,1,158, -254,97,254,218,254,216,254,98,121,1,87,246,244,1,88,254,169,245,246,254,169,1, -188,149,1,24,152,173,66,63,66,59,7,10,153,9,4,67,77,159,152,65,91,79,98,131,2, -217,1,59,1,176,254,80,254,197,254,196,254,78,1,178,1,60,254,246,254,149,1,108, -1,9,1,8,1,105,254,151,254,173,254,174,3,82,131,126,62,94,31,26,106,75,56,41, -65,21,16,21,81,42,54,72,68,130,1,63,56,73,59,0,0,0,1,0,103,5,30,3,86,5,176,0, -3,0,0,1,33,53,33,3,86,253,17,2,239,5,30,146,0,0,2,0,128,3,191,2,125,5,197,0, -11,0,23,0,0,19,52,54,51,50,22,21,20,6,35,34,38,55,20,22,51,50,54,53,52,38,35, -34,6,128,152,105,103,149,148,104,106,151,131,73,53,52,71,72,51,53,73,4,192, -106,155,155,106,108,149,149,108,55,72,72,55,55,75,75,0,0,2,0,99,0,4,3,247,4, -243,0,11,0,15,0,0,1,33,21,33,17,35,17,33,53,33,17,51,1,33,53,33,2,145,1,102, -254,154,177,254,131,1,125,177,1,58,252,189,3,67,3,88,154,254,99,1,157,154,1, -155,251,17,155,0,0,1,0,113,2,155,2,202,5,199,0,26,0,0,1,33,53,1,62,1,53,52,38, -35,34,6,21,35,39,38,54,51,50,22,21,20,6,15,1,23,33,2,202,253,176,1,46,69,44, -57,58,67,73,161,2,6,168,141,135,152,89,116,153,2,1,105,2,155,130,1,6,60,75,42, -50,62,64,50,6,99,140,128,116,80,112,105,135,6,0,1,0,106,2,143,2,228,5,198,0, -42,0,0,1,50,54,53,52,38,35,34,6,21,35,39,38,54,51,50,22,21,20,6,7,30,1,21,20, -6,35,34,38,63,1,51,20,22,51,50,54,53,52,38,43,1,53,1,168,67,65,73,69,56,69, -162,2,6,169,126,145,168,71,62,70,76,180,146,127,181,6,1,163,75,63,72,84,73,73, -132,4,113,57,52,43,58,48,40,6,94,119,119,110,55,91,26,23,96,68,111,124,116, -111,6,46,57,59,48,62,57,126,0,0,0,0,1,0,131,4,228,2,36,5,238,0,4,0,0,1,51,23, -1,35,1,60,230,2,254,243,148,5,238,6,254,252,0,0,1,0,153,254,96,3,242,4,58,0, -21,0,0,1,17,30,1,51,50,54,55,17,51,17,35,39,14,1,35,34,38,39,17,35,17,1,93,2, -111,100,98,121,32,197,177,9,44,127,83,72,109,40,196,4,58,253,126,178,129,72, -70,3,39,251,198,108,63,66,33,35,254,49,5,218,0,0,1,0,63,0,0,3,68,5,176,0,10,0, -0,33,17,35,34,0,53,52,0,51,33,17,2,127,84,233,254,253,1,3,233,1,25,2,8,1,3, -209,207,1,5,250,80,0,0,0,1,0,161,2,112,1,103,3,68,0,3,0,0,1,35,53,51,1,103, -198,198,2,112,212,0,0,0,0,1,0,119,254,77,1,175,0,0,0,15,0,0,33,7,30,1,21,20,6, -35,39,50,54,53,52,38,39,55,1,36,12,65,86,158,147,7,72,88,72,87,32,52,11,82,80, -96,114,109,49,49,48,38,7,135,0,1,0,95,2,153,1,140,5,197,0,5,0,0,1,35,17,35,53, -37,1,140,174,127,1,45,2,153,2,143,134,23,0,2,0,120,2,179,3,43,5,197,0,13,0,27, -0,0,19,52,54,51,50,22,29,1,20,6,35,34,38,53,51,20,22,51,50,54,61,1,52,38,35, -34,6,21,120,188,157,158,188,187,157,158,189,173,88,86,83,89,90,84,84,88,4,118, -148,187,187,148,117,149,185,185,149,88,105,106,87,117,84,107,107,84,0,0,255, -255,0,166,0,71,3,131,3,159,0,38,1,20,22,0,0,7,1,20,1,112,0,0,255,255,0,184,0, -0,5,236,5,196,0,39,1,101,0,89,2,152,0,39,1,21,1,24,0,8,0,7,1,104,2,196,0,0,0, -0,255,255,0,184,0,0,5,245,5,196,0,39,1,21,1,37,0,8,0,39,1,101,0,89,2,152,0,7, -1,102,3,43,0,0,0,0,255,255,0,122,0,0,6,159,5,199,0,39,1,21,1,207,0,8,0,39,1, -104,3,119,0,0,0,7,1,103,0,16,2,155,0,0,255,255,0,117,254,118,3,177,4,59,0,15, -0,31,3,235,4,59,192,1,0,2,0,14,0,0,7,132,5,176,0,15,0,19,0,0,41,1,3,33,3,35,1, -33,21,33,19,33,21,33,19,33,1,33,3,39,7,132,252,129,15,253,211,201,242,3,113,3, -199,253,77,20,2,78,253,184,22,2,193,250,172,1,191,31,5,1,94,254,162,5,176,155, -254,46,155,253,242,1,119,2,198,2,0,0,0,1,0,88,0,225,3,225,4,121,0,11,0,0,19,9, -1,55,9,1,23,9,1,7,9,1,88,1,71,254,185,126,1,70,1,71,126,254,184,1,72,126,254, -185,254,186,1,95,1,78,1,78,126,254,179,1,77,126,254,178,254,178,126,1,76,254, -180,0,0,3,0,108,255,162,4,253,5,237,0,25,0,37,0,49,0,0,1,16,0,33,34,38,39,7, -35,55,46,1,53,17,16,0,51,50,22,23,55,51,7,30,1,21,1,20,22,31,1,1,46,1,35,34,2, -21,33,52,38,47,1,1,30,1,51,50,54,53,4,253,254,181,254,248,85,151,64,91,149, -139,84,89,1,63,255,94,169,71,81,150,132,77,85,252,52,37,36,6,2,31,49,124,72, -172,205,3,7,33,30,6,253,227,44,106,62,183,215,2,86,254,245,254,160,41,40,154, -235,83,236,138,1,3,1,10,1,98,51,46,137,221,84,226,129,254,253,85,146,52,1,3, -149,40,44,255,0,200,75,134,50,1,252,113,34,34,255,203,0,0,0,2,0,163,0,0,4,96, -5,176,0,12,0,21,0,0,1,17,33,50,4,21,20,4,35,33,17,35,17,19,17,33,50,54,53,52, -38,35,1,104,1,13,232,1,3,254,253,232,254,243,197,197,1,13,147,147,147,147,5, -176,254,219,236,189,190,235,254,199,5,176,254,65,253,226,156,113,114,159,0,0, -0,1,0,137,255,235,4,92,6,19,0,39,0,0,33,35,17,52,54,51,50,22,21,14,1,21,20,18, -21,20,6,35,34,38,39,55,30,1,51,50,54,53,52,2,53,52,54,55,52,38,35,34,6,21,1, -77,196,221,198,186,247,51,48,226,198,169,89,184,40,78,40,119,56,99,91,226,58, -53,152,86,105,128,4,77,218,236,201,180,87,152,75,82,254,166,115,168,170,51,38, -141,28,48,105,88,76,1,94,110,99,164,91,72,113,156,144,0,0,3,0,88,255,235,6, -154,4,78,0,46,0,57,0,66,0,0,5,34,38,39,14,1,35,34,38,53,52,54,59,1,53,52,38, -35,34,6,21,47,1,38,54,51,50,22,23,62,1,51,50,18,29,1,33,7,30,1,51,50,54,55,23, -14,1,37,50,54,55,53,35,34,6,21,20,22,1,34,6,7,23,33,53,52,38,5,12,136,208,66, -56,223,160,170,185,230,220,229,104,97,103,122,188,2,5,230,190,114,175,50,64, -175,101,214,231,253,59,2,1,157,155,103,133,78,67,53,188,252,74,76,166,43,227, -120,135,100,3,92,113,138,11,2,1,252,120,21,97,90,79,108,174,151,157,172,87, -106,121,110,78,18,6,138,181,81,77,75,83,254,252,228,119,5,159,198,55,51,138, -44,78,154,87,57,214,111,80,74,93,3,46,169,133,5,31,122,154,0,0,2,0,72,255,235, -4,48,5,237,0,32,0,45,0,0,1,22,18,29,1,20,0,35,34,0,53,52,0,51,50,22,23,55,46, -1,39,5,39,37,46,1,39,55,30,1,23,55,23,1,50,54,61,1,46,1,35,34,6,21,20,22,3, -105,95,104,254,224,215,218,254,233,1,20,213,90,159,52,4,9,85,68,254,222,77,1, -0,39,83,44,60,79,144,63,218,77,254,17,133,169,35,161,118,131,161,164,5,17,104, -254,237,163,220,245,254,201,1,24,207,228,1,28,74,60,5,109,176,66,165,102,146, -22,34,14,164,19,66,46,125,102,251,4,228,174,148,59,81,208,149,132,201,0,0,3,0, -71,0,180,4,45,4,178,0,3,0,7,0,11,0,0,1,33,53,33,37,35,53,51,17,35,53,51,4,45, -252,26,3,230,254,113,198,198,198,198,2,85,188,214,203,252,2,203,0,0,0,3,0,97, -255,121,4,42,4,185,0,25,0,37,0,49,0,0,19,52,0,51,50,22,23,55,51,7,30,1,29,1, -20,0,35,34,38,39,7,35,55,46,1,53,51,20,22,23,51,1,46,1,35,34,6,21,33,52,38,39, -35,1,30,1,51,50,54,53,97,1,4,223,56,104,46,74,129,105,88,94,254,252,224,50,92, -42,72,129,100,97,103,197,40,41,6,1,77,30,67,37,141,145,2,63,34,33,6,254,185, -25,56,32,141,146,2,39,240,1,55,22,20,149,212,74,231,141,22,242,254,204,17,16, -147,203,72,240,149,91,152,48,2,162,17,18,226,170,80,140,47,253,106,12,11,224, -172,0,0,2,0,153,254,96,4,51,6,24,0,17,0,31,0,0,1,20,2,35,34,38,39,17,35,17,51, -17,62,1,51,50,18,17,35,52,38,35,34,6,7,17,30,1,51,50,54,53,4,51,224,197,100, -151,53,197,197,53,150,98,201,223,197,145,141,85,120,37,37,120,87,140,144,1, -244,234,254,225,67,67,253,239,7,184,253,170,68,72,254,193,254,250,184,237,77, -67,253,245,67,75,205,162,0,0,0,2,0,30,0,0,5,139,5,176,0,19,0,23,0,0,1,35,17, -35,17,33,17,35,17,35,53,51,17,51,17,33,17,51,17,51,1,33,53,33,5,139,140,197, -253,61,197,148,148,197,2,195,197,140,251,236,2,195,253,61,4,4,251,252,2,131, -253,125,4,4,146,1,26,254,230,1,26,254,230,254,136,230,0,0,0,1,0,153,0,0,1,94, -4,58,0,3,0,0,33,35,17,51,1,94,197,197,4,58,0,1,0,153,0,0,4,64,4,58,0,14,0,0,1, -35,17,35,17,51,17,51,1,51,23,9,1,7,35,1,195,101,197,197,84,1,132,231,2,254,62, -1,227,2,241,1,203,254,53,4,58,254,55,1,201,5,253,254,253,210,5,0,0,0,0,1,0,40, -0,0,4,46,5,176,0,13,0,0,1,37,21,5,17,33,21,33,17,7,53,55,17,51,1,104,1,13,254, -243,2,198,252,117,123,123,197,3,75,86,166,86,253,245,154,2,103,39,166,39,2, -163,0,1,0,37,0,0,2,14,6,24,0,11,0,0,1,55,21,7,17,35,17,7,53,55,17,51,1,120, -150,150,197,142,142,197,3,104,58,165,58,253,61,2,120,54,165,54,2,251,0,1,0, -160,254,75,4,237,5,176,0,24,0,0,1,17,20,6,35,34,38,39,55,30,1,51,50,54,61,1,1, -7,17,35,17,51,1,55,17,4,237,172,154,31,52,29,14,13,68,17,61,68,253,67,6,197, -197,2,189,6,5,176,249,247,167,181,9,9,150,5,8,103,90,89,4,88,2,251,170,5,176, -251,168,2,4,86,0,0,0,1,0,143,254,75,3,245,4,78,0,31,0,0,1,23,62,1,51,50,22,21, -17,20,6,35,34,38,39,55,30,1,51,50,54,53,17,52,38,35,34,6,7,17,35,17,1,63,13, -54,160,101,174,192,172,154,31,53,28,14,13,67,18,61,68,114,116,85,123,38,197,4, -58,150,81,89,205,214,252,252,167,181,9,9,160,5,7,94,88,3,0,143,120,66,59,252, -207,4,58,0,0,2,0,104,255,235,7,10,5,197,0,23,0,37,0,0,41,1,14,1,35,34,0,25,1, -16,0,51,50,22,23,33,21,33,17,33,21,33,17,33,5,50,54,55,17,46,1,35,34,6,21,17, -20,22,7,10,252,175,92,130,67,249,254,201,1,53,249,69,143,79,3,70,253,79,2,86, -253,170,2,188,251,142,61,122,58,61,122,60,169,192,194,10,11,1,76,1,9,1,48,1,9, -1,76,12,9,155,254,41,155,253,247,20,9,9,4,127,8,11,227,213,254,206,214,228,0, -3,0,97,255,235,6,219,4,78,0,36,0,56,0,65,0,0,5,34,38,39,14,1,35,34,0,61,1,52, -0,51,50,22,23,62,1,51,50,18,29,1,33,20,6,7,30,1,51,50,54,55,23,14,1,1,20,22, -51,50,54,55,46,1,61,1,52,54,55,46,1,35,34,6,21,1,34,6,7,23,33,53,52,38,5,93, -136,209,66,64,193,123,224,254,251,1,4,223,124,194,64,64,187,108,217,217,253, -78,2,2,16,155,141,98,116,79,49,54,155,251,68,145,143,120,141,20,3,2,2,3,20, -143,120,141,145,4,3,103,135,15,2,1,232,116,21,98,90,90,98,1,53,241,22,240,1, -55,100,90,89,101,254,242,224,104,15,28,21,140,167,41,42,139,39,59,2,38,172, -224,165,136,22,42,22,44,19,41,21,135,167,226,170,1,140,159,124,5,16,118,154,0, -0,1,0,19,255,235,2,117,5,63,0,31,0,0,1,17,51,21,35,21,51,21,35,17,20,22,51,50, -54,55,23,14,1,35,34,38,53,17,35,53,51,53,35,53,51,17,1,131,205,205,242,242,63, -52,17,41,16,27,23,86,42,119,143,162,162,171,171,5,63,254,251,146,149,146,254, -150,76,62,8,6,135,18,23,145,155,1,106,146,149,146,1,5,0,1,0,159,0,0,2,135,6, -45,0,15,0,0,51,17,52,54,51,50,22,23,7,46,1,35,34,6,21,17,159,182,162,33,69,42, -24,20,44,25,87,91,4,195,173,189,11,10,145,5,6,109,98,251,61,0,0,1,255,233,254, -75,2,192,6,45,0,37,0,0,33,21,20,6,35,34,38,39,55,30,1,51,50,54,53,17,35,53,51, -53,52,54,51,50,22,23,7,46,1,35,34,6,29,1,51,21,35,17,1,157,172,153,31,52,28, -14,13,66,18,59,69,169,170,180,162,34,69,42,24,18,51,27,87,83,196,196,89,167, -181,9,9,150,5,8,103,90,4,1,146,137,173,189,11,10,150,4,6,103,98,137,146,252, -88,0,0,2,0,108,255,235,6,49,5,197,0,23,0,37,0,0,1,16,0,33,34,0,25,1,16,0,51, -50,4,23,62,1,53,51,20,6,7,30,1,21,39,52,2,35,34,2,21,17,20,18,51,50,54,53,4, -253,254,181,254,248,255,254,193,1,63,255,183,1,23,72,84,88,197,166,154,5,7, -197,216,182,172,205,205,172,183,215,2,86,254,245,254,160,1,96,1,11,1,3,1,10,1, -98,179,152,31,160,121,187,240,40,33,67,34,2,200,1,0,255,0,200,254,251,202,255, -0,255,203,0,0,2,0,97,255,235,4,242,4,78,0,23,0,37,0,0,19,52,0,51,50,22,23,62, -1,53,51,20,6,7,30,1,29,1,20,0,35,34,0,53,51,20,22,51,50,54,61,1,52,38,35,34,6, -21,97,1,4,223,136,208,62,51,51,178,112,108,9,11,254,252,224,224,254,251,197, -145,143,141,146,147,142,141,145,2,39,240,1,55,120,107,27,110,76,137,189,41,41, -85,44,22,242,254,204,1,53,241,172,224,224,172,22,170,226,226,170,0,0,1,0,147, -255,235,6,88,5,177,0,27,0,0,1,17,23,62,1,53,51,23,22,6,7,17,20,0,35,34,0,53, -17,51,17,20,22,51,50,54,53,17,4,220,6,86,93,190,3,2,196,184,254,200,246,237, -254,210,197,191,151,160,201,5,176,254,217,1,25,154,118,5,193,243,33,254,18, -240,254,242,1,15,239,3,199,252,57,167,189,189,167,3,199,0,0,0,0,1,0,139,255, -235,5,106,4,59,0,29,0,0,1,23,22,6,7,17,35,39,14,1,35,34,38,53,17,51,17,20,22, -51,50,54,55,17,51,21,23,62,1,53,5,100,3,3,177,189,177,13,51,161,104,177,198, -197,102,108,105,137,35,197,6,100,85,4,59,6,177,192,14,253,74,161,87,95,226, -239,2,126,253,128,173,130,86,79,3,10,241,2,7,120,117,0,0,1,255,188,254,75,1, -112,4,58,0,15,0,0,1,17,20,6,35,34,38,39,55,30,1,51,50,54,53,17,1,112,172,153, -31,51,29,14,14,65,18,59,69,4,58,251,109,167,181,9,9,150,5,8,103,90,4,147,0,0, -0,1,0,110,4,228,3,77,5,235,0,8,0,0,1,7,35,39,7,35,39,1,51,3,77,2,170,196,196, -169,2,1,12,198,4,234,6,176,176,6,1,1,0,0,0,1,0,85,4,228,3,54,5,235,0,8,0,0,1, -55,51,23,1,35,1,55,51,1,197,196,171,2,254,242,198,254,243,2,170,5,59,176,6, -254,255,1,1,6,0,1,0,129,4,164,2,216,5,176,0,15,0,0,1,23,22,6,35,34,38,63,1,51, -20,22,51,50,54,53,2,210,2,4,162,137,138,162,5,2,151,68,74,72,70,5,176,6,116, -146,146,116,6,66,82,83,65,0,0,0,0,1,0,160,4,231,1,122,5,176,0,3,0,0,1,35,53, -51,1,122,218,218,4,231,201,0,0,0,0,2,0,165,4,118,2,2,5,197,0,11,0,23,0,0,19, -52,54,51,50,22,21,20,6,35,34,38,55,20,22,51,50,54,53,52,38,35,34,6,165,103,73, -72,101,101,72,73,103,100,44,32,30,43,43,30,32,44,5,27,72,98,98,72,73,92,93,72, -32,43,42,33,33,45,45,0,0,1,0,18,254,98,1,224,0,0,0,15,0,0,33,23,14,1,7,21,33, -21,33,46,1,53,52,54,55,53,1,156,2,75,115,1,1,1,254,56,3,3,122,83,109,3,79,67, -23,133,19,41,17,122,168,23,24,0,0,0,0,1,0,135,4,225,3,61,5,243,0,19,0,0,1,20, -6,35,34,38,35,34,6,21,39,52,54,51,50,22,51,50,54,53,3,61,119,90,71,154,51,43, -58,108,118,91,56,168,52,41,60,5,211,94,130,93,65,46,26,93,137,94,65,47,0,2,0, -100,4,228,3,74,5,238,0,5,0,10,0,0,1,51,23,1,35,39,3,51,23,3,35,2,98,229,3,254, -212,171,2,85,211,2,240,157,5,238,6,254,252,5,1,5,5,254,251,0,255,255,0,182, -254,131,1,236,255,173,0,15,0,156,0,36,250,142,56,209,255,255,0,36,4,240,1,64, -6,79,0,71,0,64,255,235,254,123,44,156,84,128,0,0,255,255,0,210,4,239,1,239,6, -80,0,71,0,113,0,121,254,118,43,177,84,192,0,0,255,255,0,135,4,225,3,61,5,243, -0,6,0,158,0,0,255,255,255,187,4,228,2,161,5,238,0,71,0,159,3,5,0,0,192,1,64,0, -0,0,0,1,0,148,4,246,1,100,5,252,0,3,0,0,19,51,3,35,148,208,67,83,5,252,254, -250,0,0,0,3,0,161,4,232,3,101,6,165,0,3,0,7,0,11,0,0,1,35,55,51,5,35,53,51,55, -51,7,35,3,101,219,20,199,254,22,218,198,48,219,38,142,4,232,200,200,200,245, -233,0,0,255,255,0,161,2,112,1,103,3,68,0,6,0,116,0,0,0,1,0,163,0,0,4,32,5,176, -0,5,0,0,1,33,17,35,17,33,4,32,253,72,197,3,125,5,21,250,235,5,176,0,0,0,0,2,0, -30,0,0,5,112,5,176,0,3,0,7,0,0,1,51,1,33,37,33,1,35,2,135,169,2,64,250,174,1, -8,3,70,254,112,6,5,176,250,80,154,4,26,0,0,0,0,3,0,113,255,235,5,2,5,197,0,3, -0,17,0,31,0,0,1,33,53,33,5,16,0,33,34,0,25,1,16,0,51,32,0,17,39,52,2,35,34,2, -21,17,20,18,51,50,54,53,3,191,254,3,1,253,1,67,254,181,254,248,255,254,193,1, -63,255,1,8,1,75,197,216,182,172,205,205,172,183,215,2,147,154,215,254,245,254, -160,1,96,1,11,1,3,1,10,1,98,254,159,254,245,2,200,1,0,255,0,200,254,251,202, -255,0,255,203,0,0,0,0,1,0,49,0,0,5,7,5,176,0,7,0,0,1,35,1,35,1,51,1,35,2,159, -6,254,97,201,2,22,170,2,22,201,4,147,251,109,5,176,250,80,0,0,0,3,0,123,0,0,4, -36,5,176,0,3,0,7,0,11,0,0,55,33,21,33,19,33,21,33,3,33,21,33,123,3,169,252,87, -83,2,249,253,7,82,3,156,252,100,154,154,3,65,155,3,10,155,0,0,0,0,1,0,168,0,0, -4,247,5,176,0,7,0,0,33,35,17,33,17,35,17,33,4,247,197,253,59,197,4,79,5,21, -250,235,5,176,0,1,0,70,0,0,4,72,5,176,0,14,0,0,9,1,23,33,21,33,53,9,1,53,33, -21,33,7,1,2,246,254,67,3,3,12,251,254,1,224,254,32,3,208,253,38,3,1,189,2,203, -253,213,5,155,147,2,69,2,69,147,155,5,253,211,0,0,0,0,3,0,84,0,0,5,77,5,176,0, -17,0,26,0,35,0,0,1,22,0,21,20,0,7,21,35,53,38,0,53,52,0,55,53,51,1,20,22,63,1, -17,39,38,6,5,52,38,35,7,17,23,22,54,3,52,230,1,51,254,205,230,197,232,254,205, -1,51,232,197,253,227,177,161,6,6,160,178,3,114,178,157,6,6,157,178,4,205,5, -254,229,218,221,254,227,4,213,213,3,1,28,221,219,1,30,4,226,253,33,161,187,1, -2,2,179,2,1,189,158,159,187,2,253,77,2,1,189,0,0,1,0,87,0,0,5,27,5,176,0,25,0, -0,1,23,62,1,53,17,51,17,20,0,7,17,35,17,38,0,53,17,51,17,20,22,23,55,17,51,3, -19,6,144,173,197,254,226,234,198,227,254,237,196,164,136,6,198,1,229,2,19,211, -172,2,59,253,197,245,254,215,24,254,193,1,64,24,1,40,245,2,59,253,197,170,210, -20,1,3,202,0,0,0,1,0,112,0,0,4,208,5,197,0,35,0,0,37,54,18,61,1,52,38,35,34,6, -29,1,20,18,23,21,33,53,51,38,2,61,1,16,0,51,50,0,17,21,20,2,7,33,21,33,2,223, -141,157,193,170,169,192,161,143,254,17,253,120,139,1,53,249,249,1,55,139,118, -1,3,254,15,159,25,1,31,251,118,233,249,249,233,118,251,254,224,24,159,154,92, -1,53,167,116,1,28,1,99,254,157,254,228,116,167,254,204,93,154,0,0,0,0,2,0,98, -255,235,4,128,4,78,0,28,0,43,0,0,1,17,20,22,51,50,54,55,23,14,1,35,34,38,39, -14,1,35,34,2,61,1,16,18,51,50,22,23,55,1,20,22,51,50,54,55,53,17,46,1,35,34,6, -21,3,233,41,35,15,26,11,23,29,60,37,75,100,24,55,153,99,198,224,223,201,101, -155,55,51,253,179,135,140,81,114,39,39,115,78,141,136,4,57,252,219,72,56,3,4, -142,20,14,64,69,66,67,1,31,234,21,1,5,1,64,72,68,119,253,187,164,203,71,64,8, -2,29,60,70,239,187,0,2,0,157,254,31,4,79,5,197,0,20,0,42,0,0,1,50,22,21,20,6, -7,30,1,21,20,6,35,34,38,39,17,35,17,52,36,19,50,54,53,52,38,35,34,6,21,17,30, -1,51,50,54,53,52,38,43,1,53,2,95,195,236,100,87,119,133,253,202,83,154,57,197, -1,10,180,122,116,125,109,107,146,44,141,89,129,149,131,111,143,5,197,220,174, -91,153,45,44,196,129,209,237,51,51,253,206,6,18,165,239,253,151,121,106,95, -140,143,106,252,194,52,58,160,128,112,172,155,0,0,1,0,46,254,95,3,228,4,58,0, -11,0,0,1,51,1,17,35,17,1,51,1,23,51,55,3,27,201,254,137,197,254,134,202,1,0, -17,6,19,4,58,252,4,254,33,1,228,3,247,253,5,76,76,0,0,0,2,0,97,255,235,4,42,5, -176,0,20,0,34,0,0,1,21,33,7,1,30,1,29,1,20,0,35,34,0,61,1,52,18,55,37,53,1,34, -6,29,1,20,22,51,50,54,61,1,52,38,3,170,254,57,1,1,97,110,121,254,252,224,224, -254,251,220,192,254,208,1,119,141,145,145,143,141,146,147,5,176,151,6,254,246, -69,253,160,22,242,254,204,1,53,241,22,219,1,45,26,241,118,254,3,226,170,22, -172,224,224,172,22,170,226,0,0,0,1,0,98,255,237,3,233,4,76,0,42,0,0,1,34,6,21, -20,22,51,50,54,53,51,23,22,4,35,34,38,53,52,54,55,46,1,53,52,54,51,50,22,15,1, -35,52,38,35,34,6,21,20,22,59,1,21,2,26,121,121,137,118,112,145,186,2,5,254, -246,184,202,251,103,99,87,96,233,201,183,249,5,2,186,139,100,116,121,109,115, -209,1,221,85,87,73,100,112,76,6,162,171,173,151,91,128,32,35,122,73,150,164, -175,139,6,70,98,95,67,74,85,150,0,0,0,1,0,115,254,88,3,202,5,176,0,33,0,0,1, -21,1,14,1,21,20,22,59,1,50,22,21,14,1,7,39,62,1,53,52,38,43,1,34,38,53,52,18, -55,1,39,33,53,3,202,254,170,129,113,105,102,32,159,180,2,155,109,81,66,94,82, -90,52,179,185,139,144,1,12,2,253,145,5,176,112,254,80,153,227,145,116,117,127, -128,111,165,47,127,31,86,70,52,58,214,168,120,1,65,169,1,48,5,155,0,1,0,143, -254,97,3,245,4,78,0,19,0,0,1,23,62,1,51,50,22,21,17,35,17,52,38,35,34,6,7,17, -35,17,1,63,13,54,160,101,177,189,197,114,116,85,123,38,197,4,58,150,81,89,195, -224,251,182,4,70,143,125,67,60,252,204,4,58,0,3,0,119,255,235,4,22,5,197,0,13, -0,22,0,31,0,0,1,20,2,35,34,2,53,17,52,18,51,50,18,21,5,33,17,52,38,35,34,6,21, -1,33,21,20,22,51,50,54,53,4,22,251,212,211,253,251,211,212,253,253,38,2,21, -140,128,127,138,2,21,253,235,141,126,128,138,2,2,247,254,224,1,32,247,1,172, -245,1,34,254,222,245,229,1,14,157,182,182,157,254,88,85,157,184,183,158,0,0,0, -1,0,197,255,235,2,115,4,57,0,15,0,0,1,17,20,22,51,50,54,55,23,14,1,35,34,38, -53,17,1,138,53,45,25,48,18,44,45,89,53,119,124,4,57,252,211,73,56,15,11,133, -31,22,142,158,3,34,0,0,0,1,0,56,255,239,4,94,5,238,0,33,0,0,33,35,1,39,46,1, -35,34,6,35,53,62,1,51,50,22,23,1,30,1,51,50,54,55,7,14,1,35,34,38,39,3,15,1,1, -19,219,1,135,55,32,87,60,10,54,4,20,63,24,129,153,40,1,104,22,71,44,14,9,24,3, -11,37,11,118,143,53,202,6,29,4,4,145,84,106,5,145,5,10,162,108,252,78,71,84,1, -4,154,5,10,130,140,2,19,1,113,0,0,0,1,0,45,254,68,3,235,5,176,0,46,0,0,1,21, -33,14,1,21,20,22,59,1,21,35,34,6,21,20,22,59,1,50,22,21,14,1,7,39,62,1,53,52, -38,43,1,34,36,53,52,54,55,46,1,53,52,54,55,35,53,3,235,254,95,123,125,145,155, -142,142,159,164,150,130,61,161,178,2,155,109,79,65,94,70,75,69,213,254,248, -134,129,113,127,64,61,221,5,176,155,8,142,105,105,116,155,135,133,119,149,127, -129,111,164,47,127,31,85,70,52,60,226,199,127,174,42,42,155,96,86,131,42,155, -0,0,0,0,1,0,79,255,235,4,204,4,58,0,23,0,0,1,35,17,20,22,51,50,54,55,23,14,1, -35,34,38,53,17,33,17,35,17,35,53,33,4,94,123,53,45,25,48,18,44,45,89,53,119, -124,254,145,197,155,4,15,3,158,253,110,73,56,15,11,133,31,22,142,158,2,135, -252,98,3,158,156,0,0,0,2,0,143,254,96,4,36,4,78,0,16,0,30,0,0,1,20,2,35,34,38, -39,17,35,17,53,52,0,51,50,18,17,35,52,38,35,34,6,21,17,30,1,51,50,54,53,4,36, -219,197,97,152,55,197,1,1,192,227,241,197,132,139,123,129,37,120,87,139,140,1, -244,235,254,226,60,58,253,255,3,224,1,247,1,22,254,195,254,248,189,237,231, -140,254,211,67,75,204,163,0,0,1,0,98,254,87,3,225,4,78,0,34,0,0,1,50,22,15,1, -35,52,38,35,34,6,29,1,20,22,51,50,22,21,14,1,7,39,62,1,53,52,38,35,34,0,61,1, -52,18,2,61,187,233,4,2,178,122,114,138,140,155,163,170,190,2,155,109,81,66,94, -83,90,246,254,243,255,4,78,209,178,6,103,135,230,155,42,152,215,127,129,111, -164,47,127,31,85,70,53,58,1,42,223,42,227,1,57,0,0,0,2,0,97,255,235,4,124,4, -58,0,16,0,30,0,0,1,33,30,1,29,1,20,0,35,34,0,61,1,52,0,51,33,1,20,22,51,50,54, -61,1,52,38,35,34,6,21,4,124,254,187,108,135,254,248,220,224,254,251,1,4,223,2, -56,252,170,145,143,141,146,147,142,141,145,3,158,74,222,118,22,210,254,211,1, -53,241,22,232,1,43,253,215,172,224,224,172,22,161,214,214,161,0,0,0,0,1,0,81, -0,0,3,220,4,58,0,7,0,0,1,33,17,35,17,33,53,33,3,220,254,154,197,254,160,3,139, -3,161,252,95,3,161,153,0,0,0,1,0,141,255,235,4,38,4,58,0,21,0,0,1,17,20,22,51, -50,54,53,38,2,39,51,22,18,21,20,2,35,34,38,53,17,1,82,138,117,137,135,5,86,73, -206,69,86,222,237,221,241,4,58,253,156,175,162,253,176,127,1,1,136,106,254, -253,155,255,254,184,242,251,2,98,0,0,2,0,83,254,34,5,87,4,58,0,24,0,33,0,0,1, -50,0,21,20,0,5,17,35,17,36,0,53,52,18,55,51,6,2,7,20,22,23,55,17,1,46,1,15,1, -17,23,62,1,3,46,228,1,69,254,241,254,230,197,254,238,254,252,64,52,206,57,66, -2,163,168,6,2,41,4,186,160,6,6,177,173,4,58,254,191,237,218,254,213,23,254,50, -1,206,25,1,65,234,153,1,1,108,134,254,254,126,155,238,23,2,3,164,253,210,163, -237,4,2,252,253,2,21,217,0,1,0,91,254,38,5,77,4,58,0,29,0,0,1,17,23,62,1,53, -38,2,39,51,22,18,21,20,0,5,17,35,17,38,0,25,1,51,17,20,22,23,55,17,3,37,6,177, -172,3,66,56,207,51,64,254,246,254,226,198,247,254,243,197,169,144,6,4,57,252, -92,2,23,241,156,125,1,1,133,106,255,0,153,240,254,190,22,254,55,1,203,25,1,46, -1,28,1,230,254,24,207,219,19,2,3,162,0,0,0,1,0,108,255,235,6,96,4,58,0,40,0,0, -1,6,2,7,20,22,51,50,54,53,17,51,17,20,22,51,50,54,53,38,2,39,51,22,18,21,20,2, -35,34,38,39,14,1,35,34,2,53,52,18,55,1,213,74,86,4,112,120,107,127,198,126, -108,120,112,5,86,73,207,68,86,202,216,127,175,42,43,175,125,217,202,85,70,4, -58,134,254,253,127,190,239,162,175,1,44,254,212,175,162,237,192,127,1,3,134, -106,254,252,154,255,254,184,122,119,119,122,1,72,255,155,1,4,105,0,0,1,0,57, -255,206,5,150,5,176,0,23,0,0,1,33,17,51,50,0,21,6,2,7,39,62,1,53,46,1,43,1,17, -35,17,33,53,33,4,184,254,32,171,235,1,40,2,195,190,51,128,112,1,182,150,171, -197,254,38,4,127,5,21,254,91,255,0,220,138,254,230,34,148,34,157,115,147,164, -253,53,5,21,155,0,0,1,0,135,255,236,4,208,5,198,0,33,0,0,1,33,7,30,1,51,50,54, -53,51,23,22,0,35,34,0,25,1,16,0,51,50,0,15,1,35,52,38,35,34,2,29,1,33,3,126, -253,214,3,4,194,158,164,180,189,2,4,254,216,243,247,254,201,1,55,247,247,1,36, -4,2,189,180,164,165,196,2,50,2,57,5,185,245,177,156,6,205,254,236,1,94,1,13,1, -3,1,13,1,95,254,249,217,6,153,178,254,246,197,137,0,0,0,0,2,0,69,0,0,8,73,5, -176,0,22,0,31,0,0,1,17,33,50,4,21,20,4,35,33,17,33,3,16,2,43,1,53,51,50,18,27, -1,1,17,33,50,54,53,52,38,35,4,247,1,103,232,1,3,254,253,232,253,212,254,27,1, -215,251,53,41,149,132,1,1,3,110,1,103,147,147,147,147,5,176,253,201,247,198, -198,246,5,21,253,237,254,111,254,143,154,1,30,1,74,2,174,253,47,253,187,169, -123,121,168,0,0,0,2,0,168,0,0,8,73,5,176,0,18,0,27,0,0,1,33,17,51,17,33,50,4, -21,20,4,35,33,17,33,17,35,17,51,1,17,33,50,54,53,52,38,35,1,109,2,197,197,1, -103,233,1,2,254,253,232,253,212,253,59,197,197,3,138,1,103,148,146,146,148,3, -59,2,117,253,152,228,188,189,235,2,161,253,95,5,176,252,253,253,248,148,113, -112,147,0,0,1,0,73,0,0,5,120,5,176,0,19,0,0,1,33,17,51,50,22,21,17,35,17,52, -38,43,1,17,35,17,33,53,33,4,200,254,32,167,238,251,197,140,152,167,197,254,38, -4,127,5,21,254,91,220,238,254,90,1,166,166,137,253,43,5,21,155,0,0,1,0,169, -254,218,4,247,5,176,0,11,0,0,19,51,17,33,17,51,17,33,17,35,17,33,169,197,2, -196,197,254,65,197,254,54,5,176,250,235,5,21,250,80,254,218,1,38,0,2,0,163,0, -0,4,187,5,176,0,12,0,21,0,0,1,33,17,33,50,4,21,20,4,35,33,17,33,1,17,33,50,54, -53,52,38,35,4,32,253,72,1,103,233,1,3,254,252,232,253,212,3,125,253,72,1,103, -147,148,147,148,5,21,254,91,239,197,198,246,5,176,253,37,253,197,169,123,119, -160,0,2,0,54,255,69,5,238,5,176,0,14,0,21,0,0,37,51,17,35,53,33,21,35,17,51, -50,18,27,1,33,1,6,2,7,33,17,33,5,39,199,197,251,210,197,104,141,158,44,73,2, -233,253,149,31,102,83,2,126,254,142,154,254,171,187,187,1,85,1,104,1,97,2,77, -253,179,251,254,156,106,4,123,0,0,0,1,0,26,0,0,6,124,5,176,0,21,0,0,1,35,17, -35,17,35,1,35,9,1,51,1,51,17,51,17,51,1,51,9,1,35,3,231,54,196,63,254,97,245, -1,239,254,57,230,1,132,65,196,57,1,132,230,254,57,1,239,245,2,156,253,100,2, -156,253,100,3,2,2,174,253,135,2,121,253,135,2,121,253,83,252,253,0,0,0,1,0, -120,255,235,4,223,5,197,0,42,0,0,1,20,6,7,30,1,21,20,4,33,34,36,63,1,51,20,22, -51,50,54,53,52,38,43,1,53,51,50,54,53,52,38,35,34,6,21,35,39,38,36,51,32,4,4, -201,136,120,135,143,254,193,254,254,226,254,188,5,2,188,198,157,178,202,184, -180,183,183,174,168,181,177,141,193,188,1,6,1,49,224,1,1,1,42,4,38,101,167,47, -42,174,125,201,226,214,205,6,114,157,149,120,133,129,156,132,114,112,144,142, -105,6,176,220,216,0,0,1,0,173,0,0,4,250,5,176,0,11,0,0,1,51,17,35,17,39,1,35, -17,51,17,23,4,53,197,197,6,253,67,197,197,6,5,176,250,80,4,86,2,251,168,5,176, -251,171,2,0,0,0,1,0,69,0,0,4,247,5,176,0,15,0,0,1,17,35,17,33,3,16,2,43,1,53, -51,50,18,27,1,4,247,197,254,27,1,215,251,53,41,149,132,1,1,5,176,250,80,5,21, -253,237,254,111,254,143,154,1,30,1,74,2,174,0,0,1,0,66,255,235,4,200,5,176,0, -21,0,0,1,23,51,1,51,1,14,1,35,34,38,39,55,30,1,51,50,54,63,1,1,51,2,56,74,6,1, -92,228,253,239,56,160,154,65,113,33,25,33,96,36,82,98,30,39,254,25,221,3,7, -191,3,104,251,63,124,136,22,15,144,10,17,85,67,83,4,64,0,0,0,0,1,0,161,254, -213,5,174,5,176,0,11,0,0,19,51,17,33,17,51,17,51,17,35,17,33,161,197,2,197, -197,190,197,251,184,5,176,250,235,5,21,250,240,254,53,1,43,0,0,1,0,147,0,0,4, -204,5,176,0,15,0,0,1,17,35,17,33,34,38,53,17,51,17,20,22,51,33,17,4,204,197, -254,117,241,248,198,138,153,1,139,5,176,250,80,2,74,211,237,1,166,254,90,165, -127,2,202,0,0,0,1,0,164,0,0,7,143,5,176,0,11,0,0,1,17,33,17,51,17,33,17,51,17, -33,17,1,105,2,80,196,2,77,197,249,21,5,176,250,234,5,22,250,234,5,22,250,80,5, -176,0,0,0,1,0,164,254,210,8,60,5,176,0,15,0,0,1,35,17,33,17,51,17,33,17,51,17, -33,17,51,17,51,8,60,197,249,45,197,2,80,196,2,77,197,173,254,210,1,46,5,176, -250,234,5,22,250,234,5,22,250,237,0,0,2,0,1,0,0,5,94,5,176,0,12,0,21,0,0,19, -33,17,33,50,4,21,20,4,35,33,17,33,1,17,33,50,54,53,52,38,35,1,2,10,1,103,233, -1,3,254,252,232,253,212,254,187,2,10,1,103,147,148,147,148,5,176,253,192,239, -197,198,246,5,22,253,191,253,197,169,123,119,160,0,0,3,0,163,0,0,6,50,5,176,0, -10,0,19,0,23,0,0,1,33,50,4,21,20,4,35,33,17,51,25,1,33,50,54,53,52,38,35,1,35, -17,51,1,104,1,103,233,1,3,254,252,232,253,212,197,1,103,147,148,147,148,3,99, -198,198,3,112,239,197,198,246,5,176,253,37,253,197,169,123,119,160,253,43,5, -176,0,0,0,0,2,0,163,0,0,4,187,5,176,0,10,0,19,0,0,1,33,50,4,21,20,4,35,33,17, -51,25,1,33,50,54,53,52,38,35,1,104,1,103,233,1,3,254,252,232,253,212,197,1, -103,147,148,147,148,3,112,239,197,198,246,5,176,253,37,253,197,169,123,119, -160,0,0,1,0,181,255,236,4,255,5,198,0,33,0,0,19,39,38,0,51,50,0,25,1,16,0,35, -34,0,63,1,51,20,22,51,50,18,61,1,33,53,33,53,52,2,35,34,6,21,188,2,5,1,41,242, -247,1,56,254,200,247,247,254,220,5,2,189,178,165,164,197,253,194,2,62,197,164, -165,178,3,222,6,203,1,23,254,161,254,243,254,253,254,242,254,163,1,5,218,6, -154,177,1,9,198,81,155,25,198,1,11,178,155,0,0,2,0,190,255,235,6,226,5,197,0, -20,0,34,0,0,1,16,0,33,34,0,39,35,17,35,17,51,17,51,53,16,0,51,32,0,17,39,52,2, -35,34,2,21,17,20,18,51,50,54,53,6,226,254,181,254,248,244,254,197,14,206,198, -198,205,1,63,255,1,8,1,75,197,216,182,172,205,205,172,183,215,2,86,254,245, -254,160,1,67,250,253,216,5,176,253,18,151,1,10,1,98,254,159,254,245,2,200,1,0, -255,0,200,254,251,202,255,0,255,203,0,0,2,0,44,0,0,4,54,5,176,0,13,0,22,0,0, -51,35,1,46,1,53,52,36,51,33,17,35,17,33,1,33,34,6,21,20,22,51,33,253,209,1,86, -142,147,1,18,241,1,210,197,254,189,1,67,254,243,156,162,163,153,1,15,2,149,51, -190,136,199,219,250,80,2,97,2,180,139,122,123,152,0,2,0,97,255,235,4,42,6,17, -0,32,0,46,0,0,1,50,0,29,1,20,0,35,34,0,61,1,60,1,55,53,16,18,55,62,1,53,51,23, -22,6,7,14,1,7,23,62,1,23,34,6,29,1,20,22,51,50,54,61,1,52,38,2,68,225,1,5,254, -252,224,224,254,251,1,254,233,119,99,151,2,4,162,196,128,186,14,4,53,163,86, -141,144,144,143,141,146,147,4,78,254,202,241,22,242,254,204,1,53,241,22,8,11, -7,143,1,60,1,102,30,15,48,66,6,156,107,26,18,168,128,4,70,92,155,226,170,22, -172,224,224,172,22,170,226,0,3,0,144,0,0,4,35,4,58,0,14,0,23,0,32,0,0,51,17, -33,50,22,21,20,6,7,30,1,21,20,6,35,1,17,33,50,54,53,52,38,35,37,51,50,54,53, -52,38,43,1,144,1,171,214,236,92,84,101,113,221,198,254,213,1,43,109,112,112, -109,254,213,231,125,127,128,125,230,4,58,149,149,76,119,31,25,137,88,152,156, -1,218,254,190,83,78,77,84,151,74,75,77,78,0,0,1,0,143,0,0,2,190,4,58,0,5,0,0, -1,33,17,35,17,33,2,190,254,150,197,2,47,3,158,252,98,4,58,0,0,0,0,2,0,69,255, -69,4,203,4,58,0,14,0,21,0,0,55,50,54,27,1,33,17,51,17,35,53,33,21,35,17,1,14, -1,7,33,17,33,174,99,81,25,37,2,156,143,197,253,4,197,1,251,17,54,48,1,174,254, -222,154,247,1,18,1,151,252,96,254,171,187,187,1,85,2,9,184,255,82,2,241,0,1,0, -26,0,0,5,166,4,58,0,21,0,0,1,35,17,35,17,35,1,35,9,1,51,1,51,17,51,17,51,1,51, -9,1,35,3,124,58,197,58,254,207,248,1,148,254,142,238,1,30,53,197,54,1,31,237, -254,142,1,148,248,1,213,254,43,1,213,254,43,2,60,1,254,254,66,1,190,254,66,1, -190,254,2,253,196,0,0,0,1,0,100,255,237,3,236,4,76,0,42,0,0,1,50,54,53,52,38, -35,34,6,21,35,39,38,54,51,50,22,21,20,6,7,30,1,21,20,6,35,34,36,63,1,51,20,22, -51,50,54,53,52,38,43,1,53,2,51,115,109,121,115,102,138,186,2,6,250,184,200, -233,97,86,98,105,252,201,185,254,246,6,2,186,144,113,117,138,122,121,208,2, -120,80,74,67,95,98,70,6,139,175,163,151,73,122,35,32,128,91,151,173,171,162,6, -76,112,100,73,86,81,160,0,0,0,1,0,143,0,0,3,252,4,58,0,11,0,0,1,51,17,35,17, -39,1,35,17,51,17,23,3,55,197,197,6,254,34,196,196,6,4,58,251,198,3,0,2,252, -254,4,58,253,0,2,0,0,0,1,0,153,0,0,4,64,4,58,0,14,0,0,1,35,17,35,17,51,17,51, -1,51,23,9,1,7,35,1,195,101,197,197,84,1,131,231,2,254,63,1,227,2,242,1,203, -254,53,4,58,254,55,1,201,5,253,254,253,210,5,0,0,0,0,1,0,65,0,0,3,252,4,58,0, -15,0,0,1,17,35,17,33,17,16,2,43,1,63,1,50,54,53,17,3,252,197,254,196,178,207, -57,4,41,108,91,4,58,251,198,3,158,254,206,254,194,254,210,168,1,209,242,1,206, -0,1,0,153,0,0,5,85,4,58,0,15,0,0,1,51,1,51,17,35,17,39,1,35,1,7,17,35,17,51,2, -247,6,1,98,246,197,6,254,180,136,254,174,6,197,254,1,2,3,56,251,198,2,239,2, -253,15,3,2,2,253,0,4,58,0,1,0,143,0,0,3,251,4,58,0,11,0,0,33,35,17,33,17,35, -17,51,17,33,17,51,3,251,197,254,30,197,197,1,226,197,1,204,254,52,4,58,254,44, -1,212,0,0,0,1,0,143,0,0,3,252,4,58,0,7,0,0,33,35,17,33,17,35,17,33,3,252,197, -254,29,197,3,109,3,158,252,98,4,58,0,1,0,71,0,0,3,209,4,58,0,7,0,0,1,33,17,35, -17,33,53,33,3,209,254,155,197,254,160,3,138,3,161,252,95,3,161,153,0,0,0,3,0, -98,254,96,6,191,6,24,0,31,0,45,0,59,0,0,19,16,18,51,50,22,23,17,51,17,62,1,51, -50,18,17,21,20,2,35,34,38,39,17,35,17,14,1,35,34,2,53,37,52,38,35,34,6,7,17, -30,1,51,50,54,53,33,20,22,51,50,54,55,17,46,1,35,34,6,21,98,223,201,88,142,53, -197,55,151,96,200,223,224,197,97,152,55,197,54,141,90,198,224,5,152,145,141, -85,120,37,37,120,87,140,144,251,45,135,140,81,115,39,39,115,79,141,136,2,9,1, -5,1,64,55,53,2,54,253,186,61,63,254,193,254,250,21,234,254,225,60,58,253,255, -1,247,54,54,1,31,234,21,185,241,79,68,253,243,67,75,204,163,164,203,72,65,2, -34,61,70,239,187,0,0,1,0,143,255,69,4,128,4,58,0,11,0,0,19,51,17,33,17,51,17, -51,17,35,53,33,143,197,1,227,197,132,197,252,212,4,58,252,96,3,160,252,96,254, -171,187,0,0,0,1,0,115,0,0,3,220,4,58,0,15,0,0,33,35,17,35,34,38,53,17,51,17, -20,22,59,1,17,51,3,220,197,208,236,232,197,124,147,208,197,1,165,174,222,1,9, -254,247,145,96,1,250,0,0,0,0,1,0,143,0,0,5,216,4,58,0,11,0,0,1,17,33,17,51,17, -33,17,51,17,33,17,1,84,1,125,197,1,125,197,250,183,4,58,252,96,3,160,252,96,3, -160,251,198,4,58,0,0,0,1,0,143,255,84,6,136,4,58,0,15,0,0,1,17,33,17,51,17,33, -17,51,17,51,17,35,53,33,17,1,84,1,125,197,1,125,197,176,195,250,202,4,58,252, -96,3,160,252,96,3,160,252,88,254,194,172,4,58,0,0,2,255,244,0,0,4,82,4,58,0, -14,0,23,0,0,1,33,50,22,21,20,6,35,33,17,35,53,51,53,51,25,1,33,50,54,53,52,38, -35,1,176,1,13,192,213,215,190,254,46,247,247,197,1,13,106,101,102,105,2,158, -184,147,148,191,3,47,154,113,253,202,254,150,102,76,74,110,0,0,0,0,3,0,153,0, -0,5,172,4,58,0,10,0,14,0,23,0,0,1,33,50,22,21,20,6,35,33,17,51,1,35,17,51,1, -17,33,50,54,53,52,38,35,1,94,1,13,192,213,215,190,254,46,197,4,78,197,197,251, -178,1,13,106,101,102,105,2,158,184,147,148,191,4,58,251,198,4,58,253,202,254, -150,102,76,74,110,0,0,0,0,2,0,153,0,0,4,0,4,58,0,10,0,19,0,0,1,33,50,22,21,20, -6,35,33,17,51,25,1,33,50,54,53,52,38,35,1,94,1,13,192,213,215,190,254,46,197, -1,13,106,101,102,105,2,158,184,147,148,191,4,58,253,202,254,150,102,76,74,110, -0,0,0,0,1,0,99,255,235,3,227,4,78,0,33,0,0,1,34,6,21,35,39,38,54,51,50,18,29, -1,20,0,35,34,38,63,1,51,20,22,51,50,54,55,39,33,53,33,55,46,1,2,8,92,143,178, -2,6,255,166,220,255,255,0,219,183,238,5,2,179,135,100,126,138,8,3,254,62,1, -192,2,10,137,3,179,122,87,6,139,219,254,199,227,42,228,254,199,223,163,6,99, -139,196,140,5,154,5,131,183,0,0,0,2,0,153,255,235,6,36,4,78,0,21,0,35,0,0,1, -52,0,51,50,0,29,1,20,0,35,34,38,39,33,17,35,17,51,17,51,53,51,20,22,51,50,54, -61,1,52,38,35,34,6,21,2,91,1,4,223,225,1,5,254,252,224,185,246,38,254,243,197, -197,253,197,145,143,141,146,147,142,141,145,2,39,240,1,55,254,202,241,22,242, -254,204,214,179,254,140,4,58,253,212,3,172,224,224,172,22,170,226,226,170,0,0, -0,2,0,117,0,0,3,242,4,58,0,13,0,22,0,0,1,17,35,17,33,3,35,19,46,1,53,52,54,51, -3,20,22,51,33,17,33,34,6,3,242,197,254,252,224,212,238,114,123,222,193,217, -109,107,1,25,254,232,107,110,4,58,251,198,1,164,254,92,1,189,36,162,108,146, -185,254,179,72,102,1,98,107,0,0,0,1,255,242,254,75,4,3,6,24,0,43,0,0,1,35,21, -62,1,51,50,22,29,1,51,17,20,6,35,34,38,39,55,30,1,51,50,54,61,1,35,17,52,38, -35,34,6,7,17,35,17,35,53,51,17,51,17,51,2,64,236,56,163,99,173,193,3,172,154, -33,52,28,15,13,68,17,60,68,2,115,114,88,130,40,197,157,157,197,236,4,104,191, -78,87,208,216,222,253,223,167,181,8,9,151,5,8,103,90,89,2,168,134,128,69,62, -252,213,4,104,124,1,52,254,204,0,1,0,97,255,235,3,217,4,78,0,34,0,0,1,33,7,30, -1,51,50,54,53,51,23,22,6,35,34,2,61,1,52,18,51,50,22,15,1,35,52,38,35,34,6,29, -2,33,2,215,254,108,2,21,125,106,91,136,178,3,4,248,164,228,248,249,227,181, -231,4,2,179,129,98,145,133,1,176,1,100,6,97,120,121,88,6,140,217,1,54,231,42, -229,1,55,224,163,6,99,139,225,160,42,10,0,2,0,65,0,0,6,158,4,58,0,22,0,31,0,0, -1,17,33,50,22,21,20,6,35,33,17,33,17,16,2,43,1,63,1,50,54,53,17,1,17,33,50,54, -53,52,38,35,3,252,1,13,191,214,215,190,254,46,254,196,178,207,57,4,41,107,92, -2,199,1,13,105,102,101,106,4,58,254,101,185,147,148,191,3,158,254,206,254,194, -254,210,158,1,217,244,1,206,253,203,254,147,112,77,73,103,0,0,0,0,2,0,143,0,0, -6,157,4,58,0,18,0,27,0,0,1,33,17,51,17,33,50,22,21,20,6,35,33,17,33,17,35,17, -51,1,17,33,50,54,53,52,38,35,1,84,1,226,197,1,13,192,213,215,190,254,46,254, -30,197,197,2,167,1,13,105,102,101,106,2,162,1,152,254,100,184,147,148,191,2,9, -253,247,4,58,253,203,254,147,112,77,73,103,0,0,0,0,1,255,242,0,0,4,0,6,24,0, -27,0,0,1,35,21,62,1,51,50,22,21,17,35,17,52,38,35,34,6,7,17,35,17,35,53,51,17, -51,17,51,2,64,236,56,163,99,173,193,197,115,114,88,130,40,197,157,157,197,236, -4,154,241,78,87,208,216,253,90,2,168,134,128,69,62,252,213,4,154,124,1,2,254, -254,0,0,0,0,1,0,143,255,29,3,252,4,58,0,11,0,0,1,17,33,17,51,17,33,21,35,53, -33,17,1,84,1,227,197,254,175,197,254,169,4,58,252,96,3,160,251,198,227,227,4, -58,0,1,0,108,255,235,6,98,5,176,0,42,0,0,1,6,2,7,20,18,55,51,22,54,53,17,51, -17,20,22,55,51,22,18,53,38,2,39,51,22,18,21,16,2,35,34,38,39,14,1,35,34,2,17, -52,18,55,1,213,65,95,4,112,116,6,101,132,198,131,101,6,115,114,5,95,64,206,61, -94,205,214,125,176,43,44,176,124,215,204,93,62,5,176,131,254,51,162,234,254, -179,5,6,255,221,2,22,253,234,221,255,6,5,1,76,235,162,1,205,131,105,254,54, -191,254,213,254,88,173,155,155,173,1,168,1,43,192,1,201,105,0,0,1,0,127,255, -235,5,210,4,58,0,40,0,0,1,6,2,7,20,22,51,50,54,53,17,51,17,20,22,51,50,54,53, -38,2,39,51,22,18,21,20,2,35,34,38,39,14,1,35,34,2,53,52,18,55,1,212,65,76,3, -83,89,98,116,198,115,99,87,84,4,76,65,207,60,75,174,184,119,165,40,41,164,118, -185,173,74,61,4,58,136,254,254,126,190,239,162,175,1,44,254,212,175,162,238, -191,127,1,3,134,106,254,252,154,254,254,183,121,116,117,120,1,73,254,154,1,4, -106,0,0,3,0,113,255,235,5,2,5,197,0,13,0,30,0,47,0,0,1,16,0,33,34,0,25,1,16,0, -51,32,0,17,5,50,54,55,53,52,2,35,34,2,29,1,62,1,51,50,4,5,14,1,35,34,38,35,34, -6,7,21,20,18,51,50,54,53,5,2,254,181,254,248,255,254,193,1,63,255,1,8,1,75, -254,138,55,95,27,216,182,172,205,36,87,49,87,1,2,1,2,37,90,50,109,237,80,55, -92,25,205,172,183,215,2,86,254,245,254,160,1,96,1,11,1,3,1,10,1,98,254,159, -254,245,140,41,33,68,200,1,0,255,0,200,68,28,32,134,99,27,29,133,47,35,15,202, -255,0,255,203,0,0,0,3,0,97,255,235,4,42,4,78,0,13,0,29,0,45,0,0,19,52,0,51,50, -0,29,1,20,0,35,34,0,53,37,50,54,55,46,1,35,34,6,7,23,62,1,51,50,22,5,34,6,7, -30,1,51,50,54,55,39,14,1,35,34,38,97,1,4,223,225,1,5,254,252,224,224,254,251, -2,128,43,74,9,19,143,121,134,142,2,4,20,70,41,62,182,254,249,38,67,14,16,143, -124,131,142,4,3,21,75,43,76,167,2,39,240,1,55,254,202,241,22,242,254,204,1,53, -241,27,50,38,135,168,201,149,5,23,31,90,44,40,30,139,170,193,148,4,26,31,91,0, -1,0,212,4,164,3,163,5,252,0,7,0,0,1,21,39,55,33,39,23,21,1,131,175,1,2,32,1, -175,5,34,126,1,235,108,1,217,0,0,0,1,0,251,5,23,3,243,6,21,0,17,0,0,1,50,36, -51,50,22,29,1,35,53,52,38,35,34,4,43,1,53,1,39,113,1,36,73,113,125,134,59,49, -43,254,213,130,46,5,153,124,110,108,36,18,52,54,124,130,0,0,1,1,231,5,11,2, -241,6,116,0,5,0,0,1,53,51,7,23,7,1,231,188,1,79,81,5,220,152,170,125,66,0,1,1, -231,5,11,2,241,6,116,0,5,0,0,1,39,55,39,51,21,2,56,81,79,1,188,5,11,66,125, -170,152,0,1,0,105,255,235,4,45,5,176,0,28,0,0,1,39,33,53,33,23,1,30,1,21,20,4, -35,34,36,63,1,51,20,22,51,50,54,53,52,38,43,1,53,3,13,2,253,137,3,101,1,254, -103,219,241,254,238,221,192,254,235,5,2,189,152,121,139,159,161,160,146,5,16, -5,155,120,254,21,13,227,199,200,227,214,205,6,114,157,149,120,153,143,154,0,0, -0,0,1,0,105,254,117,4,45,4,58,0,28,0,0,1,39,33,53,33,23,1,30,1,21,20,4,35,34, -36,63,1,51,20,22,51,50,54,53,52,38,43,1,53,2,248,3,253,159,3,101,1,254,116, -214,233,254,237,220,191,254,234,5,2,189,152,121,139,159,162,160,147,3,153,5, -156,120,254,19,16,226,196,198,228,215,203,6,112,157,149,118,154,142,154,0,0,0, -255,255,0,179,2,136,4,240,3,35,0,70,1,33,217,0,83,51,64,0,255,255,0,187,2,136, -5,243,3,35,0,70,1,33,175,0,102,102,64,0,0,1,0,145,3,149,1,87,5,176,0,5,0,0,19, -55,51,3,17,35,145,101,97,1,197,4,181,251,255,0,254,229,0,1,0,160,3,149,1,102, -5,176,0,5,0,0,1,7,35,55,17,51,1,102,101,97,1,197,4,144,251,248,1,35,0,1,0,168, -255,1,1,110,0,249,0,5,0,0,37,3,35,19,53,51,1,110,101,97,1,197,26,254,231,1,7, -241,255,255,0,85,3,149,1,27,5,176,0,71,1,8,1,187,0,0,192,1,64,0,0,0,255,255,0, -145,3,149,2,170,5,176,0,38,1,7,0,0,0,7,1,7,1,83,0,0,255,255,0,160,3,149,2,193, -5,176,0,38,1,8,0,0,0,7,1,8,1,91,0,0,0,2,0,176,255,17,2,170,1,24,0,5,0,11,0,0, -37,7,35,55,17,51,1,7,35,55,17,51,1,118,101,97,1,197,1,52,100,98,1,197,10,249, -240,1,23,254,242,249,247,1,16,0,0,1,0,70,0,0,4,36,5,176,0,11,0,0,1,33,17,35, -17,33,53,33,17,51,17,33,4,36,254,113,197,254,118,1,138,197,1,143,3,158,252,98, -3,158,156,1,118,254,138,0,0,0,0,1,0,87,254,96,4,52,5,176,0,19,0,0,41,1,17,35, -17,33,53,33,17,33,53,33,17,51,17,33,21,33,17,33,4,52,254,113,197,254,119,1, -137,254,119,1,137,197,1,143,254,113,1,143,254,96,1,160,154,3,4,156,1,118,254, -138,156,252,252,0,0,0,0,1,0,137,2,23,2,39,3,225,0,13,0,0,19,52,54,51,50,22,29, -1,20,6,35,34,38,53,137,112,94,95,113,112,95,95,112,3,25,88,112,112,88,60,89, -109,110,88,255,255,0,161,0,0,4,197,0,202,0,38,0,14,0,0,0,39,0,14,1,187,0,0,0, -7,0,14,3,95,0,0,0,6,0,64,255,235,7,85,5,197,0,25,0,39,0,53,0,67,0,81,0,85,0,0, -1,52,54,51,50,22,23,62,1,51,50,22,29,1,20,6,35,34,38,39,14,1,35,34,38,53,1,52, -54,51,50,22,29,1,20,6,35,34,38,53,1,20,22,51,50,54,61,1,52,38,35,34,6,21,5,20, -22,51,50,54,61,1,52,38,35,34,6,21,1,20,22,51,50,54,61,1,52,38,35,34,6,21,19, -39,1,23,3,51,164,136,74,117,37,37,117,74,137,165,164,136,75,118,37,37,116,73, -138,164,253,13,164,136,138,164,164,136,137,165,3,133,81,75,74,80,82,74,74,80, -1,200,81,75,73,80,81,74,74,80,251,69,81,75,73,81,82,74,74,80,248,109,2,199, -109,1,101,126,174,63,54,54,63,173,127,78,128,172,61,55,55,61,172,128,3,129, -127,174,173,128,77,127,172,172,127,252,204,75,103,103,75,78,74,104,104,74,78, -75,103,103,75,78,74,104,104,74,2,230,74,103,102,75,77,74,105,105,74,251,214, -67,4,114,67,0,0,0,0,1,0,88,0,72,1,218,3,160,0,10,0,0,19,7,31,1,21,7,1,53,1,23, -21,245,61,61,229,5,254,131,1,125,5,2,21,34,36,204,184,3,1,97,150,1,97,3,184,0, -0,0,0,1,0,144,0,71,2,19,3,159,0,10,0,0,19,53,55,1,21,1,39,53,63,1,39,144,5,1, -126,254,130,5,230,61,61,2,228,185,2,254,159,150,254,159,2,185,208,34,36,0,0,0, -0,1,0,59,0,110,3,111,5,35,0,3,0,0,55,39,1,23,168,109,2,199,109,110,67,4,114, -67,0,2,0,71,2,48,3,83,5,197,0,10,0,15,0,0,1,51,21,35,21,35,53,33,39,1,51,1,33, -17,39,7,2,190,149,149,172,254,57,4,1,198,177,254,71,1,13,6,13,3,105,129,184, -184,96,2,125,253,164,1,121,1,26,0,0,1,0,70,0,0,4,87,5,197,0,40,0,0,1,14,1,7, -33,7,33,53,51,62,1,55,35,53,51,39,35,53,51,39,52,54,51,50,22,15,1,35,52,38,35, -34,6,21,23,33,21,33,23,33,21,1,179,2,30,27,2,223,1,252,48,10,45,47,4,170,165, -6,158,152,5,224,188,200,220,4,2,190,126,98,99,116,5,1,166,254,96,5,1,155,1, -185,83,150,54,154,154,12,173,102,155,143,155,146,204,233,209,172,6,118,114, -149,133,146,155,143,155,0,0,0,0,1,0,79,255,235,3,213,5,197,0,42,0,0,1,33,7,6, -22,51,50,54,55,23,14,1,35,34,0,53,35,53,51,53,35,53,51,53,52,0,51,50,22,23,7, -46,1,35,34,6,29,1,33,21,33,21,33,3,146,254,27,2,4,171,147,57,112,52,19,56,123, -61,231,254,227,146,146,146,146,1,27,231,59,117,66,19,54,113,56,146,171,1,236, -254,20,1,236,2,0,5,169,205,17,17,157,15,16,1,33,244,124,166,125,15,244,1,35, -16,15,159,16,19,206,172,17,125,166,0,0,2,0,103,3,151,4,96,5,176,0,15,0,23,0,0, -1,39,3,35,3,7,17,35,17,51,19,51,19,51,17,35,1,35,17,35,17,35,53,33,4,3,6,150, -51,156,6,93,116,161,6,162,110,93,253,228,145,94,145,1,128,4,238,2,254,167,1, -103,2,254,155,2,25,254,122,1,134,253,231,1,199,254,57,1,199,82,0,0,255,255,0, -107,255,245,6,82,5,178,0,39,1,101,0,12,2,134,0,39,1,21,1,6,0,0,0,7,1,108,3,75, -0,0,0,0,255,255,0,110,255,245,6,233,5,192,0,39,1,103,0,4,2,148,0,39,1,21,1, -191,0,0,0,7,1,108,3,226,0,0,0,0,255,255,0,111,255,245,7,25,5,175,0,39,1,105, -255,253,2,142,0,39,1,21,1,247,0,0,0,7,1,108,4,18,0,0,0,0,255,255,0,107,255, -245,6,114,5,175,0,39,1,107,0,12,2,142,0,39,1,21,1,54,0,0,0,7,1,108,3,107,0,0, -0,0,0,2,0,72,255,235,4,48,5,237,0,20,0,33,0,0,1,4,0,17,21,20,0,35,34,0,53,52, -18,51,50,22,23,55,46,1,39,19,50,54,61,1,46,1,35,34,6,21,20,22,1,231,1,7,1,66, -254,224,215,218,254,233,250,218,95,168,54,3,22,235,176,146,133,169,36,172,127, -136,135,164,5,237,63,254,108,254,217,220,245,254,201,1,24,207,233,1,23,59,52, -5,193,236,52,251,60,228,174,129,67,92,201,156,132,201,0,0,0,1,0,168,255,45,4, -244,5,176,0,7,0,0,5,35,17,33,17,35,17,33,4,244,197,253,62,197,4,76,211,5,232, -250,24,6,131,0,0,0,0,1,0,70,254,243,4,174,5,176,0,14,0,0,9,1,23,33,21,33,53,9, -1,53,33,21,33,7,1,3,101,253,210,2,3,117,251,152,2,98,253,158,4,25,252,216,2,2, -48,2,36,253,111,5,155,146,2,201,2,207,147,155,5,253,103,0,0,0,0,1,0,168,2,136, -3,235,3,35,0,3,0,0,1,33,53,33,3,235,252,189,3,67,2,136,155,0,0,1,0,63,0,0,4, -173,5,176,0,11,0,0,1,23,51,55,1,51,1,35,3,35,53,33,2,42,18,6,19,1,143,201,253, -219,149,248,188,1,72,1,84,83,83,4,92,250,80,2,116,156,0,3,0,104,255,235,7,187, -4,78,0,25,0,39,0,53,0,0,1,20,2,35,34,38,39,14,1,35,34,2,61,1,52,18,51,50,22, -23,62,1,51,50,18,21,5,20,22,51,50,18,55,53,38,2,35,34,6,21,33,52,38,35,34,2,7, -21,22,18,51,50,54,53,7,187,247,208,165,238,80,80,239,163,209,246,245,208,164, -240,81,79,240,165,206,247,249,114,132,126,137,213,27,28,213,138,125,131,5,201, -133,123,138,212,30,29,212,137,125,133,1,220,221,254,236,215,156,155,216,1,20, -221,128,220,1,22,216,155,154,217,254,234,220,128,151,192,1,23,108,42,106,1,23, -195,148,148,195,254,235,108,42,110,254,235,193,150,0,1,255,188,254,75,2,147,6, -45,0,27,0,0,19,50,54,53,17,52,54,51,50,22,23,7,46,1,35,34,6,21,17,20,6,35,34, -38,39,55,30,1,43,59,69,182,162,33,69,42,24,20,44,25,87,91,172,153,31,51,29,14, -14,65,254,230,103,90,5,28,173,189,11,10,145,5,6,109,98,250,228,167,181,9,9, -150,5,8,0,1,0,152,0,167,3,218,4,227,0,19,0,0,1,51,21,33,7,33,21,33,7,39,55,35, -53,33,55,33,53,33,19,23,3,25,193,254,228,140,1,168,253,253,133,87,100,199,1, -34,140,254,82,2,9,147,87,3,219,164,252,164,240,60,180,164,252,164,1,8,60,0, -255,255,0,158,0,6,3,230,4,75,0,103,0,28,0,87,0,188,64,0,57,154,0,7,1,33,255, -251,253,126,0,0,255,255,0,154,0,4,3,242,4,76,0,103,0,30,0,18,0,207,64,0,57, -154,0,7,1,33,255,251,253,124,0,0,255,255,0,169,254,176,1,131,255,121,0,7,0, -155,0,9,249,201,0,0,0,1,0,93,4,23,1,148,5,179,0,15,0,0,19,39,62,1,53,52,38,35, -55,50,22,21,20,6,15,1,112,1,76,65,88,71,7,146,158,87,64,1,4,23,154,4,31,38,39, -38,108,103,86,70,73,9,71,0,0,0,0,2,0,125,4,228,4,113,6,152,0,8,0,12,0,0,1,51, -5,7,35,39,7,47,1,1,51,3,35,1,149,156,1,31,2,195,157,165,202,2,3,33,211,204, -147,5,224,235,6,137,148,9,5,1,166,254,252,0,0,0,0,2,255,85,4,228,3,71,6,152,0, -8,0,12,0,0,1,15,1,39,7,35,39,37,51,5,35,3,51,3,71,2,201,165,158,194,2,1,31, -155,254,132,147,203,210,4,242,5,9,148,137,6,235,76,1,4,0,2,0,110,4,228,4,49,6, -209,0,8,0,24,0,0,1,35,1,23,51,55,23,51,55,47,1,62,1,53,52,38,35,55,50,22,21, -20,6,15,1,2,64,198,254,244,2,169,196,196,170,2,25,1,66,55,75,62,6,127,137,75, -57,1,5,235,254,255,6,186,186,6,132,133,4,26,32,34,32,94,87,75,61,64,7,61,0,0, -0,2,0,110,4,228,3,77,6,252,0,8,0,28,0,0,1,7,35,39,7,35,39,1,51,55,20,6,35,34, -38,35,34,6,21,39,52,54,51,50,22,51,50,54,53,3,77,2,170,196,196,169,2,1,33,157, -182,97,66,53,113,38,31,51,80,96,66,42,123,39,30,54,4,234,6,176,176,6,1,1,250, -69,107,71,59,34,19,69,111,69,56,35,0,2,0,129,4,223,2,224,6,139,0,15,0,20,0,0, -1,23,22,6,35,34,38,63,1,51,20,22,51,50,54,53,39,51,23,7,35,2,216,2,6,164,139, -140,164,7,2,151,69,75,73,70,93,155,2,159,106,5,176,6,89,114,114,89,6,51,63,63, -51,219,5,192,0,2,0,129,4,224,2,202,7,42,0,15,0,32,0,0,1,20,6,35,34,38,53,35,7, -6,22,51,50,54,47,1,37,39,62,1,39,53,54,38,35,55,50,22,21,20,6,15,1,2,49,68,71, -72,68,144,2,7,158,135,134,158,6,2,254,179,1,73,60,5,5,81,70,7,142,152,83,63,1, -5,176,51,63,64,50,6,89,113,113,89,6,56,126,3,23,26,6,28,27,83,78,66,53,55,7, -63,0,0,0,2,0,129,4,219,2,211,6,212,0,15,0,35,0,0,1,23,22,6,35,34,38,63,1,51, -20,22,51,50,54,53,19,20,6,35,34,38,35,34,6,21,39,52,54,51,50,22,51,50,54,53,2, -203,2,6,160,136,137,161,7,2,148,67,74,71,69,148,95,71,58,124,41,34,45,88,94, -73,45,135,43,32,48,5,176,6,91,116,116,91,6,52,65,65,52,1,12,75,107,76,52,37, -21,74,111,76,51,38,0,1,0,96,254,210,1,37,0,157,0,3,0,0,1,35,17,51,1,37,197, -197,254,210,1,203,0,0,0,1,0,161,254,75,2,87,0,178,0,15,0,0,37,17,20,22,51,50, -54,55,23,14,1,35,34,38,53,17,1,92,75,63,18,66,14,15,29,53,31,154,171,178,254, -245,87,95,7,5,160,9,9,181,167,1,11,0,0,0,0,1,255,190,254,75,1,114,0,154,0,15, -0,0,37,21,20,6,35,34,38,39,55,30,1,51,50,54,61,1,1,114,172,153,31,51,29,14,14, -64,19,60,68,154,243,167,181,9,9,160,5,7,94,88,243,0,0,1,255,160,255,206,2,202, -3,112,0,15,0,0,3,33,50,0,21,6,2,7,39,62,1,53,46,1,35,33,96,1,23,235,1,40,2, -195,190,51,128,112,1,182,150,254,233,3,112,255,0,220,138,254,230,34,148,34, -157,115,147,164,0,0,0,1,0,113,0,0,2,85,5,197,0,5,0,0,33,35,17,5,53,37,2,85, -197,254,225,1,228,4,250,3,162,44,0,1,0,83,0,0,3,231,5,197,0,26,0,0,41,1,53,1, -62,1,53,52,38,35,34,6,21,35,39,38,54,51,50,22,21,20,6,7,1,23,33,3,231,252,143, -1,175,125,92,122,112,120,133,189,2,5,245,204,198,233,159,159,254,224,2,2,128, -154,1,245,138,169,82,121,157,159,117,6,178,247,227,208,125,233,179,254,166,5, -0,1,0,105,255,235,4,45,5,197,0,42,0,0,1,50,54,53,52,38,35,34,6,21,35,39,38,36, -51,50,22,21,20,6,7,30,1,21,20,4,35,34,36,63,1,51,20,22,51,50,54,53,52,38,43,1, -53,2,78,132,128,140,136,107,146,189,2,5,1,4,189,219,253,115,100,115,123,254, -238,221,192,254,235,5,2,189,152,121,139,159,143,139,182,3,51,132,115,112,144, -142,105,6,176,220,215,200,101,166,48,42,174,125,200,227,214,205,6,114,157,149, -120,133,129,155,0,2,0,73,0,0,4,111,5,176,0,10,0,15,0,0,1,51,21,35,17,35,17,33, -53,1,51,1,33,17,39,7,3,156,211,211,197,253,114,2,131,208,253,141,1,174,6,18,1, -212,154,254,198,1,58,111,4,7,252,36,2,208,1,45,0,1,0,132,255,235,4,61,5,176,0, -31,0,0,27,1,33,21,33,3,62,1,55,54,22,21,20,2,35,34,36,63,2,20,22,51,50,54,53, -52,38,35,34,6,7,176,84,3,2,253,164,47,49,125,80,213,239,246,234,202,254,241,5, -2,180,162,124,134,149,150,133,125,113,28,2,125,3,51,175,254,84,34,45,2,2,249, -223,219,254,246,202,197,6,18,120,149,176,153,138,163,70,72,0,0,0,2,0,142,255, -235,4,86,5,197,0,26,0,39,0,0,1,50,22,23,7,46,1,35,34,6,29,1,62,1,51,50,22,21, -20,0,35,34,0,53,17,52,0,19,34,6,7,21,20,22,51,50,54,53,52,38,2,165,86,168,54, -42,65,118,83,148,190,58,164,97,211,241,255,0,218,211,254,229,1,56,165,103,141, -36,171,126,134,143,143,5,197,33,26,151,26,29,224,170,148,67,77,244,220,223, -254,254,1,20,239,1,176,239,1,56,253,48,68,62,133,168,193,178,149,151,146,0,0, -0,0,1,0,37,0,0,3,213,5,176,0,12,0,0,1,10,1,17,21,35,53,16,0,55,33,53,33,3,213, -222,196,197,1,13,153,253,17,3,176,5,21,254,244,254,77,254,145,231,231,1,98,2, -41,163,155,0,0,3,0,130,255,235,4,55,5,197,0,23,0,35,0,47,0,0,1,20,6,7,30,1,21, -20,4,35,34,36,53,52,54,55,46,1,53,52,54,51,50,22,3,52,38,35,34,6,21,20,22,51, -50,54,3,52,38,35,34,6,21,20,22,51,50,54,4,14,129,109,126,153,254,250,201,214, -254,240,156,133,115,133,247,196,185,239,156,155,113,124,163,163,126,114,152, -41,131,96,109,137,140,108,96,129,4,52,114,168,40,41,181,124,202,227,226,203, -124,181,41,39,169,114,192,209,209,252,160,119,154,154,119,122,149,149,3,31, -105,136,131,110,111,138,138,0,0,2,0,92,255,235,4,32,5,197,0,26,0,39,0,0,37,50, -54,61,1,14,1,35,34,38,53,52,0,51,50,0,21,17,20,0,35,34,38,39,55,30,1,19,50,54, -55,53,52,38,35,34,6,21,20,22,2,28,142,176,53,163,95,223,232,1,9,203,220,1,20, -254,224,228,82,172,74,31,69,138,97,114,162,35,159,133,125,152,125,133,186,169, -169,73,76,231,239,223,1,20,254,236,248,254,49,242,254,243,32,31,150,32,27,2, -18,92,69,138,170,190,187,157,160,155,0,2,0,123,255,235,4,47,5,197,0,13,0,27,0, -0,1,20,2,35,34,2,53,17,52,18,51,50,0,21,39,52,38,35,34,6,21,17,20,22,51,50,54, -53,4,47,254,219,220,255,254,219,219,1,0,198,142,135,135,141,143,135,135,140,2, -2,248,254,225,1,31,248,1,172,246,1,33,254,223,246,2,176,202,203,175,254,82, -177,204,203,178,0,0,2,0,39,0,0,4,138,4,141,0,7,0,11,0,0,1,33,3,35,1,51,1,35,1, -33,3,35,3,87,254,3,103,204,1,213,186,1,212,203,253,214,1,135,193,6,1,12,254, -244,4,141,251,115,1,166,1,242,0,0,0,2,0,109,4,165,2,237,6,168,0,15,0,20,0,0,1, -23,22,6,35,34,38,63,1,51,20,22,51,50,54,53,39,35,39,55,51,2,230,2,5,174,146, -147,173,6,2,149,79,84,83,79,76,157,208,2,220,5,176,6,115,146,146,115,6,65,82, -82,65,43,199,6,0,3,0,153,0,0,4,13,4,141,0,14,0,24,0,33,0,0,51,17,33,50,22,21, -20,6,7,30,1,21,20,6,35,1,17,33,50,54,53,52,38,39,35,37,51,50,54,53,52,38,43,1, -153,1,141,213,237,94,87,102,116,221,197,254,243,1,13,109,111,106,103,11,254, -243,200,124,129,123,130,200,4,141,159,159,84,130,33,25,150,96,162,167,2,9,254, -143,94,88,84,100,3,141,89,85,86,70,0,0,0,1,0,112,255,239,4,38,4,157,0,29,0,0, -1,23,22,4,35,34,0,61,1,52,0,51,50,22,15,1,35,52,38,35,34,6,29,1,20,22,51,50, -54,53,4,30,2,5,254,253,206,207,254,235,1,21,207,212,254,5,2,189,142,128,123, -164,164,123,127,142,1,125,6,189,203,1,12,210,243,209,1,12,203,187,6,121,122, -186,137,244,139,187,122,124,0,0,0,2,0,153,0,0,4,49,4,141,0,9,0,19,0,0,51,17, -33,50,0,29,1,20,0,35,3,17,51,50,54,61,1,52,38,35,153,1,165,211,1,32,254,224, -211,224,224,126,176,176,126,4,141,254,243,209,210,210,254,245,3,244,252,164, -186,139,211,137,187,0,0,0,0,1,0,153,0,0,3,200,4,141,0,11,0,0,1,33,17,33,21,33, -17,33,21,33,17,33,3,113,253,237,2,106,252,209,3,47,253,150,2,19,2,18,254,134, -152,4,141,153,254,184,0,0,0,1,0,153,0,0,3,202,4,141,0,9,0,0,1,33,17,35,17,33, -21,33,17,33,3,115,253,235,197,3,49,253,148,2,21,1,245,254,11,4,141,153,254, -155,0,1,0,112,255,239,4,75,4,157,0,32,0,0,37,14,1,35,34,0,61,1,52,0,51,50,22, -15,1,35,52,38,35,34,6,29,1,20,22,51,50,54,55,53,33,53,33,4,75,45,242,181,231, -254,224,1,34,225,222,243,4,2,188,145,126,140,178,176,146,105,137,31,254,254,1, -197,157,65,109,1,9,213,243,211,1,10,201,157,6,101,110,184,139,244,142,184,42, -27,250,154,0,1,0,153,0,0,4,90,4,141,0,11,0,0,33,35,17,33,17,35,17,51,17,33,17, -51,4,90,198,253,202,197,197,2,54,198,1,235,254,21,4,141,253,247,2,9,0,0,0,1,0, -153,0,0,1,93,4,141,0,3,0,0,33,35,17,51,1,93,196,196,4,141,0,1,0,64,255,239,3, -119,4,141,0,16,0,0,1,51,17,20,6,35,34,38,63,1,51,20,22,51,50,54,53,2,179,196, -227,175,195,226,6,2,188,118,107,88,118,4,141,252,213,170,201,178,170,6,101, -101,121,98,0,0,0,1,0,153,0,0,4,65,4,141,0,14,0,0,1,35,17,35,17,51,17,51,1,51, -23,9,1,7,35,1,193,99,197,197,84,1,132,231,3,254,57,1,232,3,241,1,244,254,12,4, -141,254,4,1,252,5,253,214,253,167,5,0,0,0,0,1,0,153,0,0,3,107,4,141,0,5,0,0, -37,33,21,33,17,51,1,94,2,13,253,46,197,152,152,4,141,0,0,1,0,153,0,0,5,85,4, -141,0,15,0,0,1,51,1,51,17,35,17,39,1,35,1,7,17,35,17,51,2,247,6,1,98,246,197, -6,254,180,136,254,174,6,197,254,1,3,3,138,251,115,3,41,2,252,213,3,61,2,252, -197,4,141,0,1,0,153,0,0,4,118,4,141,0,11,0,0,33,35,1,7,17,35,17,51,1,55,17,51, -4,118,196,253,178,6,197,197,2,78,6,196,3,91,2,252,167,4,141,252,165,2,3,89,0, -0,0,2,0,112,255,239,4,91,4,157,0,13,0,27,0,0,1,20,0,35,34,0,61,1,52,0,51,50,0, -21,39,52,38,35,34,6,29,1,20,22,51,50,54,53,4,91,254,235,224,223,254,233,1,21, -223,224,1,23,197,164,142,141,162,163,142,142,162,1,205,214,254,248,1,9,213, -243,212,1,9,254,247,212,1,151,172,172,151,244,154,172,172,154,0,2,0,153,0,0,4, -31,4,141,0,10,0,19,0,0,1,17,35,17,33,50,22,21,20,6,35,37,33,50,54,53,52,38,35, -33,1,94,197,1,210,203,233,233,203,254,243,1,13,117,121,121,117,254,243,1,164, -254,92,4,141,208,165,166,206,154,126,90,92,130,0,0,0,2,0,112,255,138,4,154,4, -157,0,19,0,33,0,0,1,20,6,7,23,7,39,14,1,35,34,0,61,1,52,0,51,50,0,21,39,52,38, -35,34,6,29,1,20,22,51,50,54,53,4,91,52,48,163,135,167,56,133,73,223,254,233,1, -21,223,224,1,23,197,164,142,141,162,163,142,142,162,1,205,89,155,60,159,116, -161,30,30,1,9,213,243,212,1,9,254,247,212,1,151,172,172,151,244,154,172,172, -154,0,2,0,153,0,0,4,44,4,141,0,26,0,35,0,0,1,17,35,17,33,50,22,21,20,6,7,30,1, -29,1,20,22,23,21,35,46,1,61,1,52,38,35,37,33,50,54,53,52,38,35,33,1,94,197,1, -205,205,225,99,96,104,91,11,13,203,12,6,104,98,254,217,1,8,120,112,113,119, -254,248,1,223,254,33,4,141,180,162,89,126,39,30,144,105,118,45,86,22,19,23,98, -52,116,90,100,154,94,88,92,105,0,0,0,1,0,93,255,239,4,17,4,157,0,39,0,0,1,52, -38,39,46,1,53,52,54,51,50,22,15,1,35,52,38,35,34,6,21,20,22,23,30,1,21,20,6, -35,34,36,63,1,51,20,22,51,50,54,3,76,124,162,223,203,243,206,210,235,5,2,187, -132,119,125,127,115,178,215,204,254,218,202,254,238,6,1,188,163,118,131,144,1, -48,71,88,40,58,149,150,147,174,186,168,6,92,115,93,74,73,81,43,58,156,145,154, -168,170,184,6,108,100,94,0,0,0,1,0,71,0,0,3,209,4,141,0,7,0,0,1,33,17,35,17, -33,53,33,3,209,254,155,197,254,160,3,138,3,244,252,12,3,244,153,0,0,0,1,0,137, -255,239,4,116,4,141,0,17,0,0,1,17,20,4,35,34,36,53,17,51,17,20,22,51,50,54,53, -17,4,116,254,233,223,221,254,232,196,169,136,137,169,4,141,253,1,195,220,220, -195,2,255,253,1,123,140,139,124,2,255,0,0,1,0,39,0,0,4,131,4,141,0,9,0,0,1,23, -51,55,1,51,1,35,1,51,2,59,23,6,23,1,65,211,254,46,185,254,47,211,1,41,82,80,3, -102,251,115,4,141,0,1,0,63,0,0,5,192,4,141,0,17,0,0,1,21,55,19,51,19,21,55,19, -51,1,35,3,35,3,35,1,51,1,199,1,221,183,221,1,179,211,254,218,182,225,6,227, -181,254,218,211,1,8,3,5,3,131,252,123,3,5,3,131,251,115,3,87,252,169,4,141,0, -0,1,0,55,0,0,4,66,4,141,0,11,0,0,9,1,51,9,1,35,9,1,35,9,1,51,2,58,1,22,233, -254,120,1,145,230,254,225,254,227,233,1,146,254,119,232,2,220,1,177,253,191, -253,180,1,186,254,70,2,76,2,65,0,0,0,1,0,30,0,0,4,53,4,141,0,8,0,0,9,1,51,1, -17,35,17,1,51,2,41,1,47,221,254,84,197,254,90,221,2,77,2,64,253,13,254,102,1, -163,2,234,0,0,0,1,0,78,0,0,3,216,4,141,0,9,0,0,37,33,21,33,53,1,33,53,33,21,1, -61,2,155,252,118,2,129,253,161,3,80,152,152,118,3,126,153,114,0,0,2,0,120,255, -239,3,250,4,157,0,13,0,27,0,0,1,20,6,35,34,38,53,17,52,54,51,50,22,21,39,52, -38,35,34,6,21,17,20,22,51,50,54,53,3,250,247,201,202,248,247,201,202,248,197, -136,117,115,136,137,116,116,135,1,155,197,231,232,196,1,87,195,232,232,195,1, -124,149,150,123,254,168,125,151,150,126,0,0,0,1,0,78,0,0,1,195,4,157,0,5,0,0, -33,35,17,7,53,37,1,195,197,176,1,117,3,222,2,160,33,0,0,1,0,89,0,0,3,115,4, -157,0,26,0,0,41,1,53,1,62,1,53,52,38,35,34,6,21,35,39,38,54,51,50,22,21,20,6, -15,1,23,33,3,115,252,243,1,150,102,69,92,87,101,114,188,2,6,224,187,175,201, -117,158,248,3,2,15,152,1,150,97,114,62,84,113,115,83,6,143,202,184,168,109, -153,160,249,6,0,0,0,1,0,90,255,239,3,163,4,157,0,42,0,0,1,50,54,53,52,38,35, -34,6,21,35,39,38,54,51,50,22,21,20,6,7,30,1,21,20,6,35,34,38,63,1,51,20,22,51, -50,54,53,52,38,43,1,53,2,0,104,99,110,106,84,114,187,2,6,226,167,192,221,96, -84,96,103,240,192,168,241,5,2,186,121,95,108,126,111,110,168,2,157,95,84,76, -104,96,71,6,140,174,172,160,80,133,38,35,138,99,161,182,171,162,6,77,110,109, -82,98,95,150,0,0,0,0,2,0,71,0,0,4,21,4,141,0,10,0,14,0,0,1,51,21,35,21,35,53, -33,39,1,51,3,17,39,1,3,82,195,195,197,253,190,4,2,63,204,197,6,254,153,1,133, -154,235,235,122,3,40,252,248,1,251,2,254,3,0,0,0,0,1,0,90,255,239,3,168,4,141, -0,31,0,0,27,1,33,21,33,3,62,1,55,54,22,21,20,6,35,34,38,63,2,20,22,51,50,54, -53,52,38,35,34,6,7,135,71,2,166,254,5,33,37,114,56,181,204,210,219,178,239,5, -1,189,123,99,118,114,111,101,102,99,24,1,248,2,149,164,254,202,25,37,2,3,202, -185,178,210,161,157,6,14,83,103,124,110,107,125,57,53,0,2,0,120,255,239,3,215, -4,157,0,26,0,39,0,0,1,50,22,23,7,46,1,35,34,6,29,1,62,1,51,50,22,21,20,6,35, -34,38,53,17,52,36,19,34,6,7,21,20,22,51,50,54,53,52,38,2,79,66,147,67,33,58, -114,73,121,155,50,143,88,185,200,239,191,186,247,1,17,161,88,122,27,134,102, -105,128,114,4,157,28,23,148,24,22,163,125,106,52,58,198,179,171,213,248,196,1, -55,195,248,253,177,64,54,45,125,167,134,98,104,119,0,1,0,71,0,0,3,103,4,141,0, -12,0,0,1,6,2,17,21,35,53,16,18,55,33,53,33,3,103,189,163,197,231,142,253,144, -3,32,3,244,232,254,192,254,237,185,185,1,12,1,150,153,153,0,0,0,0,3,0,88,255, -239,3,201,4,157,0,23,0,35,0,47,0,0,1,20,6,7,30,1,21,20,6,35,34,38,53,52,54,55, -46,1,53,52,54,51,50,22,3,52,38,35,34,6,21,20,22,51,50,54,3,52,38,35,34,6,21, -20,22,51,50,54,3,166,102,86,102,121,247,185,194,255,123,106,91,104,233,180, -172,227,163,139,97,105,145,145,107,98,136,35,119,82,93,123,125,93,83,116,3,92, -87,132,37,39,144,94,162,182,182,162,94,145,38,37,132,87,153,168,168,253,86,84, -111,111,84,87,109,109,2,100,74,98,94,78,77,99,99,0,0,0,0,2,0,71,255,239,3,160, -4,157,0,26,0,39,0,0,37,50,54,61,1,14,1,35,34,38,53,52,54,51,50,22,21,17,20,4, -35,34,38,39,55,30,1,19,50,54,55,53,52,38,35,34,6,21,20,22,1,222,108,145,45, -127,72,195,221,240,190,185,242,255,0,194,68,148,67,31,60,117,91,88,124,25,133, -99,102,128,116,135,148,110,117,50,52,207,175,166,225,249,195,254,169,181,230, -26,24,149,26,21,1,163,74,54,55,124,167,146,92,102,134,0,0,2,0,120,255,245,3, -30,3,44,0,13,0,27,0,0,1,20,6,35,34,38,61,1,52,54,51,50,22,21,39,52,38,35,34,6, -29,1,20,22,51,50,54,53,3,30,187,151,153,187,186,152,152,188,173,89,78,78,88, -89,79,77,88,1,27,136,158,158,136,235,134,160,160,134,1,76,86,86,76,236,78,86, -86,78,0,1,0,95,0,0,1,140,3,44,0,5,0,0,33,35,17,35,53,37,1,140,174,127,1,45,2, -143,134,23,0,0,0,1,0,113,0,0,2,202,3,44,0,26,0,0,41,1,53,1,62,1,53,52,38,35, -34,6,21,35,39,38,54,51,50,22,21,20,6,15,1,23,33,2,202,253,176,1,46,69,44,57, -58,67,73,161,2,6,168,141,135,152,89,116,153,2,1,105,130,1,6,60,75,42,50,62,64, -50,6,99,140,128,116,80,112,105,135,6,0,0,0,1,0,106,255,245,2,228,3,44,0,42,0, -0,1,50,54,53,52,38,35,34,6,21,35,39,38,54,51,50,22,21,20,6,7,30,1,21,20,6,35, -34,38,63,1,51,20,22,51,50,54,53,52,38,43,1,53,1,168,67,65,73,69,56,69,162,2,6, -169,126,145,168,71,62,70,76,180,146,127,181,6,1,163,75,63,72,84,73,73,132,1, -215,57,52,43,58,48,40,6,94,119,119,110,55,91,26,23,96,68,111,124,116,111,6,46, -57,59,48,62,57,126,0,0,0,0,2,0,87,0,0,3,40,3,33,0,10,0,15,0,0,1,51,21,35,21, -35,53,33,39,1,51,1,51,17,39,7,2,170,126,126,170,254,95,8,1,166,173,254,99,243, -6,13,1,26,130,152,152,102,2,35,253,249,1,54,1,22,0,0,0,1,0,114,255,245,2,246, -3,33,0,31,0,0,27,1,33,21,33,7,62,1,55,54,22,21,20,6,35,34,38,63,2,20,22,51,50, -54,53,52,38,35,34,6,7,146,52,2,4,254,149,26,30,79,42,132,150,159,166,137,182, -6,1,162,82,68,78,76,77,67,65,67,15,1,90,1,199,133,185,17,25,1,2,145,128,122, -144,110,106,6,10,48,54,69,66,66,81,34,30,0,0,2,0,120,255,245,3,4,3,44,0,26,0, -39,0,0,1,50,22,23,7,46,1,35,34,6,29,1,62,1,51,50,22,21,20,6,35,34,38,61,1,52, -54,19,34,6,7,21,20,22,51,50,54,53,52,38,1,222,53,108,43,30,39,82,51,83,105,36, -101,63,132,148,182,144,141,185,205,128,64,83,14,86,68,71,84,74,3,44,19,16,127, -16,15,94,78,66,34,38,140,122,118,146,170,135,214,135,169,254,86,44,38,10,78, -97,75,59,63,70,0,0,0,1,0,95,0,0,2,172,3,33,0,12,0,0,1,14,1,29,1,35,53,52,18, -55,33,53,33,2,172,134,111,172,155,89,254,96,2,77,2,158,158,203,182,127,127, -181,1,23,83,131,0,0,0,3,0,112,255,245,3,7,3,44,0,23,0,35,0,47,0,0,1,20,6,7,30, -1,21,20,6,35,34,38,53,52,54,55,46,1,53,52,54,51,50,22,3,52,38,35,34,6,21,20, -22,51,50,54,3,52,38,35,34,6,21,20,22,51,50,54,2,239,73,62,73,86,185,140,146, -192,89,76,66,74,177,135,130,172,146,92,64,70,96,95,72,65,90,26,75,55,61,79,81, -60,53,76,2,80,59,91,27,28,99,63,112,124,124,112,63,100,28,27,90,59,105,115, -115,254,47,51,67,66,52,52,61,61,1,147,45,53,52,46,46,57,57,0,0,0,0,2,0,104, -255,245,2,236,3,44,0,26,0,39,0,0,37,50,54,61,1,14,1,35,34,38,53,52,54,51,50, -22,29,1,20,6,35,34,38,39,55,30,1,19,50,54,55,53,52,38,35,34,6,21,20,22,1,151, -72,96,31,84,47,145,164,180,143,138,183,195,146,51,110,50,28,43,84,72,60,79,13, -88,66,66,80,75,119,84,67,73,33,34,145,122,114,155,172,134,235,125,157,18,16, -127,17,14,1,23,49,35,24,76,99,83,55,66,79,0,0,0,0,1,0,120,255,45,1,103,0,243, -0,5,0,0,37,3,35,19,53,51,1,103,132,107,42,197,46,254,255,1,10,188,0,1,0,22,0, -0,5,23,5,196,0,21,0,0,1,23,51,55,19,62,1,51,50,22,23,7,46,1,35,34,6,7,1,35,1, -51,2,89,32,6,33,224,47,156,95,33,51,25,22,6,21,13,52,70,26,254,139,168,253, -238,214,1,126,120,120,3,37,148,141,11,15,151,2,5,65,78,251,117,5,176,0,1,0,46, -0,0,4,14,4,77,0,21,0,0,1,23,51,55,19,62,1,51,50,22,23,7,46,1,35,34,6,7,1,35,1, -51,1,227,17,6,19,149,41,132,82,34,51,24,22,5,22,13,32,59,13,254,216,149,254, -131,202,1,63,76,76,2,23,127,120,10,15,151,3,5,52,42,252,185,4,58,0,1,0,118, -254,128,4,191,5,197,0,25,0,0,1,35,17,38,0,53,17,16,0,51,50,0,15,1,35,52,38,35, -34,2,21,17,20,18,59,1,3,23,196,215,254,250,1,55,247,247,1,36,4,2,189,180,164, -165,196,196,165,115,254,128,1,113,29,1,82,246,1,3,1,13,1,95,254,249,217,6,153, -178,254,246,197,254,251,199,254,246,0,0,0,1,0,98,254,128,3,225,4,78,0,25,0,0, -1,35,17,38,2,61,1,52,18,51,50,22,15,1,35,52,38,35,34,6,29,1,20,22,59,1,2,167, -197,181,203,255,220,182,238,4,2,178,137,99,138,140,139,139,106,254,128,1,115, -32,1,42,203,42,227,1,57,224,163,6,98,140,230,155,42,159,228,0,0,0,0,1,0,163, -255,104,4,209,5,176,0,23,0,0,1,22,4,21,6,2,7,39,62,1,53,46,1,35,33,17,35,17, -51,17,51,1,51,23,2,195,232,1,25,2,225,221,51,160,142,2,178,154,254,183,197, -197,128,2,8,222,3,3,43,5,250,232,144,254,217,37,150,34,170,122,165,159,253, -120,5,176,253,124,2,132,5,0,0,0,0,1,0,153,254,254,4,30,4,58,0,23,0,0,1,30,1, -21,6,2,7,39,62,1,53,46,1,43,1,17,35,17,51,17,51,1,51,23,2,137,184,215,2,194, -190,51,128,113,2,178,154,168,197,197,84,1,131,231,2,2,101,30,222,185,133,254, -245,34,150,32,145,107,144,139,254,53,4,58,254,55,1,201,5,0,0,1,0,163,255,201, -4,116,5,176,0,21,0,0,1,33,17,51,50,0,21,6,2,7,39,62,1,53,46,1,43,1,17,35,17, -33,4,32,253,72,249,235,1,40,2,195,190,51,128,112,1,182,150,249,197,3,125,5,21, -254,86,255,0,220,138,254,230,34,148,34,157,115,147,164,253,58,5,176,0,0,0,1,0, -143,254,255,3,196,4,58,0,21,0,0,1,33,21,51,50,0,21,6,2,7,39,62,1,53,46,1,43,1, -17,35,17,33,2,190,254,150,93,235,1,40,2,195,190,51,128,112,1,182,150,93,197,2, -47,3,158,253,255,0,220,138,254,230,34,148,35,156,115,147,164,254,4,4,58,0,0,0, -0,1,0,168,255,206,7,227,5,176,0,23,0,0,1,51,50,0,21,6,2,7,39,62,1,53,46,1,43, -1,17,35,17,33,17,35,17,33,4,247,217,235,1,40,2,195,190,51,128,112,1,182,150, -217,197,253,59,197,4,79,3,112,255,0,220,138,254,230,34,148,34,157,115,147,164, -253,53,5,21,250,235,5,176,0,0,1,0,143,255,2,6,184,4,58,0,23,0,0,1,51,50,0,21, -6,2,7,39,62,1,53,46,1,43,1,17,35,17,33,17,35,17,33,3,252,169,235,1,40,2,195, -190,51,128,112,1,182,150,169,197,254,29,197,3,109,2,164,255,0,220,138,254,230, -34,148,35,156,115,147,164,254,1,3,158,252,98,4,58,0,0,2,0,89,255,235,5,33,5, -197,0,22,0,31,0,0,1,32,0,17,21,16,0,35,32,0,17,53,33,55,54,2,35,34,6,7,39,62, -1,19,50,18,55,39,33,21,20,22,2,102,1,74,1,113,254,162,252,254,208,254,194,3, -252,2,4,249,252,108,153,74,49,50,191,240,170,210,17,3,252,205,199,5,197,254, -113,254,186,49,254,196,254,104,1,97,1,56,108,5,248,1,61,47,37,139,35,65,250, -192,1,13,210,5,31,207,246,0,255,255,0,94,255,236,3,223,4,78,0,15,0,69,4,64,4, -58,192,1,0,1,0,169,0,0,7,111,5,176,0,13,0,0,1,33,17,33,21,33,17,35,17,33,17, -35,17,51,1,110,2,195,3,62,253,135,197,253,61,197,197,3,30,2,146,155,250,235,2, -131,253,125,5,176,0,0,0,1,0,143,0,0,5,101,4,58,0,13,0,0,1,33,17,33,21,33,17, -35,17,33,17,35,17,51,1,84,1,226,2,47,254,150,197,254,30,197,197,2,102,1,212, -156,252,98,1,204,254,52,4,58,0,0,0,1,0,63,255,48,6,156,5,176,0,19,0,0,1,33,17, -33,17,51,17,51,17,35,53,33,17,33,53,33,53,51,21,33,3,239,254,122,2,197,197, -169,197,251,205,254,155,1,101,197,1,134,4,165,251,246,5,21,251,75,254,53,208, -4,165,154,113,113,0,1,0,73,255,69,5,29,4,58,0,19,0,0,1,33,17,33,17,51,17,51, -17,35,53,33,17,35,53,51,53,51,21,33,3,13,254,228,1,227,197,132,197,252,212, -227,227,197,1,28,3,46,253,108,3,160,252,96,254,171,187,3,46,154,114,114,0,0,0, -2,0,77,255,233,6,44,5,195,0,30,0,39,0,0,5,32,0,17,53,46,1,63,1,51,20,22,23,18, -0,51,32,0,17,21,33,7,6,18,51,50,54,55,23,14,1,3,34,2,7,23,33,53,52,38,4,71, -254,182,254,145,158,163,4,2,151,83,85,27,1,81,233,1,27,1,42,252,46,2,5,247, -253,107,154,75,48,50,192,238,171,210,15,3,3,9,181,23,1,141,1,71,6,20,196,154, -5,93,125,18,1,23,1,94,254,157,254,201,108,5,249,254,196,46,38,139,36,63,5,63, -254,242,209,5,31,206,247,0,0,0,0,2,255,223,255,235,4,94,4,78,0,29,0,38,0,0,5, -34,0,61,1,46,1,53,51,20,22,23,62,1,51,50,18,29,1,33,7,6,22,51,50,54,55,23,14, -1,3,34,6,7,23,33,53,52,38,2,224,242,254,239,125,129,157,51,54,30,255,170,217, -217,253,76,2,1,155,158,98,116,79,49,54,155,185,103,135,15,2,1,232,116,21,1,43, -242,6,26,177,138,73,101,23,193,239,254,242,224,104,5,162,204,41,42,139,39,59, -3,200,159,124,5,16,118,154,0,0,1,0,138,0,0,4,195,5,176,0,15,0,0,51,17,51,17, -33,50,22,21,17,35,17,52,38,35,33,17,138,197,1,139,240,249,198,139,152,254,117, -5,176,253,182,212,236,254,90,1,166,164,128,253,54,0,0,1,0,116,2,136,3,58,3,35, -0,3,0,0,1,33,53,33,3,58,253,58,2,198,2,136,155,0,0,1,0,74,0,0,6,185,5,176,0, -16,0,0,1,35,17,35,17,33,53,33,17,51,1,51,23,9,1,7,35,3,185,147,197,253,233,2, -220,128,2,8,222,2,253,196,2,103,3,239,2,146,253,110,5,21,155,253,124,2,132,5, -253,80,253,10,5,0,0,1,0,49,0,0,5,188,4,58,0,16,0,0,1,35,17,35,17,33,53,33,17, -51,1,51,23,9,1,7,35,3,63,101,197,254,28,2,169,84,1,131,231,2,254,63,1,227,2, -242,1,203,254,53,3,158,156,254,55,1,201,5,253,254,253,210,5,0,0,1,0,191,255, -236,6,146,5,198,0,40,0,0,1,33,7,30,1,51,50,54,53,51,23,22,0,35,34,0,3,35,17, -35,17,51,17,51,53,16,0,51,50,0,15,1,35,52,38,35,34,2,29,1,33,4,237,254,41,3,4, -194,158,164,180,189,2,4,254,216,243,240,254,203,9,196,198,198,196,1,55,247, -247,1,36,4,2,189,180,164,165,196,1,223,2,57,5,185,245,177,156,6,205,254,236,1, -74,1,3,253,199,5,176,253,35,135,1,13,1,95,254,249,217,6,153,178,254,246,197, -137,0,0,0,1,0,151,255,235,5,131,4,78,0,39,0,0,1,33,7,30,1,51,50,54,53,51,23, -22,6,35,34,2,39,35,17,35,17,51,17,51,54,18,51,50,22,15,1,35,52,38,35,34,6,7, -23,33,4,72,254,146,2,6,132,133,91,136,178,3,4,248,164,213,246,15,177,197,197, -177,15,246,213,181,231,4,2,179,129,98,133,133,5,2,1,110,1,205,5,139,184,121, -88,6,140,217,1,16,210,254,51,4,58,254,46,210,1,20,224,163,6,99,139,189,137,5, -0,0,0,2,0,43,0,0,4,227,5,176,0,11,0,15,0,0,1,35,17,35,17,35,3,35,1,51,1,35,1, -33,3,35,3,133,161,196,148,152,201,2,13,169,2,2,201,253,171,1,136,191,6,1,182, -254,74,1,182,254,74,5,176,250,80,2,90,2,51,0,0,2,0,13,0,0,4,41,4,58,0,11,0,17, -0,0,1,35,17,35,17,35,3,35,1,51,1,35,1,33,3,39,35,7,2,233,106,196,113,116,201, -1,184,169,1,187,201,254,39,1,36,126,18,6,18,1,38,254,218,1,38,254,218,4,58, -251,198,1,193,1,56,68,68,0,0,0,0,1,0,169,255,232,7,126,5,176,0,29,0,0,1,17,6, -22,51,62,1,55,54,38,39,55,30,1,7,2,0,35,6,38,39,17,33,17,35,17,51,17,33,17,4, -242,1,90,77,135,148,4,1,32,30,190,34,36,2,5,254,236,203,169,186,8,253,65,197, -197,2,191,5,176,251,169,95,117,1,210,185,97,202,103,1,124,187,92,254,246,254, -228,3,177,192,1,42,253,125,5,176,253,110,2,146,0,0,0,0,1,0,143,255,232,6,85,4, -58,0,29,0,0,1,33,17,35,17,51,17,33,17,51,17,6,22,51,62,1,55,54,38,39,51,30,1, -7,6,2,35,6,38,39,3,64,254,20,197,197,1,236,197,1,91,76,106,117,4,1,31,30,189, -34,36,2,4,242,178,169,186,8,1,204,254,52,4,58,254,43,1,213,253,31,95,117,1, -187,164,91,193,97,123,172,86,244,254,250,3,177,192,0,0,0,0,1,0,65,255,232,6, -65,4,58,0,33,0,0,1,33,17,16,2,43,1,63,1,50,54,53,17,33,17,6,22,51,62,1,55,54, -38,39,51,30,1,7,6,2,35,6,38,39,3,45,254,205,178,206,57,4,41,107,92,2,189,1,90, -76,107,116,4,1,32,30,191,33,36,2,4,243,177,168,186,8,3,158,254,208,254,195, -254,207,168,1,212,241,1,204,253,31,95,117,1,187,164,92,192,97,120,175,86,244, -254,250,3,177,192,0,0,0,0,1,0,69,255,232,7,117,5,176,0,33,0,0,1,33,17,16,2,43, -1,53,51,50,18,25,1,33,17,6,22,51,62,1,55,54,38,39,55,30,1,7,2,0,35,6,38,39,4, -36,254,40,216,250,53,41,149,133,3,97,1,91,77,135,147,4,1,31,30,190,33,36,2,4, -254,236,203,170,186,8,5,21,253,235,254,114,254,142,154,1,32,1,70,2,176,251, -169,95,117,1,210,185,97,203,102,1,122,189,92,254,246,254,228,3,177,192,0,1,0, -118,255,235,4,159,5,197,0,33,0,0,5,32,0,25,1,16,0,33,50,22,23,7,46,1,35,34,2, -21,17,20,18,51,62,1,55,54,38,39,51,30,1,7,6,4,2,185,255,0,254,189,1,67,1,0, -113,178,68,63,67,144,85,175,207,207,175,136,148,4,1,27,24,190,42,16,1,4,254, -235,21,1,94,1,12,1,6,1,11,1,95,45,43,135,33,35,254,246,195,254,248,198,254, -246,1,154,137,83,181,97,197,86,78,216,230,0,0,0,0,1,0,98,255,235,3,198,4,78,0, -33,0,0,37,62,1,55,52,38,39,51,30,1,21,14,1,35,34,0,61,1,52,18,51,50,22,23,7, -46,1,35,34,6,29,1,20,22,2,81,95,78,3,10,9,189,13,14,4,204,165,230,254,247,255, -219,94,142,47,46,47,122,68,137,140,149,133,1,83,84,58,122,56,68,115,53,158, -164,1,58,227,42,226,1,58,35,31,147,27,31,231,154,42,158,229,0,0,0,0,1,0,36, -255,232,5,77,5,176,0,25,0,0,1,33,53,33,21,33,17,6,22,51,62,1,55,54,38,39,55, -30,1,7,2,0,35,6,38,39,1,252,254,40,4,128,254,29,1,91,76,135,149,4,1,32,31,191, -34,35,2,4,254,236,204,169,186,8,5,21,155,155,252,68,95,117,1,210,185,96,202, -104,1,124,187,92,254,246,254,228,3,177,192,0,0,0,0,1,0,70,255,232,4,189,4,58, -0,25,0,0,1,33,53,33,21,33,17,6,22,51,62,1,55,54,38,39,51,30,1,7,14,1,35,6,38, -39,1,168,254,158,3,139,254,156,1,90,77,106,117,4,1,32,29,189,34,36,2,4,243, -177,169,186,8,3,161,153,153,253,184,95,117,1,155,137,76,167,80,103,148,72,216, -231,3,177,192,0,0,0,0,2,0,91,0,0,6,110,5,176,0,24,0,33,0,0,33,34,36,53,52,36, -51,33,17,51,17,55,62,1,55,54,38,39,51,30,1,7,14,1,35,37,17,33,34,6,21,20,22, -51,2,70,233,254,254,1,1,234,1,103,197,83,106,116,4,1,31,30,190,33,36,2,4,243, -176,254,232,254,153,148,146,146,148,246,198,197,239,2,64,250,233,1,1,141,126, -77,167,79,100,151,72,204,218,154,2,59,160,119,123,169,0,0,0,2,0,98,255,233,6, -116,6,24,0,34,0,51,0,0,19,16,18,51,50,22,23,17,51,17,6,22,51,62,1,55,54,38,39, -55,30,1,7,2,0,35,6,38,39,14,1,35,34,2,53,1,46,1,35,34,6,29,1,20,22,51,50,54, -55,46,1,53,98,223,201,89,140,52,197,2,92,77,134,148,4,1,31,30,190,33,36,2,4, -254,236,203,120,163,41,53,161,109,198,224,2,193,39,114,78,142,135,134,141,84, -116,39,3,3,2,9,1,5,1,64,62,59,2,67,251,65,95,117,1,210,185,97,203,102,1,122, -189,92,254,246,254,228,2,85,93,87,89,1,31,234,1,61,58,67,234,187,21,164,197, -73,66,15,34,18,0,1,0,54,255,232,5,211,5,176,0,44,0,0,1,52,38,43,1,53,51,50,54, -53,52,38,35,33,53,33,50,22,21,20,6,7,30,1,29,1,6,22,51,62,1,55,54,38,39,51,30, -1,7,10,1,35,6,38,39,2,191,137,116,191,136,166,147,143,152,254,153,1,103,239, -253,117,111,118,105,1,79,67,116,128,4,1,31,30,190,34,34,1,4,254,187,160,174,8, -1,114,118,145,155,126,131,121,135,155,212,201,113,165,49,40,176,128,68,76,95, -1,212,183,97,204,102,134,179,90,254,247,254,227,3,157,171,0,0,1,0,49,255,227, -4,235,4,58,0,45,0,0,37,6,22,51,62,1,55,54,38,39,51,30,1,7,14,1,35,6,38,39,53, -52,38,43,1,39,51,50,54,53,52,38,35,33,39,33,50,22,21,20,6,7,30,1,29,1,2,236,1, -39,47,106,117,4,1,32,30,190,34,36,2,5,242,177,138,138,6,106,98,211,2,184,119, -113,114,119,254,250,6,1,12,206,226,96,93,99,89,213,42,44,2,153,137,76,164,79, -102,146,71,215,230,3,114,129,75,71,79,154,83,77,81,95,153,170,152,81,114,36, -28,122,89,77,0,2,0,80,254,219,3,253,5,176,0,33,0,39,0,0,19,53,51,50,54,53,52, -38,35,33,53,33,50,22,21,20,6,7,30,1,29,1,20,22,23,21,35,46,1,61,1,52,38,35,1, -3,35,19,53,51,112,221,167,149,143,152,254,238,1,18,239,252,117,111,119,105,31, -37,203,41,21,137,116,2,118,132,107,42,197,2,120,154,127,130,122,136,155,212, -203,112,166,48,40,176,128,136,68,108,34,25,35,131,71,132,118,145,253,100,254, -255,1,10,188,0,0,2,0,123,254,219,3,187,4,58,0,33,0,39,0,0,19,53,33,50,54,53, -52,38,35,33,53,33,50,22,21,20,6,7,30,1,29,1,20,22,23,21,35,46,1,61,1,52,38,35, -1,3,35,19,53,51,125,1,22,120,112,113,119,254,232,1,24,205,225,97,94,102,89,29, -34,203,37,20,106,98,2,11,132,107,42,197,1,183,154,83,78,81,94,153,169,153,81, -116,36,29,132,97,97,45,86,22,19,23,99,51,95,80,91,254,37,254,255,1,10,188,0,2, -0,91,0,0,4,114,5,176,0,10,0,19,0,0,1,17,51,17,33,34,36,53,52,36,51,1,17,33,34, -6,21,20,22,51,3,173,197,253,212,233,254,254,1,1,234,1,103,254,153,148,146,146, -148,3,112,2,64,250,80,246,198,197,239,253,42,2,59,160,119,123,169,0,0,0,0,1,0, -156,255,235,5,2,5,197,0,42,0,0,1,34,6,21,20,22,51,50,54,53,51,23,22,4,35,32, -36,53,52,54,55,46,1,53,52,36,33,50,4,15,1,35,52,38,35,34,6,21,20,22,59,1,21,2, -205,181,183,202,178,156,199,188,2,4,254,188,225,254,254,254,193,142,135,120, -135,1,42,1,1,223,1,50,5,1,188,195,140,178,180,167,175,184,2,152,129,133,120, -149,157,114,6,205,214,227,200,126,173,42,48,166,101,199,216,220,176,6,105,142, -144,112,114,132,156,0,0,1,0,163,0,0,4,34,6,218,0,9,0,0,1,35,53,33,17,35,17,33, -17,51,4,34,197,254,11,197,2,186,197,5,15,6,250,235,5,176,1,42,0,0,0,1,0,143,0, -0,3,16,5,100,0,9,0,0,1,35,53,35,17,35,17,33,17,51,3,16,197,247,197,1,188,197, -3,153,5,252,98,4,58,1,42,0,0,0,0,2,0,41,0,0,3,223,5,176,0,5,0,15,0,0,1,51,9,1, -35,1,33,1,39,35,7,3,1,23,51,55,1,183,150,1,146,254,113,149,254,110,2,237,254, -255,17,6,18,250,1,1,17,6,18,5,176,253,39,253,41,2,215,2,0,50,50,254,0,254,1, -50,50,0,0,0,0,1,0,163,0,0,4,255,5,176,0,20,0,0,9,2,35,1,35,21,35,53,35,17,35, -17,51,17,51,53,51,21,51,1,4,213,254,114,1,184,246,254,172,78,157,98,197,197, -98,157,76,1,61,5,176,253,79,253,1,2,146,243,243,253,110,5,176,253,124,255,255, -2,132,0,0,0,0,1,0,153,0,0,4,99,4,58,0,20,0,0,9,2,35,1,35,21,35,53,35,17,35,17, -51,17,51,53,51,21,51,19,4,64,254,173,1,118,249,254,243,23,157,75,197,197,75, -157,15,255,4,58,254,0,253,198,1,203,191,191,254,53,4,58,254,55,211,211,1,201, -0,2,0,147,0,0,4,204,5,176,0,3,0,19,0,0,1,35,17,51,1,17,35,17,33,34,38,53,17, -51,17,20,22,51,33,17,3,30,158,158,1,174,197,254,117,241,248,198,138,153,1,139, -1,60,2,189,1,183,250,80,2,74,211,237,1,166,254,90,165,127,2,202,0,2,0,115,0,0, -3,220,4,58,0,3,0,19,0,0,37,35,17,51,1,35,17,35,34,38,53,17,51,17,20,22,59,1, -17,51,2,135,158,158,1,85,197,208,236,232,197,124,147,208,197,229,2,54,252,229, -1,165,174,222,1,9,254,247,145,96,1,250,0,1,0,143,254,75,3,251,4,58,0,23,0,0,1, -17,33,17,51,17,20,6,35,34,38,39,55,30,1,51,50,54,53,17,33,17,35,17,1,84,1,226, -197,173,153,31,53,28,15,13,67,17,60,69,254,30,197,4,58,254,44,1,212,251,109, -167,181,9,9,150,5,8,103,90,2,37,254,52,4,58,0,1,0,169,254,75,4,246,5,176,0,23, -0,0,1,17,33,17,51,17,20,6,35,34,38,39,55,30,1,51,50,54,53,17,33,17,35,17,1, -110,2,195,197,173,153,31,53,28,14,14,67,17,60,69,253,61,197,5,176,253,110,2, -146,249,247,167,181,9,9,150,5,8,103,90,2,220,253,125,5,176,0,2,0,74,254,68,3, -164,7,114,0,44,0,53,0,0,1,50,54,53,52,38,35,33,53,33,50,4,21,20,6,7,30,1,21, -20,4,43,1,34,6,21,20,22,23,7,46,1,39,52,54,59,1,50,54,53,52,38,43,1,53,1,55, -51,23,1,35,1,55,51,1,156,154,146,143,137,254,208,1,48,211,1,11,130,115,129, -138,254,247,211,50,76,69,93,66,79,111,155,1,179,161,42,129,149,164,158,143,1, -10,196,171,2,254,242,198,254,243,2,170,3,57,127,114,102,133,155,213,181,103, -164,44,41,176,127,200,227,59,53,70,85,30,127,47,164,111,129,128,149,119,133, -134,155,3,137,176,6,254,255,1,1,6,0,0,0,0,2,0,73,254,68,3,121,6,26,0,44,0,53, -0,0,1,50,54,53,52,38,35,33,53,33,50,22,21,20,6,7,30,1,21,20,6,43,1,34,6,21,20, -22,23,7,46,1,39,52,54,59,1,50,54,53,52,38,43,1,53,19,55,51,23,1,35,1,55,51,1, -154,133,126,123,116,254,209,1,47,192,245,103,91,105,111,243,192,49,76,69,94, -66,80,111,155,1,179,161,41,110,127,143,138,143,196,196,171,2,254,242,198,254, -243,2,170,2,106,83,75,65,85,156,168,142,73,119,35,33,122,86,151,173,59,53,70, -86,29,127,47,164,111,129,128,91,74,82,81,155,3,0,176,6,254,255,1,1,6,0,0,0,2, -0,209,0,0,6,244,5,176,0,19,0,23,0,0,1,33,1,51,1,35,3,35,17,35,17,35,3,35,19, -33,17,35,17,51,1,33,3,35,1,151,1,126,1,52,169,2,2,201,149,161,196,148,152,201, -158,254,189,198,198,2,63,1,136,191,6,2,91,3,85,250,80,1,182,254,74,1,182,254, -74,1,183,254,73,5,176,252,170,2,51,0,0,2,0,186,0,0,5,232,4,58,0,19,0,25,0,0,1, -33,1,51,1,35,3,35,17,35,17,35,3,35,19,35,17,35,17,51,1,33,3,39,35,7,1,127,1,3, -1,2,169,1,187,201,119,106,196,113,116,201,119,196,197,197,1,199,1,36,126,18,6, -18,1,193,2,121,251,198,1,38,254,218,1,38,254,218,1,37,254,219,4,58,253,135,1, -56,68,68,255,255,0,163,0,0,4,188,5,176,0,99,1,49,1,217,2,204,51,51,76,205,0,2, -0,48,0,0,0,3,0,143,254,96,4,41,4,78,0,3,0,21,0,35,0,0,5,7,3,55,37,20,2,35,34, -38,39,17,35,17,51,23,62,1,51,50,18,17,35,52,38,35,34,6,7,17,30,1,51,50,54,53, -3,125,147,175,148,1,90,224,197,100,151,53,197,151,31,53,158,105,201,223,197, -145,141,85,120,37,37,120,87,140,144,136,55,1,217,55,163,234,254,225,67,67,253, -239,5,218,140,78,82,254,193,254,250,184,237,77,67,253,245,67,75,205,162,0,0,0, -0,1,0,95,254,75,4,75,4,73,0,37,0,0,19,50,22,31,1,51,19,51,1,19,30,1,51,50,54, -55,7,14,1,35,34,38,39,3,35,1,35,1,3,46,1,35,34,6,35,53,62,1,202,129,151,42,92, -6,233,198,254,171,204,33,62,42,14,10,22,3,10,36,13,116,139,53,127,6,254,247, -209,1,127,163,33,86,60,10,54,4,20,63,4,73,160,108,222,1,219,253,61,254,20,75, -79,2,3,156,6,9,130,142,1,44,253,218,3,14,1,130,83,106,5,145,5,10,0,0,0,1,0, -160,4,140,1,122,6,23,0,5,0,0,19,55,51,3,21,35,160,121,97,21,197,5,32,247,254, -255,138,0,0,2,0,78,255,235,6,25,4,58,0,22,0,44,0,0,1,35,30,1,21,20,2,35,34,38, -39,14,1,35,34,2,53,52,54,55,35,53,33,1,46,1,39,33,14,1,7,20,22,51,50,54,61,1, -51,21,20,22,51,50,54,6,25,133,29,33,174,184,119,165,40,41,164,118,185,173,32, -30,111,5,203,254,244,3,40,34,252,209,35,40,2,83,89,98,116,198,115,99,87,84,3, -158,81,182,101,254,254,183,121,116,117,120,1,73,254,101,182,81,156,253,248,89, -182,93,94,182,88,190,239,162,175,250,250,175,162,238,0,1,255,234,0,0,4,83,5, -187,0,35,0,0,1,62,1,51,50,22,23,7,46,1,35,34,6,7,1,17,35,17,1,46,1,35,34,6,7, -39,62,1,51,50,22,23,19,23,51,55,2,230,51,123,81,34,50,26,23,5,22,13,33,55,16, -254,212,196,254,212,17,55,32,14,21,5,22,24,50,35,80,123,52,178,19,6,19,4,215, -124,104,10,14,152,3,5,35,39,253,121,253,190,2,66,2,135,39,35,5,3,152,14,10, -104,124,254,106,70,70,0,255,255,0,113,255,85,5,2,6,68,2,38,0,47,0,0,0,39,1,49, -1,248,0,131,0,7,1,49,1,248,5,167,255,255,0,97,255,99,4,42,4,217,2,38,0,79,0,0, -0,39,1,49,1,132,0,145,0,7,1,49,1,132,4,60,0,2,0,108,255,235,6,98,7,7,0,11,0, -54,0,0,1,21,39,55,33,21,35,53,35,21,35,53,5,6,2,21,16,18,51,50,54,55,30,1,51, -50,18,17,52,2,39,35,22,18,23,20,2,39,35,6,38,53,17,35,17,20,6,39,35,6,2,53,54, -18,55,2,138,175,1,3,53,177,153,178,253,242,62,93,204,215,124,176,44,43,176, -125,214,205,94,61,206,64,95,5,114,115,6,101,131,198,132,101,6,116,112,4,95,65, -6,154,130,1,238,239,130,130,130,234,105,254,55,192,254,213,254,88,173,155,155, -173,1,168,1,43,191,1,202,105,131,254,51,162,235,254,180,5,6,255,221,2,22,253, -234,221,255,6,5,1,77,234,162,1,205,131,0,0,0,2,0,127,255,235,5,210,5,182,0,11, -0,52,0,0,1,21,39,55,33,21,35,53,35,21,35,53,1,6,2,21,20,18,51,50,54,55,30,1, -51,50,18,53,52,2,39,35,22,18,23,20,6,35,34,38,53,17,35,17,20,6,35,34,38,53,54, -18,55,2,92,175,1,3,53,176,154,178,254,31,61,74,173,185,118,164,41,40,165,119, -184,174,75,60,207,65,76,4,84,87,99,115,198,116,98,89,83,3,76,65,5,73,130,1, -238,239,130,130,130,254,241,106,254,252,154,254,254,183,120,117,116,121,1,73, -254,154,1,4,106,134,254,253,127,191,238,162,175,1,44,254,212,175,162,239,190, -126,1,2,136,0,0,2,0,149,0,0,6,75,5,176,0,33,0,37,0,0,1,51,50,22,21,17,35,17, -52,38,43,1,7,17,35,17,39,35,34,6,21,17,35,17,52,54,59,1,1,51,23,55,53,33,1,51, -1,33,4,76,22,239,250,197,139,153,116,25,197,17,131,153,137,197,247,240,37,254, -121,226,5,6,3,204,253,159,10,1,28,253,190,3,46,209,234,254,141,1,115,162,126, -42,253,151,2,120,27,126,162,254,141,1,115,234,209,2,130,9,2,7,253,126,1,231,0, -2,0,149,0,0,5,87,4,59,0,31,0,34,0,0,1,51,1,30,1,29,1,35,53,52,38,43,1,7,17,35, -17,39,35,34,6,29,1,35,53,52,54,55,1,51,53,33,1,19,33,4,99,123,254,227,198,208, -198,119,132,47,11,197,6,60,133,118,197,212,205,254,228,158,2,171,254,153,176, -254,160,4,58,254,33,10,210,221,162,162,163,125,19,254,81,1,184,10,125,163,162, -162,226,208,7,1,223,1,254,36,1,64,0,4,0,190,0,0,8,130,5,176,0,3,0,7,0,41,0,45, -0,0,1,33,53,33,1,35,17,51,1,51,50,22,21,17,35,17,52,38,43,1,7,17,35,17,39,35, -34,6,21,17,35,17,52,54,59,1,1,51,23,55,53,33,1,51,1,33,4,252,252,109,3,147, -252,136,198,198,4,255,22,239,250,197,139,153,116,25,197,17,131,153,137,197, -247,240,37,254,121,226,5,6,3,204,253,159,10,1,28,253,190,2,148,154,252,210,5, -176,253,126,209,234,254,141,1,115,162,126,42,253,151,2,120,27,126,162,254,141, -1,115,234,209,2,130,9,2,7,253,126,1,231,0,0,0,0,4,0,153,0,0,7,81,4,59,0,3,0,7, -0,39,0,42,0,0,1,33,53,33,1,35,17,51,33,51,1,30,1,29,1,35,53,52,38,43,1,7,17, -35,17,39,35,34,6,29,1,35,53,52,54,55,1,51,53,33,1,19,33,4,248,252,11,3,245, -252,102,197,197,4,255,123,254,227,198,208,198,119,132,47,11,197,6,60,133,118, -197,212,205,254,228,158,2,171,254,153,176,254,160,1,194,155,253,163,4,58,254, -33,10,210,221,162,162,163,125,19,254,81,1,184,10,125,163,162,162,226,208,7,1, -223,1,254,36,1,64,0,0,22,0,91,254,114,7,238,5,174,0,13,0,28,0,42,0,59,0,65,0, -71,0,77,0,83,0,93,0,97,0,101,0,105,0,109,0,113,0,117,0,126,0,130,0,134,0,138, -0,142,0,146,0,150,0,0,1,52,38,35,34,6,29,1,20,22,51,50,54,53,5,50,54,53,52,38, -39,62,1,53,52,38,43,1,17,39,20,6,35,34,38,61,1,52,54,51,50,22,21,5,20,6,35,34, -38,53,35,7,6,22,51,50,54,53,17,35,1,17,51,21,51,21,33,53,51,53,51,17,1,17,33, -21,35,21,37,53,33,17,35,53,1,51,30,1,21,20,6,43,1,53,1,53,33,21,33,53,33,21, -33,53,33,21,1,53,33,21,33,53,33,21,33,53,33,21,19,51,50,22,21,20,6,43,1,5,35, -53,51,53,35,53,51,17,35,53,51,37,35,53,51,53,35,53,51,17,35,53,51,3,57,129, -102,102,128,128,104,101,128,1,32,92,105,54,48,40,44,111,101,188,159,74,63,66, -74,74,64,64,75,3,186,55,40,50,54,84,2,6,105,91,81,106,92,249,196,113,196,5,40, -199,111,248,109,1,53,196,5,236,1,54,111,252,218,5,47,51,53,50,126,1,78,1,22, -253,91,1,21,253,92,1,20,2,10,1,22,253,91,1,21,253,92,1,20,188,93,61,57,60,58, -93,252,241,113,113,113,113,113,113,7,34,111,111,111,111,111,111,2,68,96,123, -123,96,112,98,121,121,98,216,79,76,45,70,13,15,62,39,75,75,253,219,216,69,78, -78,69,112,68,79,79,68,155,44,54,45,46,6,77,81,92,79,1,122,251,79,1,59,202,113, -113,202,254,197,6,31,1,29,116,169,169,116,254,227,169,252,182,2,46,38,40,43, -169,3,74,116,116,116,116,116,116,249,56,113,113,113,113,113,113,4,91,32,39,40, -40,150,252,126,250,252,21,249,126,252,126,250,252,21,249,0,0,5,0,92,253,213,7, -215,8,98,0,3,0,30,0,34,0,38,0,42,0,0,9,3,5,52,54,55,62,1,53,52,38,35,34,6,31, -1,51,62,1,51,50,22,21,20,6,7,14,1,21,23,35,21,51,3,51,21,35,3,51,21,35,4,24,3, -191,252,65,252,68,4,15,26,40,72,94,169,147,136,167,3,3,194,1,59,43,54,59,51, -42,79,59,202,202,202,75,4,4,2,4,4,6,82,252,49,252,49,3,207,241,53,61,26,39, -131,78,128,151,130,130,6,51,52,63,53,50,77,28,55,90,88,91,170,253,76,4,10,141, -4,255,255,0,5,254,103,3,160,0,0,0,39,0,63,0,1,255,1,0,6,0,63,1,0,0,2,0,113, -255,235,5,2,5,195,0,33,0,48,0,0,1,53,52,54,51,50,22,29,1,16,0,33,34,0,25,1,16, -0,31,1,21,34,2,21,17,20,18,51,50,54,55,46,1,53,5,53,52,38,35,34,6,29,1,20,22, -23,62,1,53,2,29,206,165,165,205,254,181,254,248,254,254,192,1,62,250,6,172, -205,205,172,63,109,45,168,195,2,32,93,80,80,94,151,134,30,32,2,145,59,176,231, -229,178,80,254,229,254,138,1,96,1,10,1,6,1,9,1,95,4,2,154,254,255,197,254,248, -201,255,0,34,34,42,241,166,21,83,107,136,138,105,64,122,167,14,59,145,80,0,2, -0,97,255,235,4,42,4,76,0,33,0,48,0,0,1,53,52,54,51,50,22,29,1,20,0,35,34,0,61, -1,52,0,31,1,21,34,6,29,1,20,22,51,50,54,55,46,1,53,5,53,52,38,35,34,6,29,1,20, -22,51,62,1,53,1,210,169,130,129,172,254,240,203,219,254,237,1,17,215,6,136, -161,160,137,29,55,25,109,125,1,147,62,42,44,58,91,80,16,19,1,233,37,132,174, -187,140,33,211,254,230,1,36,222,54,239,1,58,4,2,153,219,173,56,155,198,12,12, -35,174,116,17,36,67,96,82,61,41,82,101,36,86,46,0,0,2,0,113,255,235,4,176,5, -197,0,26,0,38,0,0,1,53,52,54,51,50,22,21,17,16,0,35,34,0,25,1,55,17,20,22,51, -50,54,55,38,36,53,37,52,38,35,34,6,29,1,20,22,23,55,2,9,189,151,157,182,254, -207,248,238,254,216,197,182,155,165,190,2,218,254,247,1,227,73,70,66,77,150, -130,6,4,12,62,172,207,202,177,254,6,254,234,254,177,1,92,1,9,2,148,2,253,106, -200,252,237,208,8,251,192,62,108,109,109,108,64,120,158,4,2,0,1,0,112,0,0,4, -148,5,62,0,19,0,0,1,5,7,37,3,35,19,37,55,5,19,37,55,5,19,51,3,5,7,37,2,92,1, -33,71,254,221,181,174,225,254,223,71,1,37,202,254,222,73,1,35,185,171,229,1, -37,75,254,224,1,191,172,125,170,254,192,1,142,171,124,171,1,108,171,126,171,1, -74,254,105,171,124,170,0,0,8,0,59,254,196,7,212,5,175,0,15,0,31,0,47,0,63,0, -79,0,95,0,111,0,127,0,0,1,39,38,54,51,50,22,15,1,35,52,38,35,34,6,21,1,39,38, -54,51,50,22,15,1,35,52,38,35,34,6,21,19,39,38,54,51,50,22,15,1,35,52,38,35,34, -6,21,1,39,38,54,51,50,22,15,1,35,52,38,35,34,6,21,1,39,38,54,51,50,22,15,1,35, -52,38,35,34,6,21,1,39,38,54,51,50,22,15,1,35,52,38,35,34,6,21,1,39,38,54,51, -50,22,15,1,35,52,38,35,34,6,21,19,39,38,54,51,50,22,15,1,35,52,38,35,34,6,21, -3,47,2,5,112,97,96,113,4,2,104,49,50,50,47,1,230,2,5,113,96,96,114,4,2,105,48, -51,50,46,81,2,5,113,96,96,113,4,2,104,48,51,50,47,254,210,2,5,113,96,96,113,4, -2,104,48,51,50,47,253,87,2,5,112,97,96,113,4,2,104,49,50,50,47,253,85,2,5,113, -97,96,113,4,2,104,49,50,50,47,254,230,2,5,113,96,96,113,4,2,104,48,51,50,47, -61,2,5,113,96,96,114,4,2,105,48,51,50,46,4,243,6,79,103,103,79,6,43,58,58,43, -254,235,6,78,104,103,79,6,44,57,58,43,254,9,6,78,104,103,79,6,44,57,58,43,253, -249,6,78,104,103,79,6,44,57,58,43,254,228,6,80,102,102,80,6,44,57,57,44,5,26, -6,79,103,103,79,6,43,58,58,43,254,9,6,78,104,103,79,6,44,57,58,43,253,249,6, -78,104,103,79,6,44,57,58,43,0,0,0,8,0,77,254,99,7,141,5,198,0,4,0,9,0,14,0,19, -0,25,0,30,0,35,0,40,0,0,5,23,3,35,19,3,39,19,51,3,1,55,5,21,37,5,7,37,53,5,1, -55,37,23,6,5,1,7,5,39,37,3,39,3,55,19,1,23,19,7,3,4,80,11,122,96,70,58,12,122, -96,70,2,30,13,1,77,254,166,251,116,13,254,179,1,90,3,156,2,1,65,68,37,254,255, -252,243,2,254,192,69,1,38,43,17,148,65,198,3,96,17,149,66,197,60,14,254,173,1, -97,4,162,14,1,82,254,160,254,17,12,124,98,71,59,12,124,98,71,1,174,16,153,68, -23,177,252,142,17,153,69,200,2,228,2,1,70,69,254,213,252,227,2,254,187,71,1, -43,0,0,1,0,122,2,139,2,250,5,186,0,19,0,0,1,23,62,1,51,50,22,21,17,35,17,52, -38,35,34,6,7,17,35,17,1,2,31,36,110,70,122,135,180,71,65,53,72,19,180,5,171, -120,64,71,151,156,254,4,1,219,102,91,54,47,253,201,3,32,0,2,0,152,255,236,4, -147,4,78,0,21,0,30,0,0,37,14,1,35,34,0,53,52,0,51,50,0,29,1,33,17,30,1,51,50, -54,55,1,34,6,7,17,33,17,46,1,4,22,87,188,95,218,254,206,1,67,201,207,1,32,253, -0,55,141,77,95,186,87,254,144,74,141,58,2,28,54,139,94,55,59,1,73,232,226,1, -79,254,202,231,47,254,184,53,57,60,62,3,42,65,57,254,235,1,30,52,61,0,0,2,0, -105,4,111,2,206,5,197,0,5,0,11,0,0,1,19,51,21,3,35,5,51,53,55,35,7,1,150,102, -210,229,83,254,211,189,81,108,162,4,140,1,57,21,254,193,2,137,204,198,0,0,4,0, -124,255,235,5,131,5,197,0,29,0,43,0,57,0,61,0,0,1,23,22,6,35,34,38,61,1,52,54, -51,50,22,15,1,35,52,38,35,34,6,29,1,20,22,51,50,54,53,1,20,22,51,50,54,61,1, -52,38,35,34,6,21,51,52,54,51,50,22,29,1,20,6,35,34,38,53,19,39,1,23,2,165,2,4, -150,126,129,154,153,128,126,152,4,2,138,70,64,65,70,71,66,63,69,1,14,165,138, -135,164,165,136,137,164,146,81,74,73,82,80,73,76,81,203,109,253,57,109,4,32,6, -105,145,172,127,77,127,174,148,103,6,57,78,105,74,77,74,103,80,54,252,247,128, -172,172,128,78,127,173,173,127,74,104,104,74,78,75,103,103,75,3,201,67,251, -142,67,0,0,0,255,255,0,169,0,0,8,78,5,193,0,34,0,46,0,0,0,35,0,119,5,35,255, -252,0,3,0,13,5,32,255,21,0,2,0,106,255,237,3,115,5,197,0,27,0,40,0,0,5,7,6,38, -61,1,14,1,35,53,50,54,55,17,52,54,51,50,22,29,1,20,2,7,21,20,22,51,3,53,52,38, -35,34,6,21,17,23,62,1,53,2,206,6,199,205,49,101,52,55,101,46,159,139,122,155, -203,175,96,117,32,44,36,51,50,6,85,90,13,2,4,239,211,12,12,12,180,13,13,1,217, -177,202,172,144,42,158,254,174,100,92,145,146,3,209,44,76,78,109,108,254,155, -1,64,204,109,0,0,0,3,0,164,255,235,6,17,5,176,0,10,0,19,0,43,0,0,1,17,35,17, -33,50,4,21,20,4,35,39,51,50,54,53,52,38,43,1,37,17,51,21,35,17,20,22,51,50,54, -55,23,14,1,35,34,38,53,17,35,53,51,17,1,105,197,1,98,232,1,4,254,252,232,157, -157,147,147,147,147,157,3,208,205,205,63,52,17,41,16,27,23,86,42,119,143,171, -171,2,52,253,204,5,176,249,197,199,247,155,167,122,123,170,42,254,251,146,253, -111,76,62,8,6,135,18,23,145,155,2,145,146,1,5,0,2,0,98,255,235,4,126,6,24,0, -25,0,39,0,0,1,35,17,35,39,14,1,35,34,2,61,1,16,18,51,50,22,23,53,33,53,33,17, -51,17,51,1,20,22,51,50,54,55,17,46,1,35,34,6,21,4,126,137,151,30,53,156,103, -198,224,223,201,95,147,52,255,0,1,0,197,137,252,169,134,141,88,120,38,38,121, -85,142,135,4,112,251,144,137,78,80,1,31,234,21,1,5,1,64,70,67,171,154,1,14, -254,242,252,234,164,197,80,72,1,249,67,79,234,187,255,255,0,161,0,0,3,33,0, -202,0,38,0,14,0,0,0,7,0,14,1,187,0,0,255,255,0,129,4,164,2,216,5,176,2,6,0, -154,0,0,255,255,127,255,127,255,128,1,128,1,2,6,0,3,0,0,0,2,0,34,0,0,4,235,5, -176,0,13,0,27,0,0,51,17,35,53,51,17,33,32,0,17,21,16,0,33,19,33,17,33,50,18, -61,1,52,2,35,33,17,33,169,135,135,1,202,1,29,1,91,254,165,254,227,117,254,134, -1,5,202,233,233,202,254,251,1,122,2,151,155,2,126,254,161,254,234,199,254,233, -254,163,2,151,254,3,1,10,208,201,206,1,10,254,29,0,0,0,0,2,0,34,0,0,4,235,5, -176,0,13,0,27,0,0,51,17,35,53,51,17,33,32,0,17,21,16,0,33,19,33,17,33,50,18, -61,1,52,2,35,33,17,33,169,135,135,1,202,1,29,1,91,254,165,254,227,117,254,134, -1,5,202,233,233,202,254,251,1,122,2,151,155,2,126,254,161,254,234,199,254,233, -254,163,2,151,254,3,1,10,208,201,206,1,10,254,29,0,0,0,0,1,0,18,0,0,4,0,6,24, -0,27,0,0,1,33,17,62,1,51,50,22,21,17,35,17,52,38,35,34,6,7,17,35,17,35,53,51, -53,51,21,33,2,216,254,124,56,163,99,173,193,197,115,114,88,130,40,197,125,125, -197,1,132,4,207,254,218,78,87,208,216,253,90,2,168,134,128,69,62,252,213,4, -207,155,174,174,0,0,0,1,0,37,0,0,4,164,5,176,0,15,0,0,1,33,17,35,17,35,53,51, -53,33,53,33,21,33,21,33,3,199,254,253,197,254,254,254,38,4,127,254,32,1,3,3, -156,252,100,3,156,155,222,155,155,222,255,255,0,167,2,26,2,245,2,180,2,6,0,13, -0,0,255,255,0,43,0,0,4,227,7,75,2,38,0,33,0,0,0,7,0,64,0,241,1,93,255,255,0, -43,0,0,4,227,7,71,2,38,0,33,0,0,0,7,0,113,1,171,1,89,255,255,0,43,0,0,4,227,7, -72,2,38,0,33,0,0,0,7,0,152,0,171,1,93,255,255,0,43,0,0,4,227,7,84,2,38,0,33,0, -0,0,7,0,158,0,166,1,97,255,255,0,43,0,0,4,227,7,13,2,38,0,33,0,0,0,7,0,102,0, -134,1,93,255,255,0,43,0,0,4,227,7,113,2,38,0,33,0,0,0,7,0,156,1,50,1,172,255, -255,0,43,0,0,4,227,7,113,2,38,0,33,0,0,0,39,0,156,1,50,1,172,0,7,0,113,1,171, -1,89,255,255,0,118,254,68,4,191,5,197,2,38,0,35,0,0,0,7,0,117,1,206,255,247, -255,255,0,163,0,0,4,36,7,75,2,38,0,37,0,0,0,7,0,64,0,205,1,93,255,255,0,163,0, -0,4,36,7,71,2,38,0,37,0,0,0,7,0,113,1,135,1,89,255,255,0,163,0,0,4,36,7,72,2, -38,0,37,0,0,0,7,0,152,0,135,1,93,255,255,0,163,0,0,4,36,7,13,2,38,0,37,0,0,0, -7,0,102,0,98,1,93,255,255,255,221,0,0,1,132,7,75,2,38,0,41,0,0,0,7,0,64,255, -139,1,93,255,255,0,190,0,0,2,104,7,71,2,38,0,41,0,0,0,7,0,113,0,68,1,89,255, -255,255,179,0,0,2,146,7,72,2,38,0,41,0,0,0,7,0,152,255,69,1,93,255,255,255, -192,0,0,2,133,7,13,2,38,0,41,0,0,0,7,0,102,255,32,1,93,255,255,0,169,0,0,4, -246,7,84,2,38,0,46,0,0,0,7,0,158,0,236,1,97,255,255,0,113,255,235,5,2,7,96,2, -38,0,47,0,0,0,7,0,64,1,36,1,114,255,255,0,113,255,235,5,2,7,92,2,38,0,47,0,0, -0,7,0,113,1,222,1,110,255,255,0,113,255,235,5,2,7,93,2,38,0,47,0,0,0,7,0,152, -0,222,1,114,255,255,0,113,255,235,5,2,7,105,2,38,0,47,0,0,0,7,0,158,0,217,1, -118,255,255,0,113,255,235,5,2,7,34,2,38,0,47,0,0,0,7,0,102,0,185,1,114,255, -255,0,147,255,235,4,220,7,75,2,38,0,53,0,0,0,7,0,64,1,34,1,93,255,255,0,147, -255,235,4,220,7,71,2,38,0,53,0,0,0,7,0,113,1,220,1,89,255,255,0,147,255,235,4, -220,7,72,2,38,0,53,0,0,0,7,0,152,0,220,1,93,255,255,0,147,255,235,4,220,7,13, -2,38,0,53,0,0,0,7,0,102,0,183,1,93,255,255,0,40,0,0,4,226,7,70,2,38,0,57,0,0, -0,7,0,113,1,169,1,88,255,255,0,106,255,235,3,243,6,9,2,38,0,65,0,0,0,7,0,64,0, -148,0,27,255,255,0,106,255,235,3,243,6,5,2,38,0,65,0,0,0,7,0,113,1,78,0,23, -255,255,0,106,255,235,3,243,6,6,2,38,0,65,0,0,0,6,0,152,78,27,0,0,255,255,0, -106,255,235,3,243,6,18,2,38,0,65,0,0,0,6,0,158,73,31,0,0,255,255,0,106,255, -235,3,243,5,203,2,38,0,65,0,0,0,6,0,102,41,27,0,0,255,255,0,106,255,235,3,243, -6,47,2,38,0,65,0,0,0,7,0,156,0,213,0,106,255,255,0,106,255,235,3,243,6,47,2, -38,0,65,0,0,0,39,0,156,0,213,0,106,0,7,0,113,1,78,0,23,255,255,0,97,254,68,3, -217,4,78,2,38,0,67,0,0,0,7,0,117,1,75,255,247,255,255,0,97,255,235,3,226,6,10, -2,38,0,69,0,0,0,7,0,64,0,150,0,28,255,255,0,97,255,235,3,226,6,6,2,38,0,69,0, -0,0,7,0,113,1,80,0,24,255,255,0,97,255,235,3,226,6,7,2,38,0,69,0,0,0,6,0,152, -80,28,0,0,255,255,0,97,255,235,3,226,5,204,2,38,0,69,0,0,0,6,0,102,43,28,0,0, -255,255,255,184,0,0,1,94,5,244,2,38,0,136,0,0,0,7,0,64,255,102,0,6,255,255,0, -153,0,0,2,67,5,240,2,38,0,136,0,0,0,6,0,113,31,2,0,0,255,255,255,142,0,0,2, -109,5,241,2,38,0,136,0,0,0,7,0,152,255,32,0,6,255,255,255,155,0,0,2,96,5,182, -2,38,0,136,0,0,0,7,0,102,254,251,0,6,255,255,0,143,0,0,3,253,6,18,2,38,0,78,0, -0,0,6,0,158,96,31,0,0,255,255,0,97,255,235,4,42,6,9,2,38,0,79,0,0,0,7,0,64,0, -175,0,27,255,255,0,97,255,235,4,42,6,5,2,38,0,79,0,0,0,7,0,113,1,105,0,23,255, -255,0,97,255,235,4,42,6,6,2,38,0,79,0,0,0,6,0,152,105,27,0,0,255,255,0,97,255, -235,4,42,6,18,2,38,0,79,0,0,0,6,0,158,100,31,0,0,255,255,0,97,255,235,4,42,5, -203,2,38,0,79,0,0,0,6,0,102,68,27,0,0,255,255,0,139,255,235,3,252,5,244,2,38, -0,85,0,0,0,7,0,64,0,173,0,6,255,255,0,139,255,235,3,252,5,240,2,38,0,85,0,0,0, -7,0,113,1,103,0,2,255,255,0,139,255,235,3,252,5,241,2,38,0,85,0,0,0,6,0,152, -103,6,0,0,255,255,0,139,255,235,3,252,5,182,2,38,0,85,0,0,0,6,0,102,66,6,0,0, -255,255,0,26,254,75,3,232,5,240,2,38,0,89,0,0,0,7,0,113,1,37,0,2,255,255,0,26, -254,75,3,232,5,182,2,38,0,89,0,0,0,6,0,102,0,6,0,0,255,255,0,43,0,0,4,227,6, -250,2,38,0,33,0,0,0,7,0,108,0,170,1,74,255,255,0,106,255,235,3,243,5,184,2,38, -0,65,0,0,0,6,0,108,77,8,0,0,255,255,0,43,0,0,4,227,7,78,2,38,0,33,0,0,0,7,0, -154,0,220,1,158,255,255,0,106,255,235,3,243,6,12,2,38,0,65,0,0,0,6,0,154,127, -92,0,0,255,255,0,43,254,98,5,39,5,176,2,38,0,33,0,0,0,7,0,157,3,71,0,0,255, -255,0,106,254,98,4,57,4,78,2,38,0,65,0,0,0,7,0,157,2,89,0,0,255,255,0,118,255, -235,4,191,7,92,2,38,0,35,0,0,0,7,0,113,1,201,1,110,255,255,0,97,255,235,3,217, -6,5,2,38,0,67,0,0,0,7,0,113,1,70,0,23,255,255,0,118,255,235,4,191,7,93,2,38,0, -35,0,0,0,7,0,152,0,201,1,114,255,255,0,97,255,235,3,217,6,6,2,38,0,67,0,0,0,6, -0,152,70,27,0,0,255,255,0,118,255,235,4,191,7,34,2,38,0,35,0,0,0,7,0,155,1, -153,1,114,255,255,0,97,255,235,3,217,5,203,2,38,0,67,0,0,0,7,0,155,1,22,0,27, -255,255,0,118,255,235,4,191,7,94,2,38,0,35,0,0,0,7,0,153,0,224,1,115,255,255, -0,97,255,235,3,217,6,7,2,38,0,67,0,0,0,6,0,153,93,28,0,0,255,255,0,169,0,0,4, -235,7,73,2,38,0,36,0,0,0,7,0,153,0,156,1,94,255,255,0,98,255,235,3,245,6,24,2, -6,0,68,0,0,255,255,0,163,0,0,4,36,6,250,2,38,0,37,0,0,0,7,0,108,0,134,1,74, -255,255,0,97,255,235,3,226,5,185,2,38,0,69,0,0,0,6,0,108,79,9,0,0,255,255,0, -163,0,0,4,36,7,78,2,38,0,37,0,0,0,7,0,154,0,184,1,158,255,255,0,97,255,235,3, -226,6,13,2,38,0,69,0,0,0,7,0,154,0,129,0,93,255,255,0,163,0,0,4,36,7,13,2,38, -0,37,0,0,0,7,0,155,1,87,1,93,255,255,0,97,255,235,3,226,5,204,2,38,0,69,0,0,0, -7,0,155,1,32,0,28,255,255,0,163,254,98,4,36,5,176,2,38,0,37,0,0,0,7,0,157,1, -56,0,0,255,255,0,97,254,98,3,226,4,78,2,38,0,69,0,0,0,7,0,157,1,31,0,0,255, -255,0,163,0,0,4,36,7,73,2,38,0,37,0,0,0,7,0,153,0,158,1,94,255,255,0,97,255, -235,3,226,6,8,2,38,0,69,0,0,0,6,0,153,103,29,0,0,255,255,0,121,255,235,4,193, -7,93,2,38,0,39,0,0,0,7,0,152,0,192,1,114,255,255,0,108,254,75,4,0,6,6,2,38,0, -71,0,0,0,6,0,152,90,27,0,0,255,255,0,121,255,235,4,193,7,99,2,38,0,39,0,0,0,7, -0,154,0,241,1,179,255,255,0,108,254,75,4,0,6,12,2,38,0,71,0,0,0,7,0,154,0,139, -0,92,255,255,0,121,255,235,4,193,7,34,2,38,0,39,0,0,0,7,0,155,1,144,1,114,255, -255,0,108,254,75,4,0,5,203,2,38,0,71,0,0,0,7,0,155,1,42,0,27,255,255,0,121, -253,207,4,193,5,197,2,38,0,39,0,0,0,7,1,110,1,157,254,162,255,255,0,108,254, -75,4,0,6,112,2,38,0,71,0,0,0,7,1,169,1,46,0,89,255,255,0,169,0,0,4,246,7,72,2, -38,0,40,0,0,0,7,0,152,0,234,1,93,255,255,255,127,0,0,4,0,7,71,2,38,0,72,0,0,0, -7,0,152,255,17,1,92,255,255,255,199,0,0,2,125,7,84,2,38,0,41,0,0,0,7,0,158, -255,64,1,97,255,255,255,162,0,0,2,88,5,253,2,38,0,136,0,0,0,7,0,158,255,27,0, -10,255,255,255,171,0,0,2,154,6,250,2,38,0,41,0,0,0,7,0,108,255,68,1,74,255, -255,255,134,0,0,2,117,5,164,2,38,0,136,0,0,0,7,0,108,255,31,255,244,255,255, -255,247,0,0,2,78,7,78,2,38,0,41,0,0,0,7,0,154,255,118,1,158,255,255,255,210,0, -0,2,41,5,247,2,38,0,136,0,0,0,7,0,154,255,81,0,71,255,255,0,57,254,98,2,7,5, -176,2,38,0,41,0,0,0,6,0,157,39,0,0,0,255,255,0,27,254,98,1,233,6,24,2,38,0,73, -0,0,0,6,0,157,9,0,0,0,255,255,0,180,0,0,1,142,7,13,2,38,0,41,0,0,0,7,0,155,0, -20,1,93,255,255,0,190,255,235,5,253,5,176,0,38,0,41,0,0,0,7,0,42,2,65,0,0,255, -255,0,159,254,75,3,118,6,24,0,38,0,73,0,0,0,7,0,74,2,4,0,0,255,255,0,74,255, -235,4,193,7,60,2,38,0,42,0,0,0,7,0,152,1,116,1,81,255,255,255,160,254,75,2, -127,5,222,2,38,0,151,0,0,0,7,0,152,255,50,255,243,255,255,0,163,253,224,4,251, -5,176,2,38,0,43,0,0,0,7,1,110,1,106,254,179,255,255,0,144,253,226,4,11,6,24,2, -38,0,75,0,0,0,7,1,110,1,23,254,181,255,255,0,168,0,0,4,51,7,8,2,38,0,44,0,0,0, -7,0,113,0,43,1,26,255,255,0,159,0,0,2,73,7,83,2,38,0,76,0,0,0,7,0,113,0,37,1, -101,255,255,0,168,253,226,4,51,5,176,2,38,0,44,0,0,0,7,1,110,1,104,254,181, -255,255,0,121,253,226,1,104,6,24,2,38,0,76,0,0,0,7,1,110,0,1,254,181,255,255, -0,168,0,0,4,51,5,176,2,6,0,44,0,0,255,255,0,159,0,0,1,100,6,24,2,6,0,76,0,0, -255,255,0,156,0,0,4,51,6,206,2,38,0,44,0,0,0,7,0,155,255,252,1,30,255,255,0, -150,0,0,1,112,7,25,2,38,0,76,0,0,0,7,0,155,255,246,1,105,255,255,0,169,0,0,4, -246,7,71,2,38,0,46,0,0,0,7,0,113,1,241,1,89,255,255,0,143,0,0,3,253,6,5,2,38, -0,78,0,0,0,7,0,113,1,101,0,23,255,255,0,169,253,226,4,246,5,176,2,38,0,46,0,0, -0,7,1,110,1,205,254,181,255,255,0,143,253,226,3,253,4,78,2,38,0,78,0,0,0,7,1, -110,1,65,254,181,255,255,0,169,0,0,4,246,7,73,2,38,0,46,0,0,0,7,0,153,1,8,1, -94,255,255,0,143,0,0,3,253,6,7,2,38,0,78,0,0,0,6,0,153,124,28,0,0,255,255,0, -143,0,0,4,223,5,179,2,38,0,78,0,0,0,7,1,110,3,120,4,192,255,255,0,113,255,235, -5,2,7,15,2,38,0,47,0,0,0,7,0,108,0,221,1,95,255,255,0,97,255,235,4,42,5,184,2, -38,0,79,0,0,0,6,0,108,104,8,0,0,255,255,0,113,255,235,5,2,7,99,2,38,0,47,0,0, -0,7,0,154,1,15,1,179,255,255,0,97,255,235,4,42,6,12,2,38,0,79,0,0,0,7,0,154,0, -154,0,92,255,255,0,113,255,235,5,2,7,96,2,38,0,47,0,0,0,7,0,159,1,107,1,114, -255,255,0,97,255,235,4,64,6,9,2,38,0,79,0,0,0,7,0,159,0,246,0,27,255,255,0, -165,0,0,4,213,7,71,2,38,0,50,0,0,0,7,0,113,1,129,1,89,255,255,0,143,0,0,2,228, -6,5,2,38,0,82,0,0,0,7,0,113,0,192,0,23,255,255,0,165,253,226,4,213,5,175,2,38, -0,50,0,0,0,7,1,110,1,93,254,181,255,255,0,119,253,226,2,170,4,78,2,38,0,82,0, -0,0,7,1,110,255,255,254,181,255,255,0,165,0,0,4,213,7,73,2,38,0,50,0,0,0,7,0, -153,0,152,1,94,255,255,0,45,0,0,3,14,6,7,2,38,0,82,0,0,0,6,0,153,216,28,0,0, -255,255,0,121,255,235,4,131,7,92,2,38,0,51,0,0,0,7,0,113,1,161,1,110,255,255, -0,103,255,235,3,201,6,5,2,38,0,83,0,0,0,7,0,113,1,58,0,23,255,255,0,121,255, -235,4,131,7,93,2,38,0,51,0,0,0,7,0,152,0,161,1,114,255,255,0,103,255,235,3, -201,6,6,2,38,0,83,0,0,0,6,0,152,58,27,0,0,255,255,0,121,254,68,4,131,5,197,2, -38,0,51,0,0,0,7,0,117,1,166,255,247,255,255,0,103,254,69,3,201,4,78,2,38,0,83, -0,0,0,7,0,117,1,63,255,248,255,255,0,121,255,235,4,131,7,94,2,38,0,51,0,0,0,7, -0,153,0,184,1,115,255,255,0,103,255,235,3,201,6,7,2,38,0,83,0,0,0,6,0,153,81, -28,0,0,255,255,0,37,253,226,4,164,5,176,2,38,0,52,0,0,0,7,1,110,1,100,254,181, -255,255,0,26,253,216,2,98,5,63,2,38,0,84,0,0,0,7,1,110,0,191,254,171,255,255, -0,37,0,0,4,164,7,72,2,38,0,52,0,0,0,7,0,153,0,159,1,93,255,255,0,26,255,235,2, -98,5,63,2,6,0,84,0,0,255,255,0,147,255,235,4,220,7,84,2,38,0,53,0,0,0,7,0,158, -0,215,1,97,255,255,0,139,255,235,3,252,5,253,2,38,0,85,0,0,0,6,0,158,98,10,0, -0,255,255,0,147,255,235,4,220,6,250,2,38,0,53,0,0,0,7,0,108,0,219,1,74,255, -255,0,139,255,235,3,252,5,164,2,38,0,85,0,0,0,6,0,108,102,244,0,0,255,255,0, -147,255,235,4,220,7,78,2,38,0,53,0,0,0,7,0,154,1,13,1,158,255,255,0,139,255, -235,3,252,5,247,2,38,0,85,0,0,0,7,0,154,0,152,0,71,255,255,0,147,255,235,4, -220,7,113,2,38,0,53,0,0,0,7,0,156,1,99,1,172,255,255,0,139,255,235,3,252,6,26, -2,38,0,85,0,0,0,7,0,156,0,238,0,85,255,255,0,147,255,235,4,220,7,75,2,38,0,53, -0,0,0,7,0,159,1,105,1,93,255,255,0,139,255,235,4,62,5,244,2,38,0,85,0,0,0,7,0, -159,0,244,0,6,255,255,0,147,254,98,4,220,5,176,2,38,0,53,0,0,0,7,0,157,1,188, -0,0,255,255,0,139,254,98,4,65,4,58,2,38,0,85,0,0,0,7,0,157,2,97,0,0,255,255,0, -37,0,0,6,191,7,72,2,38,0,55,0,0,0,7,0,152,1,148,1,93,255,255,0,45,0,0,5,220,5, -241,2,38,0,87,0,0,0,7,0,152,1,40,0,6,255,255,0,40,0,0,4,226,7,71,2,38,0,57,0, -0,0,7,0,152,0,169,1,92,255,255,0,26,254,75,3,232,5,241,2,38,0,89,0,0,0,6,0, -152,37,6,0,0,255,255,0,40,0,0,4,226,7,12,2,38,0,57,0,0,0,7,0,102,0,132,1,92, -255,255,0,97,0,0,4,109,7,71,2,38,0,58,0,0,0,7,0,113,1,132,1,89,255,255,0,94,0, -0,3,186,5,240,2,38,0,90,0,0,0,7,0,113,1,47,0,2,255,255,0,97,0,0,4,109,7,13,2, -38,0,58,0,0,0,7,0,155,1,84,1,93,255,255,0,94,0,0,3,186,5,182,2,38,0,90,0,0,0, -7,0,155,0,255,0,6,255,255,0,97,0,0,4,109,7,73,2,38,0,58,0,0,0,7,0,153,0,155,1, -94,255,255,0,94,0,0,3,186,5,242,2,38,0,90,0,0,0,6,0,153,70,7,0,0,255,255,0,14, -0,0,7,132,7,71,2,38,0,125,0,0,0,7,0,113,2,238,1,89,255,255,0,88,255,235,6,154, -6,6,2,38,0,130,0,0,0,7,0,113,2,156,0,24,255,255,0,108,255,162,4,253,7,133,2, -38,0,127,0,0,0,7,0,113,1,216,1,151,255,255,0,97,255,121,4,42,6,111,2,38,0,133, -0,0,0,7,0,113,1,105,0,129,255,255,0,121,253,206,4,131,5,197,2,38,0,51,0,0,0,7, -1,110,1,125,254,161,255,255,0,103,253,207,3,201,4,78,2,38,0,83,0,0,0,7,1,110, -1,22,254,162,255,255,0,43,0,0,4,227,7,72,2,38,0,33,0,0,0,7,0,165,1,140,1,76, -255,255,0,163,0,0,4,36,7,72,2,38,0,37,0,0,0,7,0,165,1,104,1,76,255,255,0,169, -0,0,4,246,7,72,2,38,0,40,0,0,0,7,0,165,1,203,1,76,255,255,0,185,0,0,1,137,7, -72,2,38,0,41,0,0,0,7,0,165,0,37,1,76,255,255,0,113,255,235,5,2,7,93,2,38,0,47, -0,0,0,7,0,165,1,191,1,97,255,255,0,40,0,0,4,226,7,71,2,38,0,57,0,0,0,7,0,165, -1,138,1,75,255,255,0,112,0,0,4,208,7,114,2,38,0,177,0,0,0,7,0,165,255,221,1, -118,255,255,255,204,255,235,2,144,6,92,2,38,0,186,0,0,0,7,0,166,255,43,255, -183,255,255,0,43,0,0,4,227,5,176,2,6,0,33,0,0,255,255,0,163,0,0,4,198,5,176,2, -6,0,34,0,0,255,255,0,163,0,0,4,36,5,176,2,6,0,37,0,0,255,255,0,97,0,0,4,109,5, -176,2,6,0,58,0,0,255,255,0,169,0,0,4,246,5,176,2,6,0,40,0,0,255,255,0,190,0,0, -1,132,5,176,2,6,0,41,0,0,255,255,0,163,0,0,4,251,5,176,2,6,0,43,0,0,255,255,0, -163,0,0,6,65,5,176,2,6,0,45,0,0,255,255,0,169,0,0,4,246,5,176,2,6,0,46,0,0, -255,255,0,113,255,235,5,2,5,197,2,6,0,47,0,0,255,255,0,163,0,0,4,188,5,176,2, -6,0,48,0,0,255,255,0,37,0,0,4,164,5,176,2,6,0,52,0,0,255,255,0,40,0,0,4,226,5, -176,2,6,0,57,0,0,255,255,0,66,0,0,4,214,5,176,2,6,0,56,0,0,255,255,255,192,0, -0,2,133,7,13,2,38,0,41,0,0,0,7,0,102,255,32,1,93,255,255,0,40,0,0,4,226,7,12, -2,38,0,57,0,0,0,7,0,102,0,132,1,92,255,255,0,98,255,235,4,128,6,6,2,38,0,178, -0,0,0,7,0,165,1,117,0,10,255,255,0,98,255,237,3,233,6,5,2,38,0,182,0,0,0,7,0, -165,1,43,0,9,255,255,0,143,254,97,3,245,6,6,2,38,0,184,0,0,0,7,0,165,1,70,0, -10,255,255,0,197,255,235,2,115,5,242,2,38,0,186,0,0,0,6,0,165,50,246,0,0,255, -255,0,141,255,235,4,38,6,92,2,38,0,194,0,0,0,6,0,166,84,183,0,0,255,255,0,153, -0,0,4,64,4,58,2,6,0,137,0,0,255,255,0,97,255,235,4,42,4,78,2,6,0,79,0,0,255, -255,0,153,254,96,3,242,4,58,2,6,0,114,0,0,255,255,0,46,0,0,3,228,4,58,2,6,0, -86,0,0,255,255,255,205,255,235,2,146,5,182,2,38,0,186,0,0,0,7,0,102,255,45,0, -6,255,255,0,141,255,235,4,38,5,182,2,38,0,194,0,0,0,6,0,102,86,6,0,0,255,255, -0,97,255,235,4,42,6,6,2,38,0,79,0,0,0,7,0,165,1,74,0,10,255,255,0,141,255,235, -4,38,5,242,2,38,0,194,0,0,0,7,0,165,1,92,255,246,255,255,0,108,255,235,6,96,5, -242,2,38,0,197,0,0,0,7,0,165,2,106,255,246,255,255,0,163,0,0,4,36,7,13,2,38,0, -37,0,0,0,7,0,102,0,98,1,93,255,255,0,163,0,0,4,32,7,71,2,38,0,168,0,0,0,7,0, -113,1,133,1,89,0,1,0,121,255,235,4,131,5,197,0,39,0,0,1,52,38,39,46,1,53,52, -36,51,50,0,15,1,35,52,38,35,34,6,21,20,22,23,30,1,21,20,4,35,34,36,63,1,51,20, -22,51,50,54,3,190,144,185,220,243,1,4,212,230,1,17,4,3,188,173,135,137,138, -155,179,225,233,254,233,221,211,254,189,5,2,188,208,131,138,165,1,130,95,118, -48,54,214,163,172,227,254,251,174,6,124,162,133,108,96,127,47,59,204,160,178, -231,236,198,6,137,149,143,0,0,255,255,0,190,0,0,1,132,5,176,2,6,0,41,0,0,255, -255,255,192,0,0,2,133,7,13,2,38,0,41,0,0,0,7,0,102,255,32,1,93,255,255,0,74, -255,235,3,188,5,176,2,6,0,42,0,0,255,255,0,131,4,228,2,36,5,238,2,6,0,113,0,0, -255,255,0,66,255,235,4,200,7,78,2,38,0,210,0,0,0,7,0,154,0,218,1,158,255,255, -0,163,0,0,4,251,5,176,2,6,0,43,0,0,255,255,0,43,0,0,4,227,5,176,2,6,0,33,0,0, -255,255,0,163,0,0,4,198,5,176,2,6,0,34,0,0,255,255,0,163,0,0,4,32,5,176,2,6,0, -168,0,0,255,255,0,163,0,0,4,36,5,176,2,6,0,37,0,0,255,255,0,173,0,0,4,250,7, -78,2,38,0,208,0,0,0,7,0,154,1,42,1,158,255,255,0,163,0,0,6,65,5,176,2,6,0,45, -0,0,255,255,0,169,0,0,4,246,5,176,2,6,0,40,0,0,255,255,0,113,255,235,5,2,5, -197,2,6,0,47,0,0,255,255,0,168,0,0,4,247,5,176,2,6,0,173,0,0,255,255,0,163,0, -0,4,188,5,176,2,6,0,48,0,0,255,255,0,118,255,235,4,191,5,197,2,6,0,35,0,0,255, -255,0,37,0,0,4,164,5,176,2,6,0,52,0,0,255,255,0,84,0,0,5,77,5,176,2,6,0,175,0, -0,255,255,0,66,0,0,4,214,5,176,2,6,0,56,0,0,255,255,0,106,255,235,3,243,4,78, -2,6,0,65,0,0,255,255,0,97,255,235,3,226,4,78,2,6,0,69,0,0,255,255,0,143,0,0,3, -252,5,247,2,38,0,227,0,0,0,7,0,154,0,153,0,71,255,255,0,97,255,235,4,42,4,78, -2,6,0,79,0,0,255,255,0,143,254,96,4,41,4,78,2,6,0,80,0,0,0,1,0,97,255,235,3, -217,4,78,0,29,0,0,37,50,54,53,51,23,22,6,35,34,2,61,1,52,18,51,50,22,15,1,35, -52,38,35,34,6,29,1,20,22,2,61,91,136,178,3,4,248,164,228,248,249,227,181,231, -4,2,179,129,98,145,133,131,133,121,88,6,140,217,1,54,231,42,229,1,55,224,163, -6,99,139,225,160,42,163,224,0,0,255,255,0,26,254,75,3,232,4,58,2,6,0,89,0,0, -255,255,0,46,0,0,3,212,4,58,2,6,0,88,0,0,255,255,0,97,255,235,3,226,5,204,2, -38,0,69,0,0,0,6,0,102,43,28,0,0,255,255,0,143,0,0,2,237,5,240,2,38,0,223,0,0, -0,7,0,113,0,201,0,2,255,255,0,103,255,235,3,201,4,78,2,6,0,83,0,0,255,255,0, -159,0,0,1,100,6,24,2,6,0,73,0,0,255,255,255,155,0,0,2,96,5,182,2,38,0,136,0,0, -0,7,0,102,254,251,0,6,255,255,255,190,254,75,1,114,6,24,2,6,0,74,0,0,255,255, -0,153,0,0,4,64,5,239,2,38,0,228,0,0,0,7,0,113,1,62,0,1,255,255,0,26,254,75,3, -232,5,247,2,38,0,89,0,0,0,6,0,154,86,71,0,0,255,255,0,37,0,0,6,191,7,75,2,38, -0,55,0,0,0,7,0,64,1,218,1,93,255,255,0,45,0,0,5,220,5,244,2,38,0,87,0,0,0,7,0, -64,1,110,0,6,255,255,0,37,0,0,6,191,7,71,2,38,0,55,0,0,0,7,0,113,2,148,1,89, -255,255,0,45,0,0,5,220,5,240,2,38,0,87,0,0,0,7,0,113,2,40,0,2,255,255,0,37,0, -0,6,191,7,13,2,38,0,55,0,0,0,7,0,102,1,111,1,93,255,255,0,45,0,0,5,220,5,182, -2,38,0,87,0,0,0,7,0,102,1,3,0,6,255,255,0,40,0,0,4,226,7,74,2,38,0,57,0,0,0,7, -0,64,0,239,1,92,255,255,0,26,254,75,3,232,5,244,2,38,0,89,0,0,0,6,0,64,107,6, -0,0,255,255,0,126,3,183,1,68,5,176,2,6,0,7,0,0,255,255,0,126,3,168,2,121,5, -176,2,6,3,177,0,0,255,255,0,171,0,0,3,140,5,176,0,38,3,176,0,0,0,7,3,176,2,27, -0,0,255,255,0,28,0,0,3,212,6,45,0,38,0,70,0,0,0,7,0,73,2,112,0,0,255,255,0,28, -0,0,3,212,6,45,0,38,0,70,0,0,0,7,0,76,2,112,0,0,255,255,255,158,254,75,2,127, -5,223,2,38,0,151,0,0,0,7,0,153,255,73,255,244,255,255,0,160,3,149,1,102,5,176, -2,6,1,8,0,0,255,255,0,163,0,0,6,65,7,71,2,38,0,45,0,0,0,7,0,113,2,150,1,89, -255,255,0,143,0,0,6,111,6,5,2,38,0,77,0,0,0,7,0,113,2,183,0,23,255,255,0,43,0, -0,4,227,7,113,2,38,0,33,0,0,0,7,0,156,1,50,1,172,255,255,0,106,255,235,3,243, -6,47,2,38,0,65,0,0,0,7,0,156,0,213,0,106,255,255,0,113,255,235,5,2,7,59,2,38, -0,47,0,0,0,7,1,204,0,8,1,118,255,255,0,28,0,0,6,68,6,45,0,38,0,70,0,0,0,39,0, -70,2,112,0,0,0,7,0,73,4,224,0,0,255,255,0,28,0,0,6,68,6,45,0,38,0,70,0,0,0,39, -0,70,2,112,0,0,0,7,0,76,4,224,0,0,255,255,0,163,0,0,4,36,7,75,2,38,0,37,0,0,0, -7,0,64,0,205,1,93,255,255,0,173,0,0,4,250,7,75,2,38,0,208,0,0,0,7,0,64,1,63,1, -93,255,255,0,97,255,235,3,226,6,10,2,38,0,69,0,0,0,7,0,64,0,150,0,28,255,255, -0,143,0,0,3,252,5,244,2,38,0,227,0,0,0,7,0,64,0,174,0,6,255,255,0,87,0,0,5,27, -5,176,2,6,0,176,0,0,255,255,0,91,254,38,5,77,4,58,2,6,0,196,0,0,255,255,0,22, -0,0,5,23,7,7,2,38,1,111,0,0,0,7,0,159,1,35,1,25,255,255,0,46,0,0,4,14,5,224,2, -38,1,112,0,0,0,7,0,159,0,189,255,242,255,255,0,97,254,75,8,86,4,78,0,38,0,79, -0,0,0,7,0,89,4,110,0,0,255,255,0,113,254,75,9,99,5,197,0,38,0,47,0,0,0,7,0,89, -5,123,0,0,255,255,0,120,254,8,4,223,5,197,2,38,0,207,0,0,0,7,1,50,1,174,255, -189,255,255,0,100,254,9,3,236,4,76,2,38,0,226,0,0,0,7,1,50,1,42,255,190,255, -255,0,118,253,206,4,191,5,197,2,38,0,35,0,0,0,7,1,51,1,162,255,131,255,255,0, -97,253,206,3,217,4,78,2,38,0,67,0,0,0,7,1,51,1,31,255,131,255,255,0,40,0,0,4, -226,5,176,2,6,0,57,0,0,255,255,0,46,254,95,3,228,4,58,2,6,0,180,0,0,255,255,0, -190,0,0,1,132,5,176,2,6,0,41,0,0,255,255,0,26,0,0,6,124,7,78,2,38,0,206,0,0,0, -7,0,154,1,160,1,158,255,255,0,26,0,0,5,166,5,247,2,38,0,225,0,0,0,7,0,154,1, -52,0,71,255,255,0,190,0,0,1,132,5,176,2,6,0,41,0,0,255,255,0,43,0,0,4,227,7, -78,2,38,0,33,0,0,0,7,0,154,0,220,1,158,255,255,0,106,255,235,3,243,6,12,2,38, -0,65,0,0,0,6,0,154,127,92,0,0,255,255,0,43,0,0,4,227,7,13,2,38,0,33,0,0,0,7,0, -102,0,134,1,93,255,255,0,106,255,235,3,243,5,203,2,38,0,65,0,0,0,6,0,102,41, -27,0,0,255,255,0,14,0,0,7,132,5,176,2,6,0,125,0,0,255,255,0,88,255,235,6,154, -4,78,2,6,0,130,0,0,255,255,0,163,0,0,4,36,7,78,2,38,0,37,0,0,0,7,0,154,0,184, -1,158,255,255,0,97,255,235,3,226,6,13,2,38,0,69,0,0,0,7,0,154,0,129,0,93,255, -255,0,89,255,235,5,33,6,223,2,38,1,121,0,0,0,7,0,102,0,115,1,47,255,255,0,94, -255,236,3,223,5,204,0,47,0,69,4,64,4,58,192,1,0,6,0,102,43,28,0,0,255,255,0, -26,0,0,6,124,7,13,2,38,0,206,0,0,0,7,0,102,1,74,1,93,255,255,0,26,0,0,5,166,5, -182,2,38,0,225,0,0,0,7,0,102,0,222,0,6,255,255,0,120,255,235,4,223,7,34,2,38, -0,207,0,0,0,7,0,102,0,169,1,114,255,255,0,100,255,237,3,236,5,202,2,38,0,226, -0,0,0,6,0,102,37,26,0,0,255,255,0,173,0,0,4,250,6,250,2,38,0,208,0,0,0,7,0, -108,0,248,1,74,255,255,0,143,0,0,3,252,5,164,2,38,0,227,0,0,0,6,0,108,103,244, -0,0,255,255,0,173,0,0,4,250,7,13,2,38,0,208,0,0,0,7,0,102,0,212,1,93,255,255, -0,143,0,0,3,252,5,182,2,38,0,227,0,0,0,6,0,102,67,6,0,0,255,255,0,113,255,235, -5,2,7,34,2,38,0,47,0,0,0,7,0,102,0,185,1,114,255,255,0,97,255,235,4,42,5,203, -2,38,0,79,0,0,0,6,0,102,68,27,0,0,255,255,0,113,255,235,5,2,5,197,2,6,0,253,0, -0,255,255,0,97,255,235,4,42,4,78,2,6,0,254,0,0,255,255,0,113,255,235,5,2,7,38, -2,38,0,253,0,0,0,7,0,102,0,184,1,118,255,255,0,97,255,235,4,42,5,176,2,38,0, -254,0,0,0,6,0,102,68,0,0,0,255,255,0,181,255,236,4,255,7,35,2,38,0,218,0,0,0, -7,0,102,0,178,1,115,255,255,0,99,255,235,3,227,5,203,2,38,0,242,0,0,0,6,0,102, -33,27,0,0,255,255,0,66,255,235,4,200,6,250,2,38,0,210,0,0,0,7,0,108,0,168,1, -74,255,255,0,26,254,75,3,232,5,164,2,38,0,89,0,0,0,6,0,108,36,244,0,0,255,255, -0,66,255,235,4,200,7,13,2,38,0,210,0,0,0,7,0,102,0,132,1,93,255,255,0,26,254, -75,3,232,5,182,2,38,0,89,0,0,0,6,0,102,0,6,0,0,255,255,0,66,255,235,4,200,7, -75,2,38,0,210,0,0,0,7,0,159,1,54,1,93,255,255,0,26,254,75,3,252,5,244,2,38,0, -89,0,0,0,7,0,159,0,178,0,6,255,255,0,147,0,0,4,204,7,13,2,38,0,212,0,0,0,7,0, -102,0,174,1,93,255,255,0,115,0,0,3,220,5,182,2,38,0,236,0,0,0,6,0,102,38,6,0, -0,255,255,0,163,0,0,6,50,7,13,0,38,0,217,0,0,0,39,0,41,4,174,0,0,0,7,0,102,1, -105,1,93,255,255,0,153,0,0,5,172,5,182,0,38,0,241,0,0,0,39,0,136,4,78,0,0,0,7, -0,102,1,34,0,6,255,255,0,66,254,75,5,35,5,176,2,38,0,56,0,0,0,7,1,51,3,177,0, -0,255,255,0,46,254,75,4,62,4,58,2,38,0,88,0,0,0,7,1,51,2,204,0,0,255,255,0,98, -255,235,3,245,6,24,2,6,0,68,0,0,255,255,0,69,254,75,5,187,5,176,2,38,0,209,0, -0,0,7,1,51,4,73,0,0,255,255,0,65,254,75,4,192,4,58,2,38,0,229,0,0,0,7,1,51,3, -78,0,0,255,255,0,43,0,0,4,227,7,13,2,38,0,33,0,0,0,7,0,155,1,123,1,93,255,255, -0,106,255,235,3,243,5,203,2,38,0,65,0,0,0,7,0,155,1,30,0,27,255,255,0,43,0,0, -4,227,7,157,2,38,0,33,0,0,0,7,1,41,1,214,1,234,255,255,0,106,255,235,3,243,6, -91,2,38,0,65,0,0,0,7,1,41,1,121,0,168,255,255,0,43,0,0,5,11,7,241,2,38,0,33,0, -0,0,7,1,42,0,154,1,89,255,255,0,106,255,235,4,174,6,175,2,38,0,65,0,0,0,6,1, -42,61,23,0,0,255,255,0,0,0,0,4,227,7,224,2,38,0,33,0,0,0,7,1,43,0,171,1,72, -255,255,255,163,255,235,3,243,6,158,2,38,0,65,0,0,0,6,1,43,78,6,0,0,255,255,0, -43,0,0,4,227,8,5,2,38,0,33,0,0,0,7,1,44,0,163,1,52,255,255,0,106,255,235,4, -119,6,196,2,38,0,65,0,0,0,6,1,44,70,243,0,0,255,255,0,43,0,0,4,227,8,50,2,38, -0,33,0,0,0,7,1,45,0,167,1,54,255,255,0,106,255,235,3,243,6,241,2,38,0,65,0,0, -0,6,1,45,74,245,0,0,255,255,0,43,254,176,4,227,7,72,2,38,0,33,0,0,0,39,0,152, -0,171,1,93,0,7,0,155,1,112,249,201,255,255,0,106,254,176,3,243,6,6,2,38,0,65, -0,0,0,38,0,152,78,27,0,7,0,155,0,206,249,201,0,0,255,255,0,43,0,0,4,227,7,223, -2,38,0,33,0,0,0,7,1,46,0,210,1,84,255,255,0,106,255,235,3,243,6,157,2,38,0,65, -0,0,0,6,1,46,117,18,0,0,255,255,0,43,0,0,4,227,8,34,2,38,0,33,0,0,0,7,1,64,0, -214,1,122,255,255,0,106,255,235,3,243,6,224,2,38,0,65,0,0,0,6,1,64,121,56,0,0, -255,255,0,43,0,0,4,227,8,115,2,38,0,33,0,0,0,7,1,47,0,214,1,73,255,255,0,106, -255,235,3,243,7,49,2,38,0,65,0,0,0,6,1,47,121,7,0,0,255,255,0,43,0,0,4,227,8, -37,2,38,0,33,0,0,0,7,1,48,0,214,1,81,255,255,0,106,255,235,3,243,6,227,2,38,0, -65,0,0,0,6,1,48,121,15,0,0,255,255,0,43,254,176,4,227,7,78,2,38,0,33,0,0,0,39, -0,154,0,220,1,158,0,7,0,155,1,112,249,201,255,255,0,106,254,176,3,243,6,12,2, -38,0,65,0,0,0,38,0,154,127,92,0,7,0,155,0,206,249,201,0,0,255,255,0,163,0,0,4, -36,7,13,2,38,0,37,0,0,0,7,0,155,1,87,1,93,255,255,0,97,255,235,3,226,5,204,2, -38,0,69,0,0,0,7,0,155,1,32,0,28,255,255,0,163,0,0,4,36,7,157,2,38,0,37,0,0,0, -7,1,41,1,178,1,234,255,255,0,97,255,235,3,226,6,92,2,38,0,69,0,0,0,7,1,41,1, -123,0,169,255,255,0,163,0,0,4,36,7,84,2,38,0,37,0,0,0,7,0,158,0,130,1,97,255, -255,0,97,255,235,3,226,6,19,2,38,0,69,0,0,0,6,0,158,75,32,0,0,255,255,0,163,0, -0,4,231,7,241,2,38,0,37,0,0,0,7,1,42,0,118,1,89,255,255,0,97,255,235,4,176,6, -176,2,38,0,69,0,0,0,6,1,42,63,24,0,0,255,255,255,220,0,0,4,36,7,224,2,38,0,37, -0,0,0,7,1,43,0,135,1,72,255,255,255,165,255,235,3,226,6,159,2,38,0,69,0,0,0,6, -1,43,80,7,0,0,255,255,0,163,0,0,4,176,8,5,2,38,0,37,0,0,0,7,1,44,0,127,1,52, -255,255,0,97,255,235,4,121,6,197,2,38,0,69,0,0,0,6,1,44,72,244,0,0,255,255,0, -163,0,0,4,36,8,50,2,38,0,37,0,0,0,7,1,45,0,131,1,54,255,255,0,97,255,235,3, -226,6,242,2,38,0,69,0,0,0,6,1,45,76,246,0,0,255,255,0,163,254,186,4,36,7,72,2, -38,0,37,0,0,0,39,0,152,0,135,1,93,0,7,0,155,1,86,249,211,255,255,0,97,254,176, -3,226,6,7,2,38,0,69,0,0,0,38,0,152,80,28,0,7,0,155,1,86,249,201,0,0,255,255,0, -190,0,0,2,3,7,157,2,38,0,41,0,0,0,7,1,41,0,111,1,234,255,255,0,153,0,0,1,222, -6,70,2,38,0,136,0,0,0,7,1,41,0,74,0,147,255,255,0,180,0,0,1,142,7,13,2,38,0, -41,0,0,0,7,0,155,0,20,1,93,255,255,0,149,254,186,1,111,6,24,2,38,0,73,0,0,0,7, -0,155,255,245,249,211,255,255,0,113,255,235,5,2,7,34,2,38,0,47,0,0,0,7,0,155, -1,174,1,114,255,255,0,97,255,235,4,42,5,203,2,38,0,79,0,0,0,7,0,155,1,57,0,27, -255,255,0,113,255,235,5,2,7,178,2,38,0,47,0,0,0,7,1,41,2,9,1,255,255,255,0,97, -255,235,4,42,6,91,2,38,0,79,0,0,0,7,1,41,1,148,0,168,255,255,0,113,255,235,5, -62,8,6,2,38,0,47,0,0,0,7,1,42,0,205,1,110,255,255,0,97,255,235,4,201,6,175,2, -38,0,79,0,0,0,6,1,42,88,23,0,0,255,255,0,51,255,235,5,2,7,245,2,38,0,47,0,0,0, -7,1,43,0,222,1,93,255,255,255,190,255,235,4,42,6,158,2,38,0,79,0,0,0,6,1,43, -105,6,0,0,255,255,0,113,255,235,5,7,8,26,2,38,0,47,0,0,0,7,1,44,0,214,1,73, -255,255,0,97,255,235,4,146,6,196,2,38,0,79,0,0,0,6,1,44,97,243,0,0,255,255,0, -113,255,235,5,2,8,71,2,38,0,47,0,0,0,7,1,45,0,218,1,75,255,255,0,97,255,235,4, -42,6,241,2,38,0,79,0,0,0,6,1,45,101,245,0,0,255,255,0,113,254,167,5,2,7,93,2, -38,0,47,0,0,0,39,0,152,0,222,1,114,0,7,0,155,1,172,249,192,255,255,0,97,254, -166,4,42,6,6,2,38,0,79,0,0,0,38,0,152,105,27,0,7,0,155,1,56,249,191,0,0,255, -255,0,108,255,235,6,49,6,253,2,38,0,147,0,0,0,7,0,113,1,224,1,15,255,255,0,97, -255,235,4,242,6,30,2,38,0,148,0,0,0,7,0,113,1,107,0,48,255,255,0,108,255,235, -6,49,7,1,2,38,0,147,0,0,0,7,0,64,1,38,1,19,255,255,0,97,255,235,4,242,6,30,2, -38,0,148,0,0,0,7,0,113,1,107,0,48,255,255,0,108,255,235,6,49,7,83,2,38,0,147, -0,0,0,7,1,41,2,11,1,160,255,255,0,97,255,235,4,242,6,116,2,38,0,148,0,0,0,7,1, -41,1,150,0,193,255,255,0,108,255,235,6,49,7,10,2,38,0,147,0,0,0,7,0,158,0,219, -1,23,255,255,0,97,255,235,4,42,6,18,2,38,0,79,0,0,0,6,0,158,100,31,0,0,255, -255,0,108,255,235,6,49,6,195,2,38,0,147,0,0,0,7,0,155,1,176,1,19,255,255,0,97, -255,235,4,242,5,228,2,38,0,148,0,0,0,7,0,155,1,59,0,52,255,255,0,147,255,235, -4,220,7,13,2,38,0,53,0,0,0,7,0,155,1,172,1,93,255,255,0,139,255,235,3,252,5, -182,2,38,0,85,0,0,0,7,0,155,1,55,0,6,255,255,0,147,255,235,4,220,7,157,2,38,0, -53,0,0,0,7,1,41,2,7,1,234,255,255,0,139,255,235,3,252,6,70,2,38,0,85,0,0,0,7, -1,41,1,146,0,147,255,255,0,147,255,235,6,88,6,244,2,38,0,149,0,0,0,7,0,113,1, -202,1,6,255,255,0,139,255,235,5,106,5,253,2,38,0,150,0,0,0,7,0,113,1,88,0,15, -255,255,0,147,255,235,6,88,6,248,2,38,0,149,0,0,0,7,0,64,1,16,1,10,255,255,0, -139,255,235,5,106,6,1,2,38,0,150,0,0,0,7,0,64,0,158,0,19,255,255,0,147,255, -235,6,88,7,74,2,38,0,149,0,0,0,7,1,41,1,245,1,151,255,255,0,139,255,235,5,106, -6,83,2,38,0,150,0,0,0,7,1,41,1,131,0,160,255,255,0,147,255,235,6,88,7,1,2,38, -0,149,0,0,0,7,0,158,0,197,1,14,255,255,0,139,255,235,5,106,6,10,2,38,0,150,0, -0,0,6,0,158,83,23,0,0,255,255,0,147,255,235,6,88,6,186,2,38,0,149,0,0,0,7,0, -155,1,154,1,10,255,255,0,139,255,235,5,106,5,195,2,38,0,150,0,0,0,7,0,155,1, -40,0,19,255,255,0,40,0,0,4,226,7,12,2,38,0,57,0,0,0,7,0,155,1,121,1,92,255, -255,0,26,254,75,3,232,5,182,2,38,0,89,0,0,0,7,0,155,0,245,0,6,255,255,0,40,0, -0,4,226,7,156,2,38,0,57,0,0,0,7,1,41,1,212,1,233,255,255,0,26,254,75,3,232,6, -70,2,38,0,89,0,0,0,7,1,41,1,80,0,147,255,255,0,40,0,0,4,226,7,83,2,38,0,57,0, -0,0,7,0,158,0,164,1,96,255,255,0,26,254,75,3,232,5,253,2,38,0,89,0,0,0,6,0, -158,32,10,0,0,255,255,0,98,255,12,4,126,6,24,2,38,1,209,0,0,0,7,0,63,0,148, -255,166,255,255,0,163,254,210,5,58,5,176,2,38,0,43,0,0,0,7,1,49,4,21,0,0,255, -255,0,71,254,210,3,209,4,58,2,38,0,233,0,0,0,7,1,49,1,216,0,0,255,255,0,169, -254,210,5,135,5,176,2,38,0,40,0,0,0,7,1,49,4,98,0,0,255,255,0,143,254,210,4, -140,4,58,2,38,0,231,0,0,0,7,1,49,3,103,0,0,255,255,0,37,254,210,4,164,5,176,2, -38,0,52,0,0,0,7,1,49,2,48,0,0,255,255,0,71,254,210,3,209,4,58,2,38,0,233,0,0, -0,7,1,49,1,216,0,0,255,255,0,66,254,210,4,240,5,176,2,38,0,56,0,0,0,7,1,49,3, -203,0,0,255,255,0,46,254,210,4,11,4,58,2,38,0,88,0,0,0,7,1,49,2,230,0,0,255, -255,0,147,254,210,5,93,5,176,2,38,0,212,0,0,0,7,1,49,4,56,0,0,255,255,0,115, -254,210,4,109,4,58,2,38,0,236,0,0,0,7,1,49,3,72,0,0,255,255,0,147,254,210,4, -204,5,176,2,38,0,212,0,0,0,7,1,49,3,21,0,0,255,255,0,115,254,210,3,220,4,58,2, -38,0,236,0,0,0,7,1,49,2,36,0,0,255,255,0,163,254,210,4,32,5,176,2,38,0,168,0, -0,0,7,1,49,0,212,0,0,255,255,0,143,254,210,2,190,4,58,2,38,0,223,0,0,0,7,1,49, -0,177,0,0,255,255,0,26,254,210,6,195,5,176,2,38,0,206,0,0,0,7,1,49,5,158,0,0, -255,255,0,26,254,210,5,202,4,58,2,38,0,225,0,0,0,7,1,49,4,165,0,0,255,255,0, -77,254,98,6,44,5,195,2,38,1,127,0,0,0,7,0,157,2,108,0,0,255,255,255,223,254, -98,4,94,4,78,2,38,1,128,0,0,0,7,0,157,1,102,0,0,255,255,0,143,0,0,4,0,6,24,2, -6,0,72,0,0,0,2,255,156,0,0,4,0,4,58,0,18,0,27,0,0,1,33,21,33,50,22,21,20,6,35, -33,17,35,53,51,53,51,21,33,1,17,33,50,54,53,52,38,35,2,98,254,252,1,13,192, -213,215,190,254,46,253,253,197,1,4,254,252,1,13,106,101,102,105,3,31,129,184, -147,148,191,3,31,155,128,128,254,74,254,150,102,76,74,110,0,0,0,0,2,255,175,0, -0,4,187,5,176,0,18,0,27,0,0,1,33,21,33,50,4,21,20,4,35,33,17,35,53,51,53,51, -21,33,1,17,33,50,54,53,52,38,35,2,117,254,243,1,103,233,1,3,254,252,232,253, -212,244,244,197,1,13,254,243,1,103,147,148,147,148,4,77,221,239,197,198,246,4, -77,155,200,200,253,237,253,197,169,123,119,160,0,0,2,255,156,0,0,4,0,4,58,0, -18,0,27,0,0,1,33,21,33,50,22,21,20,6,35,33,17,35,53,51,53,51,21,33,1,17,33,50, -54,53,52,38,35,2,98,254,252,1,13,192,213,215,190,254,46,253,253,197,1,4,254, -252,1,13,106,101,102,105,3,31,129,184,147,148,191,3,31,155,128,128,254,74,254, -150,102,76,74,110,0,0,0,0,2,255,175,0,0,4,187,5,176,0,18,0,27,0,0,1,33,21,33, -50,4,21,20,4,35,33,17,35,53,51,53,51,21,33,1,17,33,50,54,53,52,38,35,2,117, -254,243,1,103,233,1,3,254,252,232,253,212,244,244,197,1,13,254,243,1,103,147, -148,147,148,4,77,221,239,197,198,246,4,77,155,200,200,253,237,253,197,169,123, -119,160,0,0,1,255,205,0,0,4,32,5,176,0,13,0,0,1,33,17,35,17,35,53,51,17,33,21, -33,17,33,2,147,254,213,197,214,214,3,125,253,72,1,43,2,169,253,87,2,169,155,2, -108,155,254,47,0,0,0,0,1,255,213,0,0,2,190,4,58,0,13,0,0,1,33,17,35,17,35,53, -51,17,33,21,33,17,33,2,155,254,185,197,186,186,2,47,254,150,1,71,1,220,254,36, -1,220,155,1,195,156,254,217,0,0,0,0,1,255,179,0,0,4,251,5,176,0,22,0,0,1,35, -17,35,17,35,53,51,53,51,21,33,21,33,17,51,1,51,23,9,1,7,35,1,251,147,197,240, -240,197,1,17,254,239,128,2,8,222,2,253,196,2,103,3,239,2,146,253,110,4,130, -155,147,147,155,254,170,2,132,5,253,80,253,10,5,0,0,1,255,157,0,0,4,11,6,24,0, -20,0,0,1,35,17,35,17,35,53,51,53,51,21,33,21,33,17,51,1,51,9,1,35,1,206,121, -197,243,243,197,1,14,254,242,119,1,49,236,254,137,1,153,233,1,243,254,13,4, -190,155,191,191,155,253,210,1,170,254,14,253,184,0,0,0,255,255,0,173,254,224, -5,133,7,78,2,38,0,208,0,0,0,39,0,154,1,42,1,158,0,7,1,110,4,30,255,179,255, -255,0,143,254,224,4,135,5,247,2,38,0,227,0,0,0,39,0,154,0,153,0,71,0,7,1,110, -3,32,255,179,255,255,0,169,254,224,5,129,5,176,2,38,0,40,0,0,0,7,1,110,4,26, -255,179,255,255,0,143,254,224,4,134,4,58,2,38,0,231,0,0,0,7,1,110,3,31,255, -179,255,255,0,163,254,224,6,204,5,176,2,38,0,45,0,0,0,7,1,110,5,101,255,179, -255,255,0,153,254,224,5,224,4,58,2,38,0,230,0,0,0,7,1,110,4,121,255,179,255, -255,0,65,254,224,4,135,4,58,2,38,0,229,0,0,0,7,1,110,3,32,255,179,255,255,0, -69,254,224,5,130,5,176,2,38,0,209,0,0,0,7,1,110,4,27,255,179,0,1,0,40,0,0,4, -226,5,176,0,15,0,0,9,1,51,1,51,21,35,7,17,35,17,33,53,51,1,51,2,133,1,124,225, -254,93,159,243,8,196,254,249,179,254,93,225,2,204,2,228,252,250,155,15,254,0, -2,15,155,3,6,0,0,0,1,0,46,254,95,3,228,4,58,0,17,0,0,5,33,17,35,17,35,53,51,1, -51,1,23,51,55,19,51,1,51,3,120,254,245,197,246,218,254,162,202,1,0,17,6,19, -249,201,254,166,238,13,254,108,1,148,155,3,172,253,5,76,76,2,251,252,84,0,1,0, -66,0,0,4,214,5,176,0,17,0,0,1,35,1,35,9,1,35,1,35,53,51,1,51,9,1,51,1,51,3, -252,211,1,173,235,254,163,254,162,238,1,173,185,171,254,107,236,1,82,1,84,238, -254,106,198,2,155,253,101,2,66,253,190,2,155,155,2,122,253,200,2,56,253,134,0, -0,0,0,1,0,46,0,0,3,212,4,58,0,17,0,0,1,35,1,35,11,1,35,1,35,53,51,1,51,27,1, -51,1,51,3,95,199,1,60,226,240,240,228,1,59,208,197,254,218,227,227,230,230, -254,217,188,1,222,254,34,1,153,254,103,1,222,155,1,193,254,113,1,143,254,63,0, -0,0,255,255,255,206,254,75,4,32,5,176,2,38,0,168,0,0,0,39,1,130,255,90,0,33,0, -7,1,51,1,153,0,0,255,255,255,214,254,75,2,190,4,58,2,38,0,223,0,0,0,39,1,130, -255,98,255,85,0,7,1,51,0,219,0,0,255,255,0,108,255,235,6,98,7,114,2,38,0,251, -0,0,0,7,0,255,1,43,1,118,255,255,0,127,255,235,5,210,5,252,2,38,0,252,0,0,0,7, -0,255,0,240,0,0,255,255,0,98,255,237,3,233,4,76,2,6,0,182,0,0,255,255,255,237, -0,0,4,52,5,176,2,38,0,38,0,0,0,7,1,130,255,121,254,127,255,255,0,187,2,136,5, -243,3,35,0,70,1,33,175,0,102,102,64,0,0,2,0,70,0,0,4,162,5,176,0,27,0,31,0,0, -1,35,3,35,19,35,53,33,19,33,53,33,19,51,3,51,19,51,3,51,21,35,3,51,21,35,3,35, -3,51,19,35,2,200,255,80,151,80,236,1,8,68,255,0,1,28,82,151,82,255,82,151,82, -199,226,68,219,247,80,152,147,255,68,255,1,154,254,102,1,154,140,1,92,142,1, -160,254,96,1,160,254,96,142,254,164,140,254,102,2,38,1,92,0,2,0,171,0,0,1,113, -5,176,0,3,0,7,0,0,1,35,17,51,19,35,53,51,1,112,197,197,1,198,198,1,222,3,210, -250,80,205,0,0,0,2,0,126,3,168,2,121,5,176,0,4,0,10,0,0,1,7,35,17,51,1,7,35, -55,17,51,2,121,101,97,198,254,203,101,97,1,197,4,162,250,2,8,254,242,250,240, -1,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,152,0,242,1,4,1,42,1,80,1,112,1,136,1, -152,1,166,1,178,1,192,1,238,1,254,2,42,2,104,2,136,2,188,2,252,3,24,3,96,3, -158,3,170,3,182,3,206,3,226,3,250,4,44,4,160,4,190,4,246,5,42,5,82,5,108,5, -130,5,184,5,208,5,220,5,250,6,26,6,42,6,76,6,102,6,154,6,190,6,250,7,50,7,112, -7,132,7,166,7,190,7,234,8,10,8,34,8,56,8,76,8,90,8,108,8,132,8,146,8,162,8, -226,9,22,9,68,9,120,9,174,9,210,10,20,10,54,10,72,10,108,10,136,10,148,10,204, -10,238,11,28,11,80,11,132,11,162,11,222,12,4,12,38,12,62,12,104,12,134,12,176, -12,198,12,246,13,4,13,50,13,92,13,104,13,158,13,212,14,32,14,74,14,94,14,198, -14,218,15,52,15,118,15,130,15,146,15,246,16,4,16,42,16,74,16,118,16,180,16, -196,16,234,17,2,17,16,17,44,17,60,17,102,17,114,17,132,17,150,17,168,17,178, -17,220,17,254,18,82,18,122,18,180,19,22,19,98,19,124,19,202,19,254,20,40,20, -52,20,84,20,112,20,136,20,180,20,230,21,36,21,136,21,182,21,210,22,8,22,72,22, -130,22,178,22,226,23,0,23,22,23,44,23,74,23,88,23,126,23,156,23,188,23,214,23, -224,23,236,23,248,24,0,24,12,24,26,24,52,24,60,24,78,24,102,24,162,24,184,24, -212,24,230,25,8,25,72,25,118,25,176,25,244,26,52,26,80,26,138,26,200,26,254, -27,32,27,86,27,116,27,172,27,240,28,24,28,74,28,128,28,180,28,200,28,238,29, -44,29,98,29,162,29,204,30,6,30,62,30,110,30,144,30,168,30,208,30,250,31,38,31, -102,31,128,31,160,31,202,31,226,32,0,32,26,32,56,32,96,32,140,32,176,32,232, -33,36,33,76,33,148,33,200,33,218,34,2,34,46,34,108,34,134,34,166,34,196,34, -228,34,252,35,14,35,34,35,124,35,148,35,176,35,202,35,232,36,16,36,60,36,96, -36,150,36,206,36,248,37,54,37,106,37,160,37,208,37,252,38,20,38,90,38,154,38, -234,39,52,39,72,39,102,39,118,39,134,39,182,39,230,39,240,39,250,40,10,40,26, -40,42,40,54,40,66,40,78,40,104,40,130,40,166,40,190,40,206,41,74,41,100,41, -126,41,140,41,172,41,234,42,42,42,86,42,104,42,122,42,140,42,158,42,216,42, -236,43,14,43,28,43,54,43,136,43,180,43,216,43,232,43,248,44,2,44,32,44,62,44, -90,44,134,44,180,44,216,45,14,45,68,45,82,45,112,45,140,45,172,45,188,45,232, -46,38,46,70,46,122,46,186,46,214,47,30,47,92,47,138,47,168,47,204,48,2,48,50, -48,86,48,112,48,134,48,184,48,208,48,220,48,250,49,26,49,42,49,74,49,100,49, -146,49,182,49,236,50,36,50,96,50,116,50,148,50,172,50,208,50,240,51,8,51,30, -51,74,51,90,51,134,51,196,51,228,52,22,52,82,52,110,52,182,52,242,53,28,53,44, -53,88,53,150,53,182,53,232,54,36,54,62,54,134,54,194,54,210,54,250,55,34,55, -80,55,122,55,166,55,208,55,248,56,32,56,74,56,116,56,174,56,184,56,212,56,240, -57,18,57,52,57,122,57,184,57,212,57,226,58,4,58,38,58,104,58,166,58,200,58, -238,59,36,59,88,59,146,59,204,60,8,60,62,60,110,60,156,60,212,61,38,61,106,61, -174,61,234,62,38,62,76,62,140,62,162,62,184,62,222,63,4,63,40,63,76,63,110,63, -150,63,190,64,16,64,96,64,142,64,190,64,204,65,8,65,72,65,88,65,156,65,216,65, -232,65,248,66,78,66,158,66,218,67,18,67,94,67,164,67,164,67,164,67,164,67,164, -67,164,67,164,67,164,67,164,67,164,67,164,67,164,68,126,68,196,68,208,69,28, -69,100,69,100,69,100,69,162,69,206,70,136,70,224,71,2,71,56,71,82,71,172,71, -188,71,250,72,60,72,122,72,134,72,142,72,150,72,200,72,250,73,38,73,66,73,74, -73,86,73,98,73,110,73,122,73,134,73,146,73,162,73,174,73,186,73,198,73,210,73, -222,73,234,73,246,74,2,74,14,74,26,74,38,74,50,74,62,74,74,74,86,74,98,74,110, -74,122,74,134,74,146,74,158,74,170,74,182,74,194,74,206,74,218,74,234,74,246, -75,2,75,14,75,26,75,38,75,50,75,62,75,74,75,86,75,98,75,110,75,122,75,134,75, -146,75,158,75,170,75,182,75,194,75,206,75,218,75,230,75,242,75,254,76,10,76, -22,76,34,76,46,76,58,76,70,76,82,76,94,76,106,76,118,76,130,76,142,76,154,76, -162,76,174,76,186,76,198,76,210,76,222,76,234,76,246,77,2,77,14,77,26,77,38, -77,50,77,62,77,74,77,86,77,98,77,110,77,122,77,134,77,146,77,158,77,170,77, -182,77,194,77,206,77,218,77,230,77,242,77,254,78,10,78,22,78,34,78,46,78,58, -78,70,78,82,78,94,78,106,78,118,78,126,78,134,78,146,78,158,78,170,78,182,78, -194,78,206,78,218,78,230,78,242,78,254,79,10,79,22,79,34,79,46,79,58,79,70,79, -82,79,94,79,106,79,118,79,130,79,142,79,154,79,166,79,178,79,190,79,202,79, -214,79,226,79,238,79,250,80,6,80,14,80,26,80,38,80,50,80,62,80,74,80,86,80,98, -80,110,80,122,80,134,80,146,80,158,80,170,80,182,80,194,80,206,80,218,80,230, -80,242,80,254,81,10,81,22,81,34,81,46,81,58,81,70,81,82,81,94,81,106,81,118, -81,130,81,142,81,154,81,166,81,178,81,190,81,202,81,210,81,218,81,226,81,234, -81,242,81,250,82,2,82,10,82,18,82,26,82,34,82,42,82,50,82,58,82,70,82,82,82, -94,82,106,82,118,82,130,82,142,82,150,82,158,82,166,82,174,82,186,82,198,82, -210,82,222,82,234,82,246,83,2,83,64,83,72,83,84,83,92,83,100,83,112,83,120,83, -128,83,136,83,144,83,152,83,164,83,172,83,180,83,188,83,196,83,204,83,212,83, -220,83,228,83,236,83,244,83,252,84,8,84,16,84,24,84,70,84,78,84,86,84,98,84, -110,84,118,84,126,84,138,84,146,84,158,84,170,84,182,84,194,84,206,84,218,84, -230,84,242,84,254,85,10,85,18,85,26,85,38,85,50,85,62,85,74,85,82,85,94,85, -106,85,118,85,130,85,142,85,158,85,174,85,186,85,198,85,210,85,222,85,230,85, -238,85,250,86,6,86,18,86,30,86,42,86,54,86,66,86,78,86,86,86,94,86,102,86,114, -86,126,86,134,86,146,86,158,86,170,86,182,86,190,86,198,86,210,86,222,86,234, -86,248,87,4,87,16,87,28,87,40,87,52,87,64,87,76,87,88,87,100,87,112,87,120,87, -128,87,140,87,152,87,164,87,176,87,188,87,200,87,212,87,224,87,236,87,248,88, -4,88,16,88,32,88,48,88,60,88,72,88,80,88,92,88,104,88,116,88,128,88,140,88, -152,88,164,88,176,88,188,88,200,88,212,88,224,88,236,88,248,89,8,89,24,89,36, -89,48,89,60,89,72,89,84,89,96,89,108,89,120,89,136,89,152,89,164,89,176,89, -188,89,200,89,212,89,224,89,236,89,248,90,4,90,16,90,28,90,40,90,52,90,64,90, -80,90,96,90,108,90,120,90,132,90,144,90,156,90,168,90,180,90,192,90,204,90, -216,90,228,90,240,90,252,91,8,91,20,91,32,91,48,91,64,91,76,91,88,91,100,91, -112,91,124,91,136,91,148,91,160,91,172,91,184,91,196,91,208,91,220,91,232,91, -244,92,0,92,12,92,24,92,36,92,48,92,60,92,72,92,84,92,96,92,108,92,120,92,132, -92,144,92,156,92,168,92,180,92,192,92,204,92,216,92,228,92,240,92,252,93,8,93, -20,93,32,93,44,93,56,93,68,93,80,93,92,93,104,93,116,93,128,93,140,93,148,93, -194,93,240,94,30,94,76,94,104,94,132,94,172,94,210,94,226,94,242,94,254,95,10, -95,22,95,34,95,46,95,58,95,90,95,124,95,164,95,202,95,218,95,234,95,246,96,2, -96,10,96,22,96,32,96,86,96,106,96,132,0,0,0,0,0,1,0,0,32,210,0,1,5,118,24,0,0, -10,8,196,0,8,0,42,255,162,0,8,0,54,0,40,0,8,0,55,0,37,0,8,0,57,0,45,0,16,0,16, -0,4,0,16,0,17,255,221,0,16,0,19,255,252,0,16,0,20,0,5,0,16,0,21,255,253,0,16, -0,22,0,4,0,16,0,23,255,213,0,16,0,25,0,6,0,17,0,18,255,250,0,17,0,19,255,250, -0,17,0,21,255,250,0,17,0,23,255,254,0,18,0,16,255,239,0,18,0,17,255,239,0,18, -0,18,0,8,0,18,0,21,255,242,0,18,0,22,255,239,0,18,0,23,255,233,0,18,0,24,255, -238,0,18,0,25,0,2,0,19,0,17,255,236,0,19,0,18,255,253,0,19,0,19,0,7,0,19,0,20, -0,15,0,19,0,21,0,4,0,19,0,22,255,253,0,19,0,23,255,228,0,19,0,24,0,5,0,19,0, -25,255,255,0,20,0,16,0,3,0,20,0,18,255,225,0,20,0,20,0,34,0,20,0,21,0,17,0,20, -0,22,0,3,0,20,0,23,255,173,0,20,0,24,0,19,0,21,0,17,255,252,0,21,0,18,255,234, -0,21,0,19,0,6,0,21,0,20,0,17,0,21,0,21,0,5,0,21,0,22,255,254,0,21,0,23,255, -253,0,21,0,24,0,6,0,21,0,25,255,229,0,22,0,16,0,2,0,22,0,17,255,217,0,22,0,18, -255,232,0,22,0,20,0,23,0,22,0,21,0,9,0,22,0,22,0,2,0,22,0,23,255,216,0,22,0, -24,0,11,0,23,0,17,0,36,0,23,0,20,255,94,0,23,0,21,255,225,0,23,0,22,255,217,0, -23,0,23,0,38,0,23,0,24,255,234,0,23,0,25,255,249,0,24,0,16,255,255,0,24,0,17, -255,234,0,24,0,19,0,11,0,24,0,20,0,20,0,24,0,21,0,8,0,24,0,22,255,255,0,25,0, -16,0,3,0,25,0,17,255,218,0,25,0,18,255,247,0,25,0,20,0,5,0,25,0,21,255,252,0, -25,0,22,0,3,0,25,0,23,255,209,0,25,0,25,0,5,0,33,0,35,255,218,0,33,0,39,255, -217,0,33,0,47,255,214,0,33,0,49,255,217,0,33,0,52,255,104,0,33,0,53,255,211,0, -33,0,54,255,108,0,33,0,55,255,157,0,33,0,57,255,93,0,33,0,65,0,5,0,33,0,67, -255,236,0,33,0,68,255,229,0,33,0,69,255,232,0,33,0,71,255,240,0,33,0,79,255, -232,0,33,0,81,255,240,0,33,0,83,0,3,0,33,0,84,255,192,0,33,0,85,255,233,0,33, -0,86,255,173,0,33,0,87,255,188,0,33,0,90,0,24,0,33,1,8,255,120,0,33,1,12,255, -120,0,33,1,66,255,236,0,33,1,70,255,233,0,33,1,78,255,233,0,33,1,80,255,236,0, -33,1,83,255,139,0,33,1,84,255,225,0,33,1,85,255,152,0,33,1,86,255,185,0,33,1, -88,255,133,0,34,0,57,255,93,0,34,0,65,0,10,0,34,0,73,255,252,0,34,0,76,255, -252,0,34,0,79,0,6,0,34,0,82,0,2,0,34,0,85,0,5,0,34,0,89,0,4,0,35,0,35,255,250, -0,35,0,39,255,250,0,35,0,47,255,247,0,35,0,49,255,250,0,35,0,73,255,244,0,35, -0,82,255,250,0,35,0,85,255,250,0,35,0,89,0,11,0,35,0,90,255,247,0,35,1,66,255, -250,0,35,1,70,255,249,0,35,1,78,255,249,0,35,1,80,255,250,0,36,0,54,255,213,0, -36,0,55,255,230,0,36,0,65,255,253,0,36,0,69,0,4,0,36,0,79,0,4,0,36,0,85,0,4,0, -37,0,54,0,17,0,37,0,55,0,16,0,37,0,57,0,18,0,37,0,66,255,245,0,37,0,67,255, -218,0,37,0,68,255,213,0,37,0,69,255,217,0,37,0,70,255,219,0,37,0,71,255,222,0, -37,0,73,255,246,0,37,0,74,255,249,0,37,0,75,255,248,0,37,0,76,255,246,0,37,0, -77,255,238,0,37,0,78,255,238,0,37,0,79,255,217,0,37,0,80,255,242,0,37,0,81, -255,222,0,37,0,82,255,240,0,37,0,84,255,212,0,37,0,85,255,222,0,37,0,86,255, -203,0,37,0,87,255,210,0,37,0,88,0,5,0,37,0,89,255,207,0,37,0,90,0,6,0,37,1,85, -255,224,0,37,1,86,255,218,0,37,1,88,255,223,0,38,0,12,254,205,0,38,0,14,254, -205,0,38,0,33,255,135,0,38,0,65,255,187,0,38,0,69,255,212,0,38,0,73,255,249,0, -38,0,76,255,247,0,38,0,79,255,212,0,38,0,82,255,203,0,38,0,85,255,210,0,38,0, -89,255,206,0,38,1,63,255,124,0,39,0,65,0,1,0,39,0,69,0,4,0,39,0,78,255,255,0, -39,0,79,0,1,0,39,0,82,0,2,0,39,0,85,0,1,0,39,0,89,0,1,0,40,0,65,255,250,0,40, -0,69,255,246,0,40,0,79,255,246,0,40,0,85,255,247,0,40,0,89,255,253,0,41,0,65, -255,248,0,41,0,67,255,248,0,41,0,68,255,238,0,41,0,70,255,244,0,41,0,71,255, -248,0,41,0,77,255,248,0,41,0,78,255,248,0,41,0,79,255,244,0,41,0,80,255,252,0, -41,0,82,255,248,0,41,0,83,255,248,0,41,0,84,255,247,0,41,0,85,255,248,0,41,0, -86,255,250,0,41,0,87,255,252,0,41,0,89,255,250,0,42,0,65,255,247,0,42,0,79, -255,247,0,43,0,35,255,200,0,43,0,39,255,196,0,43,0,47,255,193,0,43,0,49,255, -196,0,43,0,65,255,246,0,43,0,69,255,202,0,43,0,73,255,247,0,43,0,79,255,201,0, -43,0,82,255,248,0,43,0,85,255,208,0,43,0,87,255,177,0,43,0,89,255,175,0,43,1, -66,255,207,0,43,1,70,255,203,0,43,1,78,255,204,0,43,1,80,255,204,0,44,0,33,0, -39,0,44,0,35,255,213,0,44,0,39,255,209,0,44,0,47,255,205,0,44,0,49,255,209,0, -44,0,52,255,100,0,44,0,53,255,206,0,44,0,54,255,71,0,44,0,55,255,147,0,44,0, -57,255,79,0,44,0,74,255,254,0,44,0,85,255,227,0,44,0,87,255,170,0,44,0,89,255, -147,0,44,1,8,254,233,0,44,1,12,254,230,0,44,1,63,0,38,0,44,1,66,255,229,0,44, -1,70,255,225,0,44,1,78,255,227,0,44,1,80,255,227,0,44,1,83,255,118,0,44,1,84, -255,220,0,44,1,85,255,109,0,44,1,86,255,172,0,44,1,88,255,106,0,45,0,65,255, -249,0,45,0,69,255,245,0,45,0,74,255,248,0,45,0,78,255,249,0,45,0,79,255,245,0, -45,0,85,255,249,0,45,0,89,255,252,0,46,0,69,255,247,0,46,0,79,255,247,0,46,0, -89,255,253,0,47,0,33,255,214,0,47,0,52,255,201,0,47,0,54,255,211,0,47,0,55, -255,233,0,47,0,56,255,210,0,47,0,57,255,198,0,47,0,67,0,2,0,47,0,68,255,252,0, -47,0,69,0,2,0,47,0,70,0,1,0,47,0,71,0,2,0,47,0,74,255,245,0,47,0,79,0,2,0,47, -0,80,255,255,0,47,0,81,0,5,0,47,0,83,255,255,0,47,0,84,0,4,0,47,0,85,0,2,0,47, -0,88,255,244,0,47,0,89,0,7,0,47,0,90,255,241,0,47,1,63,255,215,0,47,1,85,255, -254,0,47,1,86,255,255,0,47,1,87,255,233,0,48,0,12,254,176,0,48,0,14,254,176,0, -48,0,33,255,146,0,48,0,37,255,250,0,48,0,40,255,250,0,48,0,41,255,250,0,48,0, -65,255,234,0,48,0,69,255,230,0,48,0,72,255,254,0,48,0,73,255,248,0,48,0,76, -255,250,0,48,0,78,255,250,0,48,0,79,255,230,0,48,0,82,255,252,0,48,0,83,255, -244,0,48,0,84,0,29,0,48,0,89,0,31,0,48,1,63,255,138,0,48,1,68,255,253,0,48,1, -71,255,253,0,48,1,72,255,253,0,49,0,33,0,28,0,49,0,52,255,188,0,49,0,53,255, -242,0,49,0,54,255,199,0,49,0,55,255,216,0,49,0,56,0,24,0,49,0,57,255,185,0,49, -0,65,255,255,0,49,0,85,255,252,0,49,1,63,0,28,0,49,1,83,255,244,0,49,1,84,255, -249,0,49,1,85,255,240,0,49,1,86,255,244,0,49,1,87,0,13,0,49,1,88,255,238,0,50, -0,35,255,245,0,50,0,39,255,245,0,50,0,47,255,242,0,50,0,49,255,245,0,50,0,52, -255,215,0,50,0,53,255,242,0,50,0,54,255,217,0,50,0,55,255,226,0,50,0,57,255, -158,0,50,0,65,255,252,0,50,0,69,255,241,0,50,0,79,255,241,0,50,0,85,255,248,0, -50,0,89,255,254,0,50,1,66,255,246,0,50,1,70,255,245,0,50,1,78,255,245,0,50,1, -80,255,245,0,50,1,83,255,253,0,50,1,84,255,245,0,50,1,86,255,248,0,51,0,65,0, -1,0,51,0,69,255,253,0,51,0,74,255,247,0,51,0,77,255,250,0,51,0,78,255,250,0, -51,0,79,255,253,0,51,0,80,255,254,0,51,0,81,255,255,0,51,0,85,255,254,0,51,0, -87,0,6,0,51,0,89,0,5,0,52,0,12,255,92,0,52,0,13,255,96,0,52,0,14,255,92,0,52, -0,26,255,102,0,52,0,27,255,100,0,52,0,33,255,94,0,52,0,35,255,204,0,52,0,39, -255,200,0,52,0,47,255,199,0,52,0,49,255,202,0,52,0,51,255,223,0,52,0,52,0,32, -0,52,0,54,0,32,0,52,0,55,0,31,0,52,0,56,0,21,0,52,0,57,0,33,0,52,0,65,255,97, -0,52,0,69,255,94,0,52,0,73,255,249,0,52,0,77,255,122,0,52,0,79,255,94,0,52,0, -82,255,122,0,52,0,83,255,101,0,52,0,85,255,122,0,52,0,87,255,159,0,52,0,89, -255,156,0,52,0,90,255,133,0,52,1,8,0,7,0,52,1,63,255,91,0,52,1,66,255,110,0, -52,1,70,255,110,0,52,1,78,255,110,0,52,1,80,255,110,0,52,1,82,255,117,0,52,1, -83,255,225,0,52,1,85,255,235,0,52,1,86,255,225,0,52,1,87,255,218,0,52,1,88, -255,236,0,53,0,33,255,211,0,53,0,68,255,240,0,53,0,70,255,252,0,53,0,71,255, -248,0,53,0,77,255,248,0,53,0,78,255,248,0,53,0,80,255,248,0,53,0,82,255,248,0, -53,0,83,255,244,0,53,0,84,255,255,0,53,0,88,255,241,0,53,0,90,255,237,0,53,1, -63,255,212,0,54,0,9,0,40,0,54,0,12,255,76,0,54,0,13,255,181,0,54,0,14,255,81, -0,54,0,26,255,193,0,54,0,27,255,193,0,54,0,33,255,103,0,54,0,35,255,213,0,54, -0,39,255,213,0,54,0,47,255,210,0,54,0,49,255,213,0,54,0,61,0,34,0,54,0,65,255, -161,0,54,0,69,255,165,0,54,0,79,255,161,0,54,0,82,255,194,0,54,0,85,255,198,0, -54,0,89,255,234,0,54,0,93,0,38,0,54,1,8,0,12,0,54,1,12,0,12,0,54,1,63,255,100, -0,54,1,66,255,177,0,54,1,70,255,177,0,54,1,78,255,177,0,54,1,80,255,177,0,55, -0,9,0,31,0,55,0,12,255,138,0,55,0,13,255,213,0,55,0,14,255,138,0,55,0,26,255, -212,0,55,0,27,255,211,0,55,0,33,255,147,0,55,0,35,255,228,0,55,0,39,255,228,0, -55,0,47,255,225,0,55,0,49,255,228,0,55,0,52,0,29,0,55,0,61,0,25,0,55,0,65,255, -189,0,55,0,69,255,193,0,55,0,79,255,193,0,55,0,82,255,213,0,55,0,85,255,217,0, -55,0,89,255,247,0,55,0,93,0,29,0,55,1,8,0,9,0,55,1,12,0,9,0,55,1,63,255,148,0, -55,1,66,255,209,0,55,1,70,255,205,0,55,1,78,255,205,0,55,1,80,255,205,0,55,1, -83,255,254,0,56,0,35,255,209,0,56,0,39,255,209,0,56,0,47,255,205,0,56,0,49, -255,209,0,56,0,69,255,203,0,56,0,85,255,212,0,56,0,89,255,192,0,56,1,8,255, -249,0,56,1,66,255,209,0,56,1,70,255,205,0,56,1,78,255,205,0,56,1,80,255,208,0, -57,0,9,0,41,0,57,0,12,255,69,0,57,0,13,255,150,0,57,0,14,255,69,0,57,0,26,255, -167,0,57,0,27,255,168,0,57,0,33,255,88,0,57,0,35,255,202,0,57,0,39,255,200,0, -57,0,47,255,196,0,57,0,49,255,200,0,57,0,52,0,34,0,57,0,54,0,36,0,57,0,55,0, -34,0,57,0,56,0,27,0,57,0,57,0,37,0,57,0,61,0,37,0,57,0,65,255,127,0,57,0,69, -255,122,0,57,0,79,255,122,0,57,0,81,255,131,0,57,0,84,255,210,0,57,0,85,255, -176,0,57,0,86,255,216,0,57,0,93,0,39,0,57,1,63,255,81,0,57,1,66,255,151,0,57, -1,70,255,147,0,57,1,78,255,147,0,57,1,80,255,147,0,57,1,83,255,230,0,57,1,85, -255,238,0,57,1,86,255,230,0,57,1,87,255,222,0,57,1,88,255,239,0,58,0,33,0,27, -0,58,0,35,255,209,0,58,0,39,255,205,0,58,0,47,255,202,0,58,0,49,255,205,0,58, -0,65,255,254,0,58,0,69,255,213,0,58,0,73,255,247,0,58,0,79,255,212,0,58,0,85, -255,218,0,58,0,87,255,200,0,58,0,89,255,201,0,58,1,63,0,27,0,58,1,66,255,218, -0,58,1,70,255,214,0,58,1,78,255,216,0,58,1,80,255,216,0,59,0,42,255,219,0,65, -1,8,255,225,0,65,1,12,255,225,0,66,0,86,255,233,0,66,0,87,255,240,0,66,0,89, -255,233,0,66,1,8,255,197,0,66,1,12,255,197,0,67,1,8,255,246,0,67,1,12,255,246, -0,68,1,8,255,247,0,68,1,12,255,247,0,69,0,89,255,230,0,69,1,8,255,227,0,69,1, -12,255,227,0,70,0,7,0,32,0,70,0,9,0,41,0,70,0,61,0,37,0,70,0,71,255,207,0,70, -0,93,0,39,0,70,1,8,0,32,0,70,1,12,0,32,0,70,3,177,0,28,0,71,1,8,255,247,0,71, -1,12,255,247,0,72,1,8,255,198,0,72,1,12,255,198,0,73,1,8,255,249,0,73,1,12, -255,249,0,75,0,69,255,215,0,76,1,8,255,245,0,76,1,12,255,245,0,77,1,8,255,220, -0,77,1,12,255,220,0,78,1,8,255,227,0,78,1,12,255,227,0,79,0,86,255,226,0,79,0, -87,255,237,0,79,0,88,255,214,0,79,0,89,255,226,0,79,1,8,255,216,0,79,1,12,255, -216,0,80,0,87,255,240,0,80,1,8,255,223,0,80,1,12,255,223,0,82,0,12,255,126,0, -82,0,14,255,126,0,82,0,67,255,218,0,82,0,68,255,220,0,82,0,69,255,218,0,82,0, -70,0,31,0,82,0,75,0,1,0,82,0,79,255,216,0,82,0,81,255,221,0,82,0,84,0,34,0,82, -0,85,0,1,0,82,0,86,0,36,0,82,0,87,0,35,0,82,0,88,0,18,0,82,0,89,0,36,0,82,0, -90,0,10,0,82,1,8,0,32,0,82,1,12,0,32,0,83,1,8,255,247,0,83,1,12,255,247,0,84, -1,8,255,249,0,84,1,12,255,249,0,85,1,8,255,248,0,85,1,12,255,248,0,86,0,12, -255,135,0,86,0,14,255,139,0,86,0,65,255,226,0,86,0,67,255,229,0,86,0,68,255, -229,0,86,0,69,255,229,0,86,0,79,255,225,0,86,0,81,255,229,0,86,1,8,0,34,0,86, -1,12,0,34,0,87,0,12,255,162,0,87,0,14,255,166,0,87,0,67,255,236,0,87,0,68,255, -236,0,87,0,69,255,232,0,87,0,81,255,236,0,88,0,67,255,215,0,88,0,68,255,219,0, -88,0,69,255,215,0,88,0,79,255,215,0,88,0,81,255,219,0,88,1,8,0,18,0,88,1,12,0, -18,0,89,0,12,255,118,0,89,0,14,255,128,0,89,0,67,255,223,0,89,0,68,255,223,0, -89,0,69,255,223,0,89,0,79,255,223,0,89,0,81,255,217,0,89,1,8,0,28,0,89,1,12,0, -28,0,90,0,67,255,223,0,90,0,68,255,226,0,90,0,69,255,223,0,90,0,79,255,223,0, -90,1,8,0,7,0,90,1,12,0,7,0,91,0,42,255,215,0,168,0,12,254,206,0,168,0,13,254, -204,0,168,0,14,254,210,0,168,0,35,255,199,0,168,0,39,255,197,0,168,0,47,255, -197,0,168,0,49,255,197,0,168,0,52,0,34,0,168,0,54,0,33,0,168,0,55,0,30,0,168, -0,57,0,33,0,168,0,105,254,208,0,168,0,120,254,210,0,168,0,127,255,195,0,168,0, -142,255,195,0,168,0,169,255,66,0,168,0,170,255,197,0,168,0,171,255,66,0,168,0, -175,255,108,0,168,0,178,254,244,0,168,0,180,254,241,0,168,0,181,255,223,0,168, -0,182,254,249,0,168,0,184,255,14,0,168,0,186,254,246,0,168,0,189,255,70,0,168, -0,190,254,237,0,168,0,191,254,240,0,168,0,192,254,231,0,168,0,193,255,92,0, -168,0,194,254,250,0,168,0,195,254,252,0,168,0,196,255,1,0,168,0,197,254,244,0, -168,1,5,254,207,0,168,1,6,254,207,0,170,0,12,255,217,0,170,0,14,255,226,0,170, -0,33,255,224,0,170,0,52,255,203,0,170,0,54,255,224,0,170,0,55,255,238,0,170,0, -56,255,216,0,170,0,57,255,206,0,170,0,58,255,219,0,170,0,125,255,206,0,170,0, -169,255,217,0,170,0,171,255,224,0,170,0,172,255,228,0,170,0,174,255,217,0,171, -0,7,255,115,0,171,0,31,255,140,0,171,0,33,0,36,0,171,0,35,255,219,0,171,0,39, -255,215,0,171,0,47,255,215,0,171,0,49,255,215,0,171,0,52,255,75,0,171,0,53, -255,212,0,171,0,54,255,113,0,171,0,55,255,156,0,171,0,57,255,85,0,171,0,67, -255,234,0,171,0,68,255,229,0,171,0,69,255,234,0,171,0,71,255,238,0,171,0,79, -255,234,0,171,0,81,255,238,0,171,0,85,255,235,0,171,0,125,0,38,0,171,0,127, -255,236,0,171,0,133,255,238,0,171,0,142,255,215,0,171,0,143,255,238,0,171,0, -169,0,38,0,171,0,170,255,215,0,171,0,175,255,202,0,171,0,176,255,156,0,171,0, -193,255,149,0,171,1,8,255,119,0,171,1,12,255,119,0,171,3,177,255,119,0,172,0, -170,255,225,0,172,0,187,0,27,0,174,0,7,255,246,0,174,0,35,255,211,0,174,0,39, -255,209,0,174,0,47,255,209,0,174,0,49,255,209,0,174,0,127,255,232,0,174,0,142, -255,205,0,174,0,170,255,209,0,174,0,175,255,151,0,174,0,187,0,36,0,174,1,8, -255,246,0,174,1,12,255,246,0,174,3,177,255,246,0,175,0,171,255,199,0,175,0, -187,255,193,0,176,0,12,255,84,0,176,0,14,255,88,0,176,0,171,255,157,0,176,0, -181,255,243,0,176,0,190,255,224,0,176,0,192,255,237,0,176,0,195,255,244,0,176, -0,197,255,240,0,178,0,187,0,34,0,180,0,7,0,32,0,180,0,70,0,29,0,180,0,181,255, -239,0,180,0,189,0,27,0,180,0,190,255,211,0,180,0,193,0,30,0,180,0,197,255,236, -0,180,1,8,0,32,0,180,1,12,0,32,0,180,3,177,0,32,0,181,0,193,255,225,0,182,0,7, -255,239,0,182,0,191,255,243,0,182,0,192,255,243,0,182,0,195,255,242,0,182,1,8, -255,244,0,182,1,12,255,244,0,182,3,177,255,240,0,183,0,178,255,209,0,183,0, -180,0,10,0,183,0,181,255,216,0,183,0,182,255,226,0,183,0,184,255,233,0,183,0, -186,255,237,0,183,0,187,0,11,0,183,0,188,255,223,0,183,0,189,0,14,0,183,0,191, -255,199,0,183,0,192,255,205,0,183,0,193,0,15,0,183,0,194,255,238,0,183,0,195, -255,219,0,183,0,196,255,239,0,183,0,197,255,217,0,184,0,7,255,217,0,184,1,8, -255,227,0,184,1,12,255,227,0,186,0,7,255,186,0,186,0,178,255,225,0,186,0,180, -255,191,0,186,0,185,255,217,0,186,0,186,255,239,0,186,0,187,0,37,0,186,0,189, -255,214,0,186,0,193,255,190,0,186,0,195,255,212,0,186,1,8,255,249,0,186,1,12, -255,249,0,186,3,177,255,184,0,187,0,7,255,58,0,187,0,70,255,209,0,187,0,180, -255,145,0,187,0,185,255,212,0,187,0,187,0,33,0,187,0,189,255,212,0,187,0,193, -255,125,0,187,1,8,255,63,0,187,1,12,255,63,0,187,3,177,255,58,0,188,0,178,255, -179,0,188,0,187,0,17,0,190,0,87,255,240,0,190,0,88,255,226,0,190,0,90,255,232, -0,190,0,193,255,215,0,190,1,8,255,223,0,190,1,12,255,223,0,192,0,180,0,17,0, -192,0,189,0,19,0,192,0,193,0,20,0,193,0,7,0,34,0,193,0,70,0,29,0,193,0,120, -255,233,0,193,0,180,0,27,0,193,0,181,255,223,0,193,0,189,0,29,0,193,0,191,255, -214,0,193,0,192,255,211,0,193,0,193,0,29,0,193,1,8,0,34,0,193,1,12,0,34,0,193, -1,63,255,122,0,193,1,66,255,220,0,193,1,70,255,216,0,193,1,78,255,218,0,193,1, -80,255,216,0,193,1,82,255,234,0,193,1,83,0,29,0,193,1,85,0,27,0,193,1,86,0,20, -0,193,1,87,0,8,0,193,1,88,0,27,0,193,3,177,0,34,0,195,0,88,255,220,0,195,0,90, -255,220,0,196,0,88,255,228,0,196,0,90,255,228,0,197,0,88,255,226,0,197,0,90, -255,226,0,197,0,180,255,234,0,198,0,7,255,170,0,198,0,198,255,185,0,198,0,202, -255,186,0,198,0,206,255,233,0,198,0,210,255,223,0,198,0,212,255,194,0,198,0, -215,255,188,0,198,0,233,255,164,0,198,0,236,255,239,0,198,0,239,255,200,0,198, -1,8,255,175,0,198,1,12,255,175,0,198,3,177,255,171,0,200,0,7,255,126,0,200,0, -202,255,67,0,200,0,206,255,232,0,200,0,209,255,243,0,200,0,210,255,220,0,200, -0,212,255,194,0,200,0,215,255,141,0,200,0,233,255,161,0,200,0,236,255,241,0, -200,0,239,255,201,0,200,1,8,255,146,0,200,1,12,255,146,0,200,3,177,255,135,0, -201,0,7,255,125,0,201,0,198,255,68,0,201,0,202,255,66,0,201,0,206,255,230,0, -201,0,210,255,219,0,201,0,212,255,193,0,201,0,215,255,140,0,201,0,233,255,159, -0,201,0,236,255,240,0,201,0,239,255,200,0,201,1,8,255,144,0,201,1,12,255,144, -0,201,3,177,255,134,0,202,0,198,255,181,0,202,0,202,255,179,0,202,0,215,255, -184,0,202,0,233,255,158,0,202,0,236,255,225,0,202,0,239,255,194,0,204,0,198, -255,206,0,204,0,210,255,225,0,204,0,212,255,202,0,204,0,215,255,208,0,204,0, -225,255,227,0,204,0,233,255,168,0,204,0,236,255,242,0,204,0,239,255,204,0,205, -0,198,255,196,0,205,0,200,0,40,0,205,0,202,255,197,0,205,0,205,0,46,0,205,0, -209,0,40,0,205,0,212,255,197,0,205,0,215,255,199,0,205,0,224,0,44,0,205,0,229, -0,40,0,205,0,236,255,196,0,205,0,247,0,40,0,205,0,253,255,213,0,206,0,13,255, -141,0,206,0,199,255,206,0,206,0,200,0,36,0,206,0,209,0,36,0,206,0,221,255,210, -0,206,0,229,0,37,0,206,0,233,255,181,0,206,0,236,255,161,0,206,0,247,0,37,0, -206,0,253,255,206,0,207,0,17,255,236,0,207,0,18,255,253,0,207,0,19,0,7,0,207, -0,20,0,15,0,207,0,21,0,4,0,207,0,22,255,253,0,207,0,23,255,228,0,207,0,24,0,5, -0,207,0,25,255,255,0,207,0,207,0,11,0,207,0,209,255,239,0,207,0,210,255,236,0, -207,0,215,255,228,0,208,0,65,255,252,0,208,0,69,255,255,0,208,0,79,255,252,0, -208,0,85,255,255,0,208,0,89,0,2,0,210,0,7,0,15,0,210,0,13,255,177,0,210,0,14, -255,135,0,210,0,67,255,229,0,210,0,68,255,229,0,210,0,69,255,229,0,210,0,79, -255,229,0,210,0,81,255,225,0,210,0,199,255,210,0,210,0,200,255,138,0,210,0, -205,255,53,0,210,0,209,255,138,0,210,0,215,0,36,0,210,0,222,255,187,0,210,0, -223,255,187,0,210,0,224,255,69,0,210,0,227,255,187,0,210,0,228,255,187,0,210, -0,229,255,116,0,210,0,230,255,187,0,210,0,231,255,187,0,210,0,232,255,187,0, -210,0,234,255,154,0,210,0,235,255,187,0,210,0,236,255,207,0,210,0,237,255,187, -0,210,0,238,255,185,0,210,0,240,255,187,0,210,0,241,255,187,0,210,0,243,255, -185,0,210,0,244,255,172,0,210,0,246,255,150,0,210,0,247,255,116,0,210,0,248, -255,187,0,210,0,250,255,187,0,210,0,254,255,153,0,210,1,8,0,31,0,210,1,12,0, -31,0,210,3,177,0,13,0,211,0,200,0,39,0,211,0,205,0,96,0,211,0,209,0,49,0,211, -0,212,255,195,0,211,0,224,0,104,0,211,0,229,0,58,0,211,0,236,255,194,0,211,0, -247,0,39,0,214,0,198,255,218,0,214,0,200,0,42,0,214,0,205,0,48,0,214,0,209,0, -42,0,214,0,210,0,22,0,214,0,212,255,218,0,214,0,215,255,219,0,214,0,218,255, -242,0,214,0,224,0,45,0,214,0,229,0,40,0,214,0,233,255,223,0,214,0,236,255,217, -0,214,0,239,255,225,0,214,0,247,0,40,0,215,0,7,255,124,0,215,0,198,255,65,0, -215,0,202,255,63,0,215,0,212,255,190,0,215,0,215,255,137,0,215,0,233,255,158, -0,215,0,239,255,198,0,215,1,8,255,139,0,215,1,12,255,139,0,215,3,177,255,133, -0,217,0,7,255,131,0,217,0,198,255,69,0,217,0,202,255,67,0,217,0,212,255,194,0, -217,0,215,255,141,0,217,0,233,255,164,0,217,0,239,255,200,0,217,1,8,255,145,0, -217,1,12,255,145,0,217,3,177,255,135,0,218,0,198,255,206,0,218,0,200,255,207, -0,218,0,202,255,205,0,218,0,205,255,202,0,218,0,206,255,207,0,218,0,209,255, -207,0,218,0,210,255,217,0,218,0,229,255,214,0,218,0,247,255,214,0,219,0,198, -255,202,0,219,0,200,255,206,0,219,0,202,255,202,0,219,0,205,255,203,0,219,0, -206,255,207,0,219,0,209,255,206,0,219,0,210,255,217,0,219,0,224,255,203,0,219, -0,229,255,214,0,219,0,247,255,214,0,220,0,35,255,250,0,220,0,39,255,250,0,220, -0,47,255,253,0,220,0,49,255,250,0,220,0,52,255,214,0,220,0,53,255,249,0,220,0, -54,255,236,0,220,0,55,255,243,0,220,0,57,255,229,0,220,0,69,255,252,0,220,0, -79,255,250,0,220,0,85,255,253,0,220,0,89,0,6,0,220,1,66,255,253,0,220,1,70, -255,249,0,220,1,78,255,249,0,220,1,80,255,249,0,220,1,83,0,1,0,220,1,84,255, -253,0,220,1,85,0,1,0,220,1,88,0,1,0,221,0,224,255,225,0,221,0,225,255,224,0, -221,0,233,255,223,0,221,0,239,255,241,0,222,0,7,255,191,0,222,0,225,255,237,0, -222,0,233,255,230,0,222,0,236,255,238,0,222,0,239,255,235,0,222,1,8,255,230,0, -222,1,12,255,230,0,222,3,177,255,190,0,223,0,224,255,132,0,223,0,229,255,171, -0,223,0,246,255,211,0,223,0,247,255,171,0,224,0,224,0,42,0,224,0,233,255,219, -0,224,0,236,255,216,0,224,0,239,255,223,0,225,0,7,0,11,0,225,0,234,255,236,0, -225,0,236,255,245,0,225,0,246,255,218,0,225,0,254,255,220,0,225,1,8,0,11,0, -225,1,12,0,11,0,225,3,177,0,11,0,226,0,7,255,232,0,226,0,233,255,237,0,226,0, -236,255,240,0,226,1,8,255,236,0,226,1,12,255,236,0,226,3,177,255,232,0,228,0, -221,255,233,0,228,0,234,255,224,0,228,0,236,255,242,0,228,0,246,255,211,0,228, -0,254,255,213,0,228,1,8,0,12,0,228,1,12,0,12,0,228,1,66,255,212,0,228,1,70, -255,208,0,228,1,78,255,212,0,228,1,80,255,212,0,233,0,7,0,34,0,233,0,70,0,29, -0,233,0,224,255,133,0,233,0,229,255,172,0,233,0,234,255,223,0,233,0,246,255, -211,0,233,0,247,255,172,0,233,0,254,255,213,0,233,1,8,0,31,0,233,1,12,0,31,0, -233,1,63,255,122,0,233,1,66,255,220,0,233,1,70,255,216,0,233,1,78,255,218,0, -233,1,80,255,216,0,233,1,82,255,234,0,233,1,83,0,29,0,233,1,85,0,27,0,233,1, -86,0,20,0,233,1,87,0,8,0,233,1,88,0,27,0,233,3,177,0,34,0,234,0,88,255,244,0, -234,0,90,255,244,0,234,0,225,255,236,0,234,0,229,255,246,0,234,0,233,255,229, -0,234,0,239,255,237,0,234,0,247,255,246,0,235,0,224,0,37,0,235,0,229,0,32,0, -235,0,233,255,222,0,235,0,236,255,220,0,235,0,239,255,224,0,235,0,247,0,32,0, -238,0,224,0,43,0,238,0,229,0,38,0,238,0,233,255,206,0,238,0,236,255,203,0,238, -0,239,255,215,0,238,0,242,255,242,0,238,0,246,255,224,0,238,0,247,0,38,0,239, -0,233,255,122,0,239,0,236,255,203,0,239,0,239,255,178,0,241,0,7,254,253,0,241, -0,233,255,118,0,241,0,236,255,202,0,241,0,239,255,174,0,241,1,8,255,35,0,241, -1,12,255,39,0,241,3,177,255,10,0,242,0,224,255,218,0,242,0,225,255,218,0,242, -0,229,255,225,0,242,0,239,255,222,0,242,0,247,255,225,0,243,0,224,255,217,0, -243,0,225,255,217,0,243,0,226,255,245,0,243,0,229,255,223,0,243,0,239,255,232, -0,246,0,7,255,240,0,246,1,8,255,244,0,246,1,12,255,244,0,246,3,177,255,240,0, -247,0,225,255,232,0,247,0,233,255,116,0,247,0,234,0,11,0,247,0,236,255,200,0, -247,0,239,255,172,0,248,0,225,255,236,0,248,0,233,255,121,0,248,0,236,255,203, -0,248,0,239,255,177,1,7,0,33,255,120,1,7,0,52,0,12,1,7,0,54,0,16,1,7,0,55,0, -18,1,7,0,57,0,9,1,7,0,65,255,225,1,7,0,67,255,217,1,7,0,68,255,197,1,7,0,69, -255,217,1,7,0,70,0,5,1,7,0,71,255,222,1,7,0,77,255,247,1,7,0,78,255,247,1,7,0, -79,255,217,1,7,0,81,255,222,1,7,0,83,255,237,1,7,0,84,0,11,1,7,0,85,255,254,1, -7,0,86,0,36,1,7,0,87,0,32,1,7,0,88,0,18,1,7,0,89,0,36,1,7,0,90,0,8,1,7,1,7, -255,241,1,8,0,68,255,172,1,8,0,77,255,243,1,8,0,82,255,247,1,8,0,83,255,216,1, -8,0,84,0,6,1,8,0,86,0,27,1,8,1,8,255,245,1,11,0,33,255,118,1,11,0,52,0,9,1,11, -0,54,0,10,1,11,0,55,0,12,1,11,0,57,0,7,1,11,0,65,255,223,1,11,0,67,255,215,1, -11,0,68,255,191,1,11,0,69,255,215,1,11,0,71,255,215,1,11,0,77,255,245,1,11,0, -78,255,245,1,11,0,79,255,211,1,11,0,80,255,249,1,11,0,81,255,219,1,11,0,82, -255,245,1,11,0,83,255,230,1,11,0,84,0,4,1,11,0,85,255,252,1,11,0,86,0,27,1,11, -0,87,0,23,1,11,0,88,0,12,1,11,0,89,0,27,1,11,0,90,0,3,1,63,1,66,255,227,1,63, -1,70,255,227,1,63,1,78,255,227,1,63,1,80,255,227,1,63,1,83,255,125,1,63,1,84, -255,216,1,63,1,85,255,139,1,63,1,86,255,175,1,63,1,88,255,123,1,66,1,66,255, -254,1,66,1,70,255,254,1,66,1,78,255,254,1,66,1,80,255,254,1,67,1,85,255,220,1, -67,1,86,255,234,1,68,1,85,0,4,1,68,1,88,0,4,1,69,1,63,255,162,1,74,1,66,255, -212,1,74,1,70,255,208,1,74,1,78,255,212,1,74,1,80,255,212,1,75,1,63,0,35,1,75, -1,66,255,224,1,75,1,70,255,220,1,75,1,78,255,222,1,75,1,80,255,223,1,75,1,83, -255,115,1,75,1,84,255,215,1,75,1,85,255,107,1,75,1,86,255,167,1,75,1,88,255, -101,1,78,1,63,255,229,1,78,1,83,255,219,1,78,1,85,255,225,1,78,1,86,255,239,1, -78,1,87,255,215,1,78,1,88,255,211,1,79,1,63,255,168,1,79,1,68,255,245,1,79,1, -71,255,245,1,79,1,72,255,245,1,80,1,63,0,13,1,80,1,83,255,208,1,80,1,84,255, -246,1,80,1,85,255,213,1,80,1,86,255,226,1,80,1,88,255,201,1,81,1,66,255,252,1, -81,1,70,255,252,1,81,1,78,255,252,1,81,1,80,255,252,1,81,1,83,255,228,1,81,1, -84,255,245,1,81,1,85,255,226,1,81,1,86,255,233,1,81,1,88,255,219,1,83,1,63, -255,122,1,83,1,66,255,220,1,83,1,70,255,216,1,83,1,78,255,218,1,83,1,80,255, -216,1,83,1,82,255,234,1,83,1,83,0,29,1,83,1,85,0,27,1,83,1,86,0,20,1,83,1,87, -0,8,1,83,1,88,0,27,1,84,1,63,255,221,1,85,1,63,255,140,1,85,1,66,255,228,1,85, -1,70,255,224,1,85,1,78,255,224,1,85,1,80,255,224,1,86,1,63,255,182,1,86,1,66, -255,239,1,86,1,70,255,239,1,86,1,78,255,239,1,86,1,80,255,239,1,86,1,83,0,28, -1,87,1,66,255,218,1,87,1,70,255,214,1,87,1,78,255,214,1,87,1,80,255,214,1,88, -1,63,255,124,1,88,1,66,255,217,1,88,1,70,255,213,1,88,1,78,255,213,1,88,1,80, -255,213,1,88,1,83,0,31,1,88,1,85,0,33,1,88,1,86,0,27,1,88,1,87,0,14,1,88,1,88, -0,33,1,89,1,63,0,25,1,89,1,66,255,224,1,89,1,70,255,224,1,89,1,78,255,224,1, -89,1,80,255,224,1,111,0,9,0,40,1,111,0,12,255,76,1,111,0,13,255,181,1,111,0, -14,255,81,1,111,0,26,255,193,1,111,0,27,255,193,1,111,0,33,255,103,1,111,0,35, -255,213,1,111,0,39,255,213,1,111,0,47,255,210,1,111,0,49,255,213,1,111,0,61,0, -34,1,111,0,65,255,161,1,111,0,69,255,165,1,111,0,79,255,161,1,111,0,82,255, -194,1,111,0,85,255,198,1,111,0,89,255,234,1,111,0,93,0,38,1,111,1,8,0,12,1, -111,1,12,0,12,1,111,1,63,255,100,1,111,1,66,255,177,1,111,1,70,255,177,1,111, -1,78,255,177,1,111,1,80,255,177,1,112,0,12,255,135,1,112,0,14,255,139,1,112,0, -65,255,226,1,112,0,67,255,229,1,112,0,68,255,229,1,112,0,69,255,229,1,112,0, -79,255,225,1,112,0,81,255,229,1,112,1,8,0,34,1,112,1,12,0,34,1,113,0,35,255, -253,1,113,0,39,255,253,1,113,0,47,255,254,1,113,0,49,255,253,1,113,0,65,0,8,1, -113,0,73,255,247,1,113,0,82,255,255,1,113,0,85,255,252,1,113,0,89,0,16,1,113, -0,90,0,2,1,114,1,8,255,234,1,114,1,12,255,234,1,137,0,65,255,250,1,137,0,69, -255,246,1,137,0,79,255,246,1,137,0,85,255,247,1,137,0,89,255,253,1,141,0,35, -255,250,1,141,0,39,255,250,1,141,0,47,255,247,1,141,0,49,255,250,1,141,0,73, -255,244,1,141,0,82,255,250,1,141,0,85,255,250,1,141,0,89,0,11,1,141,0,90,255, -247,1,141,1,66,255,250,1,141,1,70,255,249,1,141,1,78,255,249,1,141,1,80,255, -250,1,142,1,8,255,246,1,142,1,12,255,246,0,0,0,0,0,22,1,14,0,1,0,0,0,0,0,0,0, -31,0,0,0,1,0,0,0,0,0,1,0,6,0,31,0,1,0,0,0,0,0,2,0,7,0,37,0,1,0,0,0,0,0,3,0,18, -0,44,0,1,0,0,0,0,0,4,0,14,0,62,0,1,0,0,0,0,0,5,0,21,0,76,0,1,0,0,0,0,0,6,0,14, -0,97,0,1,0,0,0,0,0,7,0,32,0,111,0,1,0,0,0,0,0,9,0,6,0,143,0,1,0,0,0,0,0,11,0, -10,0,149,0,1,0,0,0,0,0,12,0,19,0,159,0,3,0,1,4,9,0,0,0,62,0,178,0,3,0,1,4,9,0, -1,0,12,0,240,0,3,0,1,4,9,0,2,0,14,0,252,0,3,0,1,4,9,0,3,0,36,1,10,0,3,0,1,4,9, -0,4,0,28,1,46,0,3,0,1,4,9,0,5,0,42,1,74,0,3,0,1,4,9,0,6,0,28,1,116,0,3,0,1,4, -9,0,7,0,64,1,144,0,3,0,1,4,9,0,9,0,12,1,208,0,3,0,1,4,9,0,11,0,20,1,220,0,3,0, -1,4,9,0,12,0,38,1,240,70,111,110,116,32,100,97,116,97,32,99,111,112,121,114, -105,103,104,116,32,71,111,111,103,108,101,32,50,48,49,49,82,111,98,111,116, -111,82,101,103,117,108,97,114,71,111,111,103,108,101,58,82,111,98,111,116,111, -58,50,48,49,49,82,111,98,111,116,111,32,82,101,103,117,108,97,114,86,101,114, -115,105,111,110,32,49,46,48,48,48,48,48,59,32,50,48,49,49,82,111,98,111,116, -111,45,82,101,103,117,108,97,114,82,111,98,111,116,111,32,105,115,32,97,32, -116,114,97,100,101,109,97,114,107,32,111,102,32,71,111,111,103,108,101,46,71, -111,111,103,108,101,71,111,111,103,108,101,46,99,111,109,67,104,114,105,115, -116,105,97,110,32,82,111,98,101,114,116,115,111,110,0,70,0,111,0,110,0,116,0, -32,0,100,0,97,0,116,0,97,0,32,0,99,0,111,0,112,0,121,0,114,0,105,0,103,0,104, -0,116,0,32,0,71,0,111,0,111,0,103,0,108,0,101,0,32,0,50,0,48,0,49,0,49,0,82,0, -111,0,98,0,111,0,116,0,111,0,82,0,101,0,103,0,117,0,108,0,97,0,114,0,71,0,111, -0,111,0,103,0,108,0,101,0,58,0,82,0,111,0,98,0,111,0,116,0,111,0,58,0,50,0,48, -0,49,0,49,0,82,0,111,0,98,0,111,0,116,0,111,0,32,0,82,0,101,0,103,0,117,0,108, -0,97,0,114,0,86,0,101,0,114,0,115,0,105,0,111,0,110,0,32,0,49,0,46,0,48,0,48, -0,48,0,48,0,48,0,59,0,32,0,50,0,48,0,49,0,49,0,82,0,111,0,98,0,111,0,116,0, -111,0,45,0,82,0,101,0,103,0,117,0,108,0,97,0,114,0,82,0,111,0,98,0,111,0,116, -0,111,0,32,0,105,0,115,0,32,0,97,0,32,0,116,0,114,0,97,0,100,0,101,0,109,0,97, -0,114,0,107,0,32,0,111,0,102,0,32,0,71,0,111,0,111,0,103,0,108,0,101,0,46,0, -71,0,111,0,111,0,103,0,108,0,101,0,71,0,111,0,111,0,103,0,108,0,101,0,46,0,99, -0,111,0,109,0,67,0,104,0,114,0,105,0,115,0,116,0,105,0,97,0,110,0,32,0,82,0, -111,0,98,0,101,0,114,0,116,0,115,0,111,0,110,0,2,0,0,0,0,0,0,255,106,0,100,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,178,0,0,1,2,0,2,0,3,0,7,0,8,0,9,0,10, -0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0, -26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41, -0,42,0,43,0,44,0,45,0,46,0,47,0,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0, -57,0,58,0,59,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72, -0,73,0,74,0,75,0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0, -88,0,89,0,90,0,91,0,92,0,93,0,94,0,95,0,96,0,97,0,163,0,132,0,133,0,189,0,150, -0,232,0,134,0,142,0,139,0,157,0,169,0,164,0,138,1,3,0,131,0,147,0,242,0,243,0, -141,0,151,0,136,1,4,0,222,0,241,0,158,0,170,0,245,0,244,0,246,0,162,0,144,0, -240,0,145,0,237,0,137,0,160,0,234,0,184,0,161,0,238,1,5,0,215,1,6,0,226,0,227, -1,7,1,8,0,176,0,177,1,9,1,10,0,166,1,11,1,12,1,13,1,14,1,15,0,216,0,225,0,219, -0,220,0,221,0,224,0,217,0,223,1,16,1,17,1,18,1,19,1,20,1,21,1,22,1,23,1,24,1, -25,1,26,1,27,1,28,1,29,1,30,1,31,1,32,0,159,1,33,1,34,1,35,1,36,1,37,1,38,1, -39,1,40,1,41,1,42,1,43,0,155,1,44,1,45,1,46,1,47,1,48,1,49,1,50,1,51,1,52,1, -53,1,54,1,55,1,56,1,57,1,58,1,59,1,60,1,61,1,62,1,63,1,64,1,65,1,66,1,67,1,68, -1,69,1,70,1,71,1,72,1,73,1,74,1,75,1,76,1,77,1,78,1,79,1,80,1,81,1,82,1,83,1, -84,1,85,1,86,1,87,1,88,1,89,1,90,1,91,1,92,1,93,1,94,1,95,1,96,1,97,1,98,1,99, -1,100,1,101,1,102,1,103,1,104,1,105,1,106,1,107,1,108,1,109,1,110,1,111,1,112, -1,113,1,114,0,178,0,179,0,182,0,183,0,196,1,115,0,180,0,181,0,197,0,130,0,194, -0,135,0,171,0,198,0,190,0,191,0,188,1,116,1,117,1,118,0,140,1,119,1,120,1,121, -1,122,0,152,0,154,0,153,0,239,0,165,0,146,0,156,0,143,0,148,0,149,1,123,1,124, -1,125,1,126,1,127,1,128,1,129,1,130,1,131,1,132,1,133,1,134,1,135,1,136,1,137, -1,138,1,139,1,140,1,141,1,142,1,143,1,144,1,145,1,146,1,147,1,148,1,149,1,150, -1,151,1,152,1,153,1,154,1,155,1,156,1,157,1,158,1,159,1,160,1,161,1,162,1,163, -1,164,1,165,1,166,1,167,1,168,1,169,1,170,1,171,1,172,1,173,1,174,1,175,1,176, -1,177,1,178,1,179,1,180,1,181,1,182,1,183,1,184,1,185,1,186,1,187,1,188,1,189, -1,190,1,191,1,192,1,193,1,194,1,195,1,196,1,197,1,198,1,199,1,200,1,201,1,202, -1,203,1,204,1,205,1,206,1,207,1,208,1,209,1,210,1,211,1,212,1,213,1,214,1,215, -1,216,1,217,1,218,1,219,1,220,1,221,1,222,1,223,1,224,1,225,1,226,1,227,1,228, -1,229,1,230,1,231,1,232,1,233,1,234,1,235,1,236,1,237,0,185,1,238,1,239,1,240, -1,241,1,242,1,243,1,244,1,245,1,246,1,247,1,248,1,249,1,250,1,251,1,252,1,253, -1,254,1,255,2,0,2,1,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,2,13,2,14, -2,15,2,16,2,17,2,18,2,19,2,20,2,21,2,22,2,23,2,24,2,25,2,26,2,27,2,28,2,29,2, -30,2,31,2,32,2,33,2,34,2,35,2,36,2,37,0,172,2,38,0,233,2,39,2,40,2,41,0,173,0, -201,0,199,0,174,0,98,0,99,2,42,0,100,0,203,0,101,0,200,0,202,0,207,0,204,0, -205,0,206,0,102,0,211,0,208,0,209,0,175,0,103,0,214,0,212,0,213,0,104,0,235,0, -106,0,105,0,107,0,109,0,108,0,110,2,43,0,111,0,113,0,112,0,114,0,115,0,117,0, -116,0,118,0,119,0,120,0,122,0,121,0,123,0,125,0,124,0,127,0,126,0,128,0,129,0, -236,0,186,2,44,2,45,2,46,2,47,2,48,2,49,0,253,0,254,2,50,2,51,2,52,2,53,0,255, -1,0,2,54,2,55,2,56,2,57,2,58,2,59,2,60,2,61,2,62,2,63,2,64,2,65,2,66,2,67,0, -248,0,249,2,68,2,69,2,70,2,71,2,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,2,80,2, -81,2,82,2,83,2,84,2,85,2,86,2,87,2,88,2,89,2,90,2,91,2,92,2,93,2,94,2,95,2,96, -2,97,2,98,2,99,2,100,2,101,2,102,2,103,2,104,2,105,2,106,2,107,2,108,2,109,2, -110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,0,251,0,252,0,228,0, -229,2,120,2,121,2,122,2,123,2,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,2, -132,2,133,2,134,2,135,2,136,2,137,2,138,2,139,0,187,2,140,2,141,2,142,2,143,0, -230,0,231,2,144,2,145,2,146,2,147,2,148,2,149,2,150,2,151,2,152,2,153,2,154,2, -155,2,156,2,157,2,158,2,159,2,160,2,161,2,162,2,163,2,164,2,165,2,166,2,167,2, -168,2,169,2,170,2,171,2,172,2,173,2,174,2,175,2,176,2,177,2,178,2,179,2,180,2, -181,2,182,2,183,2,184,2,185,2,186,2,187,2,188,2,189,2,190,2,191,2,192,2,193,2, -194,2,195,2,196,2,197,2,198,2,199,2,200,2,201,2,202,2,203,2,204,2,205,2,206,2, -207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,2,215,2,216,2,217,2,218,2,219,2, -220,2,221,2,222,2,223,2,224,2,225,2,226,2,227,2,228,2,229,2,230,2,231,2,232,2, -233,2,234,2,235,2,236,2,237,2,238,2,239,2,240,2,241,2,242,2,243,2,244,2,245,2, -246,2,247,2,248,2,249,2,250,2,251,2,252,2,253,2,254,2,255,3,0,3,1,3,2,3,3,3,4, -3,5,3,6,3,7,3,8,3,9,3,10,3,11,3,12,3,13,3,14,3,15,3,16,3,17,3,18,3,19,3,20,3, -21,3,22,3,23,3,24,3,25,3,26,3,27,3,28,3,29,3,30,3,31,3,32,3,33,3,34,3,35,3,36, -3,37,3,38,3,39,3,40,3,41,3,42,3,43,3,44,3,45,3,46,3,47,3,48,3,49,3,50,3,51,3, -52,3,53,3,54,3,55,3,56,3,57,3,58,3,59,3,60,3,61,3,62,3,63,3,64,3,65,3,66,3,67, -3,68,3,69,3,70,3,71,3,72,3,73,3,74,3,75,3,76,3,77,3,78,3,79,3,80,3,81,3,82,3, -83,3,84,3,85,3,86,3,87,3,88,3,89,3,90,3,91,3,92,3,93,3,94,3,95,3,96,3,97,3,98, -3,99,3,100,3,101,3,102,3,103,3,104,3,105,3,106,3,107,3,108,3,109,3,110,3,111, -3,112,3,113,3,114,3,115,3,116,3,117,3,118,3,119,3,120,3,121,3,122,3,123,3,124, -3,125,3,126,3,127,3,128,3,129,3,130,3,131,3,132,3,133,3,134,3,135,3,136,3,137, -3,138,3,139,3,140,3,141,3,142,3,143,3,144,3,145,3,146,3,147,3,148,3,149,3,150, -3,151,3,152,3,153,3,154,3,155,3,156,3,157,3,158,3,159,3,160,3,161,3,162,3,163, -3,164,3,165,3,166,3,167,3,168,3,169,3,170,3,171,3,172,3,173,3,174,3,175,3,176, -3,177,3,178,3,179,3,180,3,181,3,182,3,183,3,184,3,185,3,186,0,247,3,187,0,6,0, -4,0,5,5,46,110,117,108,108,6,109,97,99,114,111,110,14,112,101,114,105,111,100, -99,101,110,116,101,114,101,100,4,72,98,97,114,12,107,103,114,101,101,110,108, -97,110,100,105,99,3,69,110,103,3,101,110,103,4,116,98,97,114,5,108,111,110, -103,115,5,79,104,111,114,110,5,111,104,111,114,110,5,85,104,111,114,110,5,117, -104,111,114,110,7,117,110,105,48,50,51,55,7,117,110,105,48,50,70,51,9,103,114, -97,118,101,99,111,109,98,9,97,99,117,116,101,99,111,109,98,9,116,105,108,100, -101,99,111,109,98,7,117,110,105,48,51,48,70,5,116,111,110,111,115,13,100,105, -101,114,101,115,105,115,116,111,110,111,115,9,97,110,111,116,101,108,101,105, -97,5,71,97,109,109,97,5,68,101,108,116,97,5,84,104,101,116,97,6,76,97,109,98, -100,97,2,88,105,2,80,105,5,83,105,103,109,97,3,80,104,105,3,80,115,105,5,97, -108,112,104,97,4,98,101,116,97,5,103,97,109,109,97,5,100,101,108,116,97,7,101, -112,115,105,108,111,110,4,122,101,116,97,3,101,116,97,5,116,104,101,116,97,4, -105,111,116,97,6,108,97,109,98,100,97,2,120,105,3,114,104,111,6,115,105,103, -109,97,49,5,115,105,103,109,97,3,116,97,117,7,117,112,115,105,108,111,110,3, -112,104,105,3,112,115,105,5,111,109,101,103,97,7,117,110,105,48,52,48,50,7, -117,110,105,48,52,48,52,7,117,110,105,48,52,48,57,7,117,110,105,48,52,48,65,7, -117,110,105,48,52,48,66,7,117,110,105,48,52,48,70,7,117,110,105,48,52,49,49,7, -117,110,105,48,52,49,52,7,117,110,105,48,52,49,54,7,117,110,105,48,52,49,55,7, -117,110,105,48,52,49,56,7,117,110,105,48,52,49,66,7,117,110,105,48,52,50,51,7, -117,110,105,48,52,50,54,7,117,110,105,48,52,50,55,7,117,110,105,48,52,50,56,7, -117,110,105,48,52,50,57,7,117,110,105,48,52,50,65,7,117,110,105,48,52,50,66,7, -117,110,105,48,52,50,67,7,117,110,105,48,52,50,68,7,117,110,105,48,52,50,69,7, -117,110,105,48,52,50,70,7,117,110,105,48,52,51,49,7,117,110,105,48,52,51,50,7, -117,110,105,48,52,51,51,7,117,110,105,48,52,51,52,7,117,110,105,48,52,51,54,7, -117,110,105,48,52,51,55,7,117,110,105,48,52,51,56,7,117,110,105,48,52,51,65,7, -117,110,105,48,52,51,66,7,117,110,105,48,52,51,67,7,117,110,105,48,52,51,68,7, -117,110,105,48,52,51,70,7,117,110,105,48,52,52,50,7,117,110,105,48,52,52,52,7, -117,110,105,48,52,52,54,7,117,110,105,48,52,52,55,7,117,110,105,48,52,52,56,7, -117,110,105,48,52,52,57,7,117,110,105,48,52,52,65,7,117,110,105,48,52,52,66,7, -117,110,105,48,52,52,67,7,117,110,105,48,52,52,68,7,117,110,105,48,52,52,69,7, -117,110,105,48,52,52,70,7,117,110,105,48,52,53,50,7,117,110,105,48,52,53,52,7, -117,110,105,48,52,53,57,7,117,110,105,48,52,53,65,7,117,110,105,48,52,53,66,7, -117,110,105,48,52,53,70,7,117,110,105,48,52,54,48,7,117,110,105,48,52,54,49,7, -117,110,105,48,52,55,50,7,117,110,105,48,52,55,51,7,117,110,105,48,52,56,51,7, -117,110,105,48,52,56,52,7,117,110,105,48,52,56,53,7,117,110,105,48,52,56,54,7, -117,110,105,48,52,69,48,7,117,110,105,48,52,69,49,13,113,117,111,116,101,114, -101,118,101,114,115,101,100,7,117,110,105,50,48,55,52,4,108,105,114,97,4,69, -117,114,111,9,111,110,101,101,105,103,104,116,104,12,116,104,114,101,101,101, -105,103,104,116,104,115,11,102,105,118,101,101,105,103,104,116,104,115,12,115, -101,118,101,110,101,105,103,104,116,104,115,8,100,111,116,98,101,108,111,119, -4,104,111,111,107,19,99,105,114,99,117,109,102,108,101,120,97,99,117,116,101, -99,111,109,98,19,99,105,114,99,117,109,102,108,101,120,103,114,97,118,101,99, -111,109,98,18,99,105,114,99,117,109,102,108,101,120,104,111,111,107,99,111, -109,98,19,99,105,114,99,117,109,102,108,101,120,116,105,108,100,101,99,111, -109,98,14,98,114,101,118,101,97,99,117,116,101,99,111,109,98,13,98,114,101, -118,101,104,111,111,107,99,111,109,98,14,98,114,101,118,101,116,105,108,100, -101,99,111,109,98,11,99,121,114,105,108,108,105,99,116,105,99,16,99,121,114, -105,108,108,105,99,104,111,111,107,108,101,102,116,12,99,121,114,105,108,108, -105,99,104,111,111,107,14,108,97,114,103,101,114,105,103,104,116,104,111,111, -107,8,111,110,101,46,108,110,117,109,8,116,119,111,46,108,110,117,109,10,116, -104,114,101,101,46,108,110,117,109,9,102,111,117,114,46,108,110,117,109,9,102, -105,118,101,46,108,110,117,109,8,115,105,120,46,108,110,117,109,10,115,101, -118,101,110,46,108,110,117,109,10,101,105,103,104,116,46,108,110,117,109,9, -110,105,110,101,46,108,110,117,109,9,122,101,114,111,46,108,110,117,109,6,65, -46,115,109,99,112,14,98,114,101,118,101,103,114,97,118,101,99,111,109,98,6,66, -46,115,109,99,112,6,67,46,115,109,99,112,6,68,46,115,109,99,112,6,69,46,115, -109,99,112,6,70,46,115,109,99,112,6,71,46,115,109,99,112,6,72,46,115,109,99, -112,6,73,46,115,109,99,112,6,74,46,115,109,99,112,6,75,46,115,109,99,112,6,76, -46,115,109,99,112,6,77,46,115,109,99,112,6,78,46,115,109,99,112,6,79,46,115, -109,99,112,6,80,46,115,109,99,112,6,81,46,115,109,99,112,6,82,46,115,109,99, -112,6,83,46,115,109,99,112,6,84,46,115,109,99,112,6,85,46,115,109,99,112,6,86, -46,115,109,99,112,6,87,46,115,109,99,112,6,88,46,115,109,99,112,6,89,46,115, -109,99,112,6,90,46,115,109,99,112,9,122,101,114,111,46,115,109,99,112,8,111, -110,101,46,115,109,99,112,8,116,119,111,46,115,109,99,112,10,116,104,114,101, -101,46,115,109,99,112,9,102,111,117,114,46,115,109,99,112,9,102,105,118,101, -46,115,109,99,112,8,115,105,120,46,115,109,99,112,10,115,101,118,101,110,46, -115,109,99,112,10,101,105,103,104,116,46,115,109,99,112,9,110,105,110,101,46, -115,109,99,112,8,122,101,114,111,46,115,117,112,7,111,110,101,46,115,117,112, -7,116,119,111,46,115,117,112,9,116,104,114,101,101,46,115,117,112,8,102,111, -117,114,46,115,117,112,8,102,105,118,101,46,115,117,112,7,115,105,120,46,115, -117,112,9,115,101,118,101,110,46,115,117,112,9,101,105,103,104,116,46,115,117, -112,8,110,105,110,101,46,115,117,112,11,99,111,109,109,97,97,99,99,101,110, -116,7,117,110,105,48,52,55,52,7,117,110,105,48,52,55,53,7,117,110,105,48,52, -56,48,7,117,110,105,48,52,56,49,7,117,110,105,48,52,67,51,7,117,110,105,48,52, -67,52,7,117,110,105,48,52,57,52,7,117,110,105,48,52,57,53,7,117,110,105,48,52, -65,54,7,117,110,105,48,52,65,55,7,117,110,105,48,52,68,56,7,117,110,105,48,52, -68,57,7,117,110,105,48,52,65,52,7,117,110,105,48,52,65,53,7,117,110,105,48,52, -66,52,7,117,110,105,48,52,66,53,7,117,110,105,48,52,66,67,7,117,110,105,48,52, -66,68,7,117,110,105,48,52,66,65,8,99,114,111,115,115,98,97,114,7,117,110,105, -48,52,65,48,7,117,110,105,48,52,65,49,7,117,110,105,48,52,54,52,7,117,110,105, -48,52,54,53,7,117,110,105,48,52,54,54,7,117,110,105,48,52,54,55,7,117,110,105, -48,53,48,65,7,117,110,105,48,53,48,66,7,117,110,105,48,53,48,57,7,117,110,105, -48,53,48,56,7,117,110,105,48,53,48,67,7,117,110,105,48,53,48,68,7,117,110,105, -48,53,48,69,7,117,110,105,48,53,48,70,7,117,110,105,48,53,48,50,7,117,110,105, -48,53,48,51,7,117,110,105,48,53,48,52,7,117,110,105,48,53,48,53,7,117,110,105, -48,53,48,54,7,117,110,105,48,53,48,55,7,117,110,105,48,53,48,48,7,117,110,105, -48,53,49,48,7,117,110,105,48,52,57,48,7,117,110,105,48,52,57,49,7,117,110,105, -48,52,57,67,7,117,110,105,48,52,57,68,7,117,110,105,48,52,66,56,7,117,110,105, -48,52,66,57,7,117,110,105,48,52,67,56,7,117,110,105,48,52,67,55,7,117,110,105, -48,52,54,69,7,117,110,105,48,52,54,70,7,117,110,105,48,52,54,56,7,117,110,105, -48,52,54,57,7,117,110,105,48,52,56,69,7,117,110,105,48,52,56,70,3,99,104,105, -17,99,111,109,109,97,97,99,99,101,110,116,114,111,116,97,116,101,7,117,110, -105,48,51,68,54,7,117,110,105,48,51,68,50,7,117,110,105,48,52,55,65,7,117,110, -105,48,52,55,66,7,117,110,105,48,52,55,69,7,117,110,105,48,52,55,70,7,117,110, -105,48,52,54,65,7,117,110,105,48,52,54,66,7,117,110,105,48,52,54,67,7,117,110, -105,48,52,54,68,7,117,110,105,50,48,48,48,7,117,110,105,50,48,48,49,7,117,110, -105,50,48,48,50,7,117,110,105,50,48,48,51,7,117,110,105,50,48,48,52,7,117,110, -105,50,48,48,53,7,117,110,105,50,48,48,54,7,117,110,105,50,48,48,55,7,117,110, -105,50,48,48,56,7,117,110,105,50,48,48,57,7,117,110,105,50,48,48,65,7,117,110, -105,70,70,70,67,7,117,110,105,70,70,70,68,13,117,110,100,101,114,115,99,111, -114,101,100,98,108,7,117,110,105,48,52,65,56,7,117,110,105,48,52,65,57,7,117, -110,105,50,48,48,66,7,117,110,105,70,69,70,70,7,117,110,105,48,51,68,49,7,117, -110,105,48,52,56,50,7,117,110,105,48,52,56,56,7,117,110,105,48,52,56,57,9,110, -115,117,112,101,114,105,111,114,9,101,115,116,105,109,97,116,101,100,9,100,97, -115,105,97,111,120,105,97,7,117,110,105,50,49,48,53,7,117,110,105,50,49,49,54, -7,117,110,105,50,49,49,51,6,112,101,115,101,116,97,6,100,99,114,111,97,116,7, -117,110,105,50,48,50,53,13,99,121,114,105,108,108,105,99,98,114,101,118,101,6, -68,99,114,111,97,116,4,104,98,97,114,4,84,98,97,114,7,117,110,105,48,48,65,68, -10,65,114,105,110,103,97,99,117,116,101,10,97,114,105,110,103,97,99,117,116, -101,7,65,109,97,99,114,111,110,7,97,109,97,99,114,111,110,6,65,98,114,101,118, -101,6,97,98,114,101,118,101,7,65,111,103,111,110,101,107,7,97,111,103,111,110, -101,107,11,67,99,105,114,99,117,109,102,108,101,120,11,99,99,105,114,99,117, -109,102,108,101,120,4,67,100,111,116,4,99,100,111,116,6,68,99,97,114,111,110, -6,100,99,97,114,111,110,7,69,109,97,99,114,111,110,7,101,109,97,99,114,111, -110,6,69,98,114,101,118,101,6,101,98,114,101,118,101,10,69,100,111,116,97,99, -99,101,110,116,10,101,100,111,116,97,99,99,101,110,116,7,69,111,103,111,110, -101,107,7,101,111,103,111,110,101,107,6,69,99,97,114,111,110,6,101,99,97,114, -111,110,11,71,99,105,114,99,117,109,102,108,101,120,11,103,99,105,114,99,117, -109,102,108,101,120,4,71,100,111,116,4,103,100,111,116,12,71,99,111,109,109, -97,97,99,99,101,110,116,12,103,99,111,109,109,97,97,99,99,101,110,116,11,72, -99,105,114,99,117,109,102,108,101,120,11,104,99,105,114,99,117,109,102,108, -101,120,6,73,116,105,108,100,101,6,105,116,105,108,100,101,7,73,109,97,99,114, -111,110,7,105,109,97,99,114,111,110,6,73,98,114,101,118,101,6,105,98,114,101, -118,101,7,73,111,103,111,110,101,107,7,105,111,103,111,110,101,107,10,73,100, -111,116,97,99,99,101,110,116,2,73,74,2,105,106,11,74,99,105,114,99,117,109, -102,108,101,120,11,106,99,105,114,99,117,109,102,108,101,120,12,75,99,111,109, -109,97,97,99,99,101,110,116,12,107,99,111,109,109,97,97,99,99,101,110,116,6, -76,97,99,117,116,101,6,108,97,99,117,116,101,12,76,99,111,109,109,97,97,99,99, -101,110,116,12,108,99,111,109,109,97,97,99,99,101,110,116,6,76,99,97,114,111, -110,6,108,99,97,114,111,110,4,76,100,111,116,4,108,100,111,116,6,78,97,99,117, -116,101,6,110,97,99,117,116,101,12,78,99,111,109,109,97,97,99,99,101,110,116, -12,110,99,111,109,109,97,97,99,99,101,110,116,6,78,99,97,114,111,110,6,110,99, -97,114,111,110,11,110,97,112,111,115,116,114,111,112,104,101,7,79,109,97,99, -114,111,110,7,111,109,97,99,114,111,110,6,79,98,114,101,118,101,6,111,98,114, -101,118,101,13,79,104,117,110,103,97,114,117,109,108,97,117,116,13,111,104, -117,110,103,97,114,117,109,108,97,117,116,6,82,97,99,117,116,101,6,114,97,99, -117,116,101,12,82,99,111,109,109,97,97,99,99,101,110,116,12,114,99,111,109, -109,97,97,99,99,101,110,116,6,82,99,97,114,111,110,6,114,99,97,114,111,110,6, -83,97,99,117,116,101,6,115,97,99,117,116,101,11,83,99,105,114,99,117,109,102, -108,101,120,11,115,99,105,114,99,117,109,102,108,101,120,12,84,99,111,109,109, -97,97,99,99,101,110,116,12,116,99,111,109,109,97,97,99,99,101,110,116,6,84,99, -97,114,111,110,6,116,99,97,114,111,110,6,85,116,105,108,100,101,6,117,116,105, -108,100,101,7,85,109,97,99,114,111,110,7,117,109,97,99,114,111,110,6,85,98, -114,101,118,101,6,117,98,114,101,118,101,5,85,114,105,110,103,5,117,114,105, -110,103,13,85,104,117,110,103,97,114,117,109,108,97,117,116,13,117,104,117, -110,103,97,114,117,109,108,97,117,116,7,85,111,103,111,110,101,107,7,117,111, -103,111,110,101,107,11,87,99,105,114,99,117,109,102,108,101,120,11,119,99,105, -114,99,117,109,102,108,101,120,11,89,99,105,114,99,117,109,102,108,101,120,11, -121,99,105,114,99,117,109,102,108,101,120,6,90,97,99,117,116,101,6,122,97,99, -117,116,101,10,90,100,111,116,97,99,99,101,110,116,10,122,100,111,116,97,99, -99,101,110,116,7,65,69,97,99,117,116,101,7,97,101,97,99,117,116,101,11,79,115, -108,97,115,104,97,99,117,116,101,11,111,115,108,97,115,104,97,99,117,116,101, -12,83,99,111,109,109,97,97,99,99,101,110,116,12,115,99,111,109,109,97,97,99, -99,101,110,116,10,65,108,112,104,97,116,111,110,111,115,12,69,112,115,105,108, -111,110,116,111,110,111,115,8,69,116,97,116,111,110,111,115,9,73,111,116,97, -116,111,110,111,115,12,79,109,105,99,114,111,110,116,111,110,111,115,12,85, -112,115,105,108,111,110,116,111,110,111,115,10,79,109,101,103,97,116,111,110, -111,115,17,105,111,116,97,100,105,101,114,101,115,105,115,116,111,110,111,115, -5,65,108,112,104,97,4,66,101,116,97,7,69,112,115,105,108,111,110,4,90,101,116, -97,3,69,116,97,4,73,111,116,97,5,75,97,112,112,97,2,77,117,2,78,117,7,79,109, -105,99,114,111,110,3,82,104,111,3,84,97,117,7,85,112,115,105,108,111,110,3,67, -104,105,12,73,111,116,97,100,105,101,114,101,115,105,115,15,85,112,115,105, -108,111,110,100,105,101,114,101,115,105,115,10,97,108,112,104,97,116,111,110, -111,115,12,101,112,115,105,108,111,110,116,111,110,111,115,8,101,116,97,116, -111,110,111,115,9,105,111,116,97,116,111,110,111,115,20,117,112,115,105,108, -111,110,100,105,101,114,101,115,105,115,116,111,110,111,115,5,107,97,112,112, -97,7,111,109,105,99,114,111,110,7,117,110,105,48,51,66,67,2,110,117,12,105, -111,116,97,100,105,101,114,101,115,105,115,15,117,112,115,105,108,111,110,100, -105,101,114,101,115,105,115,12,111,109,105,99,114,111,110,116,111,110,111,115, -12,117,112,115,105,108,111,110,116,111,110,111,115,10,111,109,101,103,97,116, -111,110,111,115,7,117,110,105,48,52,48,49,7,117,110,105,48,52,48,51,7,117,110, -105,48,52,48,53,7,117,110,105,48,52,48,54,7,117,110,105,48,52,48,55,7,117,110, -105,48,52,48,56,7,117,110,105,48,52,48,67,7,117,110,105,48,52,48,69,7,117,110, -105,48,52,49,65,7,117,110,105,48,52,49,48,7,117,110,105,48,52,49,50,7,117,110, -105,48,52,49,51,7,117,110,105,48,52,49,53,7,117,110,105,48,52,49,57,7,117,110, -105,48,52,49,67,7,117,110,105,48,52,49,68,7,117,110,105,48,52,49,69,7,117,110, -105,48,52,49,70,7,117,110,105,48,52,50,48,7,117,110,105,48,52,50,49,7,117,110, -105,48,52,50,50,7,117,110,105,48,52,50,52,7,117,110,105,48,52,50,53,7,117,110, -105,48,52,51,48,7,117,110,105,48,52,51,53,7,117,110,105,48,52,51,57,7,117,110, -105,48,52,51,69,7,117,110,105,48,52,52,48,7,117,110,105,48,52,52,49,7,117,110, -105,48,52,52,51,7,117,110,105,48,52,52,53,7,117,110,105,48,52,53,49,7,117,110, -105,48,52,53,51,7,117,110,105,48,52,53,53,7,117,110,105,48,52,53,54,7,117,110, -105,48,52,53,55,7,117,110,105,48,52,53,56,7,117,110,105,48,52,53,67,7,117,110, -105,48,52,53,69,6,87,103,114,97,118,101,6,119,103,114,97,118,101,6,87,97,99, -117,116,101,6,119,97,99,117,116,101,9,87,100,105,101,114,101,115,105,115,9, -119,100,105,101,114,101,115,105,115,6,89,103,114,97,118,101,6,121,103,114,97, -118,101,6,109,105,110,117,116,101,6,115,101,99,111,110,100,9,101,120,99,108, -97,109,100,98,108,7,117,110,105,70,66,48,49,7,117,110,105,70,66,48,50,7,117, -110,105,48,49,70,48,7,117,110,105,48,50,66,67,7,117,110,105,49,69,51,69,7,117, -110,105,49,69,51,70,7,117,110,105,49,69,48,48,7,117,110,105,49,69,48,49,7,117, -110,105,49,70,52,68,7,117,110,105,70,66,48,51,7,117,110,105,70,66,48,52,7,117, -110,105,48,52,48,48,7,117,110,105,48,52,48,68,7,117,110,105,48,52,53,48,7,117, -110,105,48,52,53,68,7,117,110,105,48,52,55,48,7,117,110,105,48,52,55,49,7,117, -110,105,48,52,55,54,7,117,110,105,48,52,55,55,7,117,110,105,48,52,55,57,7,117, -110,105,48,52,55,56,7,117,110,105,48,52,57,56,7,117,110,105,48,52,57,57,7,117, -110,105,48,52,65,65,7,117,110,105,48,52,65,66,7,117,110,105,48,52,65,69,7,117, -110,105,48,52,65,70,7,117,110,105,48,52,67,48,7,117,110,105,48,52,67,49,7,117, -110,105,48,52,67,50,7,117,110,105,48,52,67,70,7,117,110,105,48,52,68,48,7,117, -110,105,48,52,68,49,7,117,110,105,48,52,68,50,7,117,110,105,48,52,68,51,7,117, -110,105,48,52,68,52,7,117,110,105,48,52,68,53,7,117,110,105,48,52,68,54,7,117, -110,105,48,52,68,55,7,117,110,105,48,52,68,65,7,117,110,105,48,52,68,66,7,117, -110,105,48,52,68,67,7,117,110,105,48,52,68,68,7,117,110,105,48,52,68,69,7,117, -110,105,48,52,68,70,7,117,110,105,48,52,69,50,7,117,110,105,48,52,69,51,7,117, -110,105,48,52,69,52,7,117,110,105,48,52,69,53,7,117,110,105,48,52,69,54,7,117, -110,105,48,52,69,55,7,117,110,105,48,52,69,56,7,117,110,105,48,52,69,57,7,117, -110,105,48,52,69,65,7,117,110,105,48,52,69,66,7,117,110,105,48,52,69,67,7,117, -110,105,48,52,69,68,7,117,110,105,48,52,69,69,7,117,110,105,48,52,69,70,7,117, -110,105,48,52,70,48,7,117,110,105,48,52,70,49,7,117,110,105,48,52,70,50,7,117, -110,105,48,52,70,51,7,117,110,105,48,52,70,52,7,117,110,105,48,52,70,53,7,117, -110,105,48,52,70,56,7,117,110,105,48,52,70,57,7,117,110,105,48,52,70,67,7,117, -110,105,48,52,70,68,7,117,110,105,48,53,48,49,7,117,110,105,48,53,49,50,7,117, -110,105,48,53,49,51,7,117,110,105,49,69,65,48,7,117,110,105,49,69,65,49,7,117, -110,105,49,69,65,50,7,117,110,105,49,69,65,51,7,117,110,105,49,69,65,52,7,117, -110,105,49,69,65,53,7,117,110,105,49,69,65,54,7,117,110,105,49,69,65,55,7,117, -110,105,49,69,65,56,7,117,110,105,49,69,65,57,7,117,110,105,49,69,65,65,7,117, -110,105,49,69,65,66,7,117,110,105,49,69,65,67,7,117,110,105,49,69,65,68,7,117, -110,105,49,69,65,69,7,117,110,105,49,69,65,70,7,117,110,105,49,69,66,48,7,117, -110,105,49,69,66,49,7,117,110,105,49,69,66,50,7,117,110,105,49,69,66,51,7,117, -110,105,49,69,66,52,7,117,110,105,49,69,66,53,7,117,110,105,49,69,66,54,7,117, -110,105,49,69,66,55,7,117,110,105,49,69,66,56,7,117,110,105,49,69,66,57,7,117, -110,105,49,69,66,65,7,117,110,105,49,69,66,66,7,117,110,105,49,69,66,67,7,117, -110,105,49,69,66,68,7,117,110,105,49,69,66,69,7,117,110,105,49,69,66,70,7,117, -110,105,49,69,67,48,7,117,110,105,49,69,67,49,7,117,110,105,49,69,67,50,7,117, -110,105,49,69,67,51,7,117,110,105,49,69,67,52,7,117,110,105,49,69,67,53,7,117, -110,105,49,69,67,54,7,117,110,105,49,69,67,55,7,117,110,105,49,69,67,56,7,117, -110,105,49,69,67,57,7,117,110,105,49,69,67,65,7,117,110,105,49,69,67,66,7,117, -110,105,49,69,67,67,7,117,110,105,49,69,67,68,7,117,110,105,49,69,67,69,7,117, -110,105,49,69,67,70,7,117,110,105,49,69,68,48,7,117,110,105,49,69,68,49,7,117, -110,105,49,69,68,50,7,117,110,105,49,69,68,51,7,117,110,105,49,69,68,52,7,117, -110,105,49,69,68,53,7,117,110,105,49,69,68,54,7,117,110,105,49,69,68,55,7,117, -110,105,49,69,68,56,7,117,110,105,49,69,68,57,7,117,110,105,49,69,68,65,7,117, -110,105,49,69,68,66,7,117,110,105,49,69,68,67,7,117,110,105,49,69,68,68,7,117, -110,105,49,69,68,69,7,117,110,105,49,69,68,70,7,117,110,105,49,69,69,48,7,117, -110,105,49,69,69,49,7,117,110,105,49,69,69,50,7,117,110,105,49,69,69,51,7,117, -110,105,49,69,69,52,7,117,110,105,49,69,69,53,7,117,110,105,49,69,69,54,7,117, -110,105,49,69,69,55,7,117,110,105,49,69,69,56,7,117,110,105,49,69,69,57,7,117, -110,105,49,69,69,65,7,117,110,105,49,69,69,66,7,117,110,105,49,69,69,67,7,117, -110,105,49,69,69,68,7,117,110,105,49,69,69,69,7,117,110,105,49,69,69,70,7,117, -110,105,49,69,70,48,7,117,110,105,49,69,70,49,7,117,110,105,49,69,70,52,7,117, -110,105,49,69,70,53,7,117,110,105,49,69,70,54,7,117,110,105,49,69,70,55,7,117, -110,105,49,69,70,56,7,117,110,105,49,69,70,57,7,117,110,105,50,48,65,66,7,117, -110,105,48,52,57,65,7,117,110,105,48,52,57,66,7,117,110,105,48,52,65,50,7,117, -110,105,48,52,65,51,7,117,110,105,48,52,65,67,7,117,110,105,48,52,65,68,7,117, -110,105,48,52,66,50,7,117,110,105,48,52,66,51,7,117,110,105,48,52,66,54,7,117, -110,105,48,52,66,55,7,117,110,105,48,52,67,66,7,117,110,105,48,52,67,67,7,117, -110,105,48,52,70,54,7,117,110,105,48,52,70,55,7,117,110,105,48,52,57,54,7,117, -110,105,48,52,57,55,7,117,110,105,48,52,66,69,7,117,110,105,48,52,66,70,7,117, -110,105,48,52,66,66,7,117,110,105,48,52,56,68,7,117,110,105,48,52,56,67,7,117, -110,105,48,52,54,51,7,117,110,105,48,52,54,50,7,117,110,105,48,52,57,50,7,117, -110,105,48,52,57,51,7,117,110,105,48,52,57,69,7,117,110,105,48,52,57,70,7,117, -110,105,48,52,56,65,7,117,110,105,48,52,56,66,7,117,110,105,48,52,67,57,7,117, -110,105,48,52,67,65,7,117,110,105,48,52,67,68,7,117,110,105,48,52,67,69,7,117, -110,105,48,52,67,53,7,117,110,105,48,52,67,54,7,117,110,105,48,52,66,48,7,117, -110,105,48,52,66,49,7,117,110,105,48,52,70,69,7,117,110,105,48,52,70,70,7,117, -110,105,48,52,70,65,7,117,110,105,48,52,70,66,7,117,110,105,48,52,55,67,7,117, -110,105,48,52,55,68,7,117,110,105,48,53,49,49,7,117,110,105,50,48,49,53,0,0,0, -0,1,0,0,0,12,0,0,0,0,0,0,0,2,0,4,0,255,1,2,0,1,1,180,1,192,0,1,1,196,1,204,0, -1,1,206,1,207,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,10,0,30,0,44,0,1,108,97,116,110,0, -8,0,4,0,0,0,0,255,255,0,1,0,0,0,1,107,101,114,110,0,8,0,0,0,1,0,0,0,1,0,4,0,2, -0,0,0,1,0,8,0,1,24,50,0,4,0,0,0,148,1,50,1,68,1,102,1,120,1,154,1,192,1,222,2, -4,2,38,2,68,2,94,2,128,3,6,3,40,3,94,3,120,3,238,4,32,4,62,4,84,4,150,4,160,4, -226,5,76,5,106,5,120,5,222,6,52,6,118,6,204,6,250,7,152,7,206,8,56,8,170,8, -220,9,106,9,176,9,182,9,192,9,214,9,224,9,234,9,248,10,26,10,36,10,46,10,56, -10,62,10,72,10,82,10,92,10,118,10,132,10,206,10,216,10,226,10,236,11,22,11,48, -11,78,11,116,11,142,11,148,12,38,12,96,12,226,12,236,13,34,13,44,13,78,13,84, -13,126,13,132,13,162,13,228,13,242,14,36,14,78,14,88,14,114,14,128,14,222,14, -232,14,242,15,0,15,54,15,108,15,162,15,188,15,222,16,16,16,58,16,112,16,134, -17,36,17,70,17,128,17,170,17,212,17,250,18,36,18,122,18,140,18,174,18,192,18, -210,18,244,19,14,19,60,19,150,19,180,19,206,19,240,19,254,20,28,20,50,20,72, -20,90,20,112,20,130,20,228,21,2,21,100,21,138,21,156,21,166,21,176,21,182,21, -200,21,242,22,12,22,30,22,56,22,94,22,140,22,146,22,168,22,194,22,212,22,254, -23,20,23,126,23,168,23,210,23,220,23,242,24,40,0,4,0,42,255,162,0,54,0,40,0, -55,0,37,0,57,0,45,0,8,0,16,0,4,0,17,255,221,0,19,255,252,0,20,0,5,0,21,255, -253,0,22,0,4,0,23,255,213,0,25,0,6,0,4,0,18,255,250,0,19,255,250,0,21,255,250, -0,23,255,254,0,8,0,16,255,239,0,17,255,239,0,18,0,8,0,21,255,242,0,22,255,239, -0,23,255,233,0,24,255,238,0,25,0,2,0,9,0,17,255,236,0,18,255,253,0,19,0,7,0, -20,0,15,0,21,0,4,0,22,255,253,0,23,255,228,0,24,0,5,0,25,255,255,0,7,0,16,0,3, -0,18,255,225,0,20,0,34,0,21,0,17,0,22,0,3,0,23,255,173,0,24,0,19,0,9,0,17,255, -252,0,18,255,234,0,19,0,6,0,20,0,17,0,21,0,5,0,22,255,254,0,23,255,253,0,24,0, -6,0,25,255,229,0,8,0,16,0,2,0,17,255,217,0,18,255,232,0,20,0,23,0,21,0,9,0,22, -0,2,0,23,255,216,0,24,0,11,0,7,0,17,0,36,0,20,255,94,0,21,255,225,0,22,255, -217,0,23,0,38,0,24,255,234,0,25,255,249,0,6,0,16,255,255,0,17,255,234,0,19,0, -11,0,20,0,20,0,21,0,8,0,22,255,255,0,8,0,16,0,3,0,17,255,218,0,18,255,247,0, -20,0,5,0,21,255,252,0,22,0,3,0,23,255,209,0,25,0,5,0,33,0,35,255,218,0,39,255, -217,0,47,255,214,0,49,255,217,0,52,255,104,0,53,255,211,0,54,255,108,0,55,255, -157,0,57,255,93,0,65,0,5,0,67,255,236,0,68,255,229,0,69,255,232,0,71,255,240, -0,79,255,232,0,81,255,240,0,83,0,3,0,84,255,192,0,85,255,233,0,86,255,173,0, -87,255,188,0,90,0,24,1,8,255,120,1,12,255,120,1,66,255,236,1,70,255,233,1,78, -255,233,1,80,255,236,1,83,255,139,1,84,255,225,1,85,255,152,1,86,255,185,1,88, -255,133,0,8,0,57,255,93,0,65,0,10,0,73,255,252,0,76,255,252,0,79,0,6,0,82,0,2, -0,85,0,5,0,89,0,4,0,13,0,35,255,250,0,39,255,250,0,47,255,247,0,49,255,250,0, -73,255,244,0,82,255,250,0,85,255,250,0,89,0,11,0,90,255,247,1,66,255,250,1,70, -255,249,1,78,255,249,1,80,255,250,0,6,0,54,255,213,0,55,255,230,0,65,255,253, -0,69,0,4,0,79,0,4,0,85,0,4,0,29,0,54,0,17,0,55,0,16,0,57,0,18,0,66,255,245,0, -67,255,218,0,68,255,213,0,69,255,217,0,70,255,219,0,71,255,222,0,73,255,246,0, -74,255,249,0,75,255,248,0,76,255,246,0,77,255,238,0,78,255,238,0,79,255,217,0, -80,255,242,0,81,255,222,0,82,255,240,0,84,255,212,0,85,255,222,0,86,255,203,0, -87,255,210,0,88,0,5,0,89,255,207,0,90,0,6,1,85,255,224,1,86,255,218,1,88,255, -223,0,12,0,12,254,205,0,14,254,205,0,33,255,135,0,65,255,187,0,69,255,212,0, -73,255,249,0,76,255,247,0,79,255,212,0,82,255,203,0,85,255,210,0,89,255,206,1, -63,255,124,0,7,0,65,0,1,0,69,0,4,0,78,255,255,0,79,0,1,0,82,0,2,0,85,0,1,0,89, -0,1,0,5,0,65,255,250,0,69,255,246,0,79,255,246,0,85,255,247,0,89,255,253,0,16, -0,65,255,248,0,67,255,248,0,68,255,238,0,70,255,244,0,71,255,248,0,77,255,248, -0,78,255,248,0,79,255,244,0,80,255,252,0,82,255,248,0,83,255,248,0,84,255,247, -0,85,255,248,0,86,255,250,0,87,255,252,0,89,255,250,0,2,0,65,255,247,0,79,255, -247,0,16,0,35,255,200,0,39,255,196,0,47,255,193,0,49,255,196,0,65,255,246,0, -69,255,202,0,73,255,247,0,79,255,201,0,82,255,248,0,85,255,208,0,87,255,177,0, -89,255,175,1,66,255,207,1,70,255,203,1,78,255,204,1,80,255,204,0,26,0,33,0,39, -0,35,255,213,0,39,255,209,0,47,255,205,0,49,255,209,0,52,255,100,0,53,255,206, -0,54,255,71,0,55,255,147,0,57,255,79,0,74,255,254,0,85,255,227,0,87,255,170,0, -89,255,147,1,8,254,233,1,12,254,230,1,63,0,38,1,66,255,229,1,70,255,225,1,78, -255,227,1,80,255,227,1,83,255,118,1,84,255,220,1,85,255,109,1,86,255,172,1,88, -255,106,0,7,0,65,255,249,0,69,255,245,0,74,255,248,0,78,255,249,0,79,255,245, -0,85,255,249,0,89,255,252,0,3,0,69,255,247,0,79,255,247,0,89,255,253,0,25,0, -33,255,214,0,52,255,201,0,54,255,211,0,55,255,233,0,56,255,210,0,57,255,198,0, -67,0,2,0,68,255,252,0,69,0,2,0,70,0,1,0,71,0,2,0,74,255,245,0,79,0,2,0,80,255, -255,0,81,0,5,0,83,255,255,0,84,0,4,0,85,0,2,0,88,255,244,0,89,0,7,0,90,255, -241,1,63,255,215,1,85,255,254,1,86,255,255,1,87,255,233,0,21,0,12,254,176,0, -14,254,176,0,33,255,146,0,37,255,250,0,40,255,250,0,41,255,250,0,65,255,234,0, -69,255,230,0,72,255,254,0,73,255,248,0,76,255,250,0,78,255,250,0,79,255,230,0, -82,255,252,0,83,255,244,0,84,0,29,0,89,0,31,1,63,255,138,1,68,255,253,1,71, -255,253,1,72,255,253,0,16,0,33,0,28,0,52,255,188,0,53,255,242,0,54,255,199,0, -55,255,216,0,56,0,24,0,57,255,185,0,65,255,255,0,85,255,252,1,63,0,28,1,83, -255,244,1,84,255,249,1,85,255,240,1,86,255,244,1,87,0,13,1,88,255,238,0,21,0, -35,255,245,0,39,255,245,0,47,255,242,0,49,255,245,0,52,255,215,0,53,255,242,0, -54,255,217,0,55,255,226,0,57,255,158,0,65,255,252,0,69,255,241,0,79,255,241,0, -85,255,248,0,89,255,254,1,66,255,246,1,70,255,245,1,78,255,245,1,80,255,245,1, -83,255,253,1,84,255,245,1,86,255,248,0,11,0,65,0,1,0,69,255,253,0,74,255,247, -0,77,255,250,0,78,255,250,0,79,255,253,0,80,255,254,0,81,255,255,0,85,255,254, -0,87,0,6,0,89,0,5,0,39,0,12,255,92,0,13,255,96,0,14,255,92,0,26,255,102,0,27, -255,100,0,33,255,94,0,35,255,204,0,39,255,200,0,47,255,199,0,49,255,202,0,51, -255,223,0,52,0,32,0,54,0,32,0,55,0,31,0,56,0,21,0,57,0,33,0,65,255,97,0,69, -255,94,0,73,255,249,0,77,255,122,0,79,255,94,0,82,255,122,0,83,255,101,0,85, -255,122,0,87,255,159,0,89,255,156,0,90,255,133,1,8,0,7,1,63,255,91,1,66,255, -110,1,70,255,110,1,78,255,110,1,80,255,110,1,82,255,117,1,83,255,225,1,85,255, -235,1,86,255,225,1,87,255,218,1,88,255,236,0,13,0,33,255,211,0,68,255,240,0, -70,255,252,0,71,255,248,0,77,255,248,0,78,255,248,0,80,255,248,0,82,255,248,0, -83,255,244,0,84,255,255,0,88,255,241,0,90,255,237,1,63,255,212,0,26,0,9,0,40, -0,12,255,76,0,13,255,181,0,14,255,81,0,26,255,193,0,27,255,193,0,33,255,103,0, -35,255,213,0,39,255,213,0,47,255,210,0,49,255,213,0,61,0,34,0,65,255,161,0,69, -255,165,0,79,255,161,0,82,255,194,0,85,255,198,0,89,255,234,0,93,0,38,1,8,0, -12,1,12,0,12,1,63,255,100,1,66,255,177,1,70,255,177,1,78,255,177,1,80,255,177, -0,28,0,9,0,31,0,12,255,138,0,13,255,213,0,14,255,138,0,26,255,212,0,27,255, -211,0,33,255,147,0,35,255,228,0,39,255,228,0,47,255,225,0,49,255,228,0,52,0, -29,0,61,0,25,0,65,255,189,0,69,255,193,0,79,255,193,0,82,255,213,0,85,255,217, -0,89,255,247,0,93,0,29,1,8,0,9,1,12,0,9,1,63,255,148,1,66,255,209,1,70,255, -205,1,78,255,205,1,80,255,205,1,83,255,254,0,12,0,35,255,209,0,39,255,209,0, -47,255,205,0,49,255,209,0,69,255,203,0,85,255,212,0,89,255,192,1,8,255,249,1, -66,255,209,1,70,255,205,1,78,255,205,1,80,255,208,0,35,0,9,0,41,0,12,255,69,0, -13,255,150,0,14,255,69,0,26,255,167,0,27,255,168,0,33,255,88,0,35,255,202,0, -39,255,200,0,47,255,196,0,49,255,200,0,52,0,34,0,54,0,36,0,55,0,34,0,56,0,27, -0,57,0,37,0,61,0,37,0,65,255,127,0,69,255,122,0,79,255,122,0,81,255,131,0,84, -255,210,0,85,255,176,0,86,255,216,0,93,0,39,1,63,255,81,1,66,255,151,1,70,255, -147,1,78,255,147,1,80,255,147,1,83,255,230,1,85,255,238,1,86,255,230,1,87,255, -222,1,88,255,239,0,17,0,33,0,27,0,35,255,209,0,39,255,205,0,47,255,202,0,49, -255,205,0,65,255,254,0,69,255,213,0,73,255,247,0,79,255,212,0,85,255,218,0,87, -255,200,0,89,255,201,1,63,0,27,1,66,255,218,1,70,255,214,1,78,255,216,1,80, -255,216,0,1,0,42,255,219,0,2,1,8,255,225,1,12,255,225,0,5,0,86,255,233,0,87, -255,240,0,89,255,233,1,8,255,197,1,12,255,197,0,2,1,8,255,246,1,12,255,246,0, -2,1,8,255,247,1,12,255,247,0,3,0,89,255,230,1,8,255,227,1,12,255,227,0,8,0,7, -0,32,0,9,0,41,0,61,0,37,0,71,255,207,0,93,0,39,1,8,0,32,1,12,0,32,3,177,0,28, -0,2,1,8,255,247,1,12,255,247,0,2,1,8,255,198,1,12,255,198,0,2,1,8,255,249,1, -12,255,249,0,1,0,69,255,215,0,2,1,8,255,245,1,12,255,245,0,2,1,8,255,220,1,12, -255,220,0,2,1,8,255,227,1,12,255,227,0,6,0,86,255,226,0,87,255,237,0,88,255, -214,0,89,255,226,1,8,255,216,1,12,255,216,0,3,0,87,255,240,1,8,255,223,1,12, -255,223,0,18,0,12,255,126,0,14,255,126,0,67,255,218,0,68,255,220,0,69,255,218, -0,70,0,31,0,75,0,1,0,79,255,216,0,81,255,221,0,84,0,34,0,85,0,1,0,86,0,36,0, -87,0,35,0,88,0,18,0,89,0,36,0,90,0,10,1,8,0,32,1,12,0,32,0,2,1,8,255,247,1,12, -255,247,0,2,1,8,255,249,1,12,255,249,0,2,1,8,255,248,1,12,255,248,0,10,0,12, -255,135,0,14,255,139,0,65,255,226,0,67,255,229,0,68,255,229,0,69,255,229,0,79, -255,225,0,81,255,229,1,8,0,34,1,12,0,34,0,6,0,12,255,162,0,14,255,166,0,67, -255,236,0,68,255,236,0,69,255,232,0,81,255,236,0,7,0,67,255,215,0,68,255,219, -0,69,255,215,0,79,255,215,0,81,255,219,1,8,0,18,1,12,0,18,0,9,0,12,255,118,0, -14,255,128,0,67,255,223,0,68,255,223,0,69,255,223,0,79,255,223,0,81,255,217,1, -8,0,28,1,12,0,28,0,6,0,67,255,223,0,68,255,226,0,69,255,223,0,79,255,223,1,8, -0,7,1,12,0,7,0,1,0,42,255,215,0,36,0,12,254,206,0,13,254,204,0,14,254,210,0, -35,255,199,0,39,255,197,0,47,255,197,0,49,255,197,0,52,0,34,0,54,0,33,0,55,0, -30,0,57,0,33,0,105,254,208,0,120,254,210,0,127,255,195,0,142,255,195,0,169, -255,66,0,170,255,197,0,171,255,66,0,175,255,108,0,178,254,244,0,180,254,241,0, -181,255,223,0,182,254,249,0,184,255,14,0,186,254,246,0,189,255,70,0,190,254, -237,0,191,254,240,0,192,254,231,0,193,255,92,0,194,254,250,0,195,254,252,0, -196,255,1,0,197,254,244,1,5,254,207,1,6,254,207,0,14,0,12,255,217,0,14,255, -226,0,33,255,224,0,52,255,203,0,54,255,224,0,55,255,238,0,56,255,216,0,57,255, -206,0,58,255,219,0,125,255,206,0,169,255,217,0,171,255,224,0,172,255,228,0, -174,255,217,0,32,0,7,255,115,0,31,255,140,0,33,0,36,0,35,255,219,0,39,255,215, -0,47,255,215,0,49,255,215,0,52,255,75,0,53,255,212,0,54,255,113,0,55,255,156, -0,57,255,85,0,67,255,234,0,68,255,229,0,69,255,234,0,71,255,238,0,79,255,234, -0,81,255,238,0,85,255,235,0,125,0,38,0,127,255,236,0,133,255,238,0,142,255, -215,0,143,255,238,0,169,0,38,0,170,255,215,0,175,255,202,0,176,255,156,0,193, -255,149,1,8,255,119,1,12,255,119,3,177,255,119,0,2,0,170,255,225,0,187,0,27,0, -13,0,7,255,246,0,35,255,211,0,39,255,209,0,47,255,209,0,49,255,209,0,127,255, -232,0,142,255,205,0,170,255,209,0,175,255,151,0,187,0,36,1,8,255,246,1,12,255, -246,3,177,255,246,0,2,0,171,255,199,0,187,255,193,0,8,0,12,255,84,0,14,255,88, -0,171,255,157,0,181,255,243,0,190,255,224,0,192,255,237,0,195,255,244,0,197, -255,240,0,1,0,187,0,34,0,10,0,7,0,32,0,70,0,29,0,181,255,239,0,189,0,27,0,190, -255,211,0,193,0,30,0,197,255,236,1,8,0,32,1,12,0,32,3,177,0,32,0,1,0,193,255, -225,0,7,0,7,255,239,0,191,255,243,0,192,255,243,0,195,255,242,1,8,255,244,1, -12,255,244,3,177,255,240,0,16,0,178,255,209,0,180,0,10,0,181,255,216,0,182, -255,226,0,184,255,233,0,186,255,237,0,187,0,11,0,188,255,223,0,189,0,14,0,191, -255,199,0,192,255,205,0,193,0,15,0,194,255,238,0,195,255,219,0,196,255,239,0, -197,255,217,0,3,0,7,255,217,1,8,255,227,1,12,255,227,0,12,0,7,255,186,0,178, -255,225,0,180,255,191,0,185,255,217,0,186,255,239,0,187,0,37,0,189,255,214,0, -193,255,190,0,195,255,212,1,8,255,249,1,12,255,249,3,177,255,184,0,10,0,7,255, -58,0,70,255,209,0,180,255,145,0,185,255,212,0,187,0,33,0,189,255,212,0,193, -255,125,1,8,255,63,1,12,255,63,3,177,255,58,0,2,0,178,255,179,0,187,0,17,0,6, -0,87,255,240,0,88,255,226,0,90,255,232,0,193,255,215,1,8,255,223,1,12,255,223, -0,3,0,180,0,17,0,189,0,19,0,193,0,20,0,23,0,7,0,34,0,70,0,29,0,120,255,233,0, -180,0,27,0,181,255,223,0,189,0,29,0,191,255,214,0,192,255,211,0,193,0,29,1,8, -0,34,1,12,0,34,1,63,255,122,1,66,255,220,1,70,255,216,1,78,255,218,1,80,255, -216,1,82,255,234,1,83,0,29,1,85,0,27,1,86,0,20,1,87,0,8,1,88,0,27,3,177,0,34, -0,2,0,88,255,220,0,90,255,220,0,2,0,88,255,228,0,90,255,228,0,3,0,88,255,226, -0,90,255,226,0,180,255,234,0,13,0,7,255,170,0,198,255,185,0,202,255,186,0,206, -255,233,0,210,255,223,0,212,255,194,0,215,255,188,0,233,255,164,0,236,255,239, -0,239,255,200,1,8,255,175,1,12,255,175,3,177,255,171,0,13,0,7,255,126,0,202, -255,67,0,206,255,232,0,209,255,243,0,210,255,220,0,212,255,194,0,215,255,141, -0,233,255,161,0,236,255,241,0,239,255,201,1,8,255,146,1,12,255,146,3,177,255, -135,0,13,0,7,255,125,0,198,255,68,0,202,255,66,0,206,255,230,0,210,255,219,0, -212,255,193,0,215,255,140,0,233,255,159,0,236,255,240,0,239,255,200,1,8,255, -144,1,12,255,144,3,177,255,134,0,6,0,198,255,181,0,202,255,179,0,215,255,184, -0,233,255,158,0,236,255,225,0,239,255,194,0,8,0,198,255,206,0,210,255,225,0, -212,255,202,0,215,255,208,0,225,255,227,0,233,255,168,0,236,255,242,0,239,255, -204,0,12,0,198,255,196,0,200,0,40,0,202,255,197,0,205,0,46,0,209,0,40,0,212, -255,197,0,215,255,199,0,224,0,44,0,229,0,40,0,236,255,196,0,247,0,40,0,253, -255,213,0,10,0,13,255,141,0,199,255,206,0,200,0,36,0,209,0,36,0,221,255,210,0, -229,0,37,0,233,255,181,0,236,255,161,0,247,0,37,0,253,255,206,0,13,0,17,255, -236,0,18,255,253,0,19,0,7,0,20,0,15,0,21,0,4,0,22,255,253,0,23,255,228,0,24,0, -5,0,25,255,255,0,207,0,11,0,209,255,239,0,210,255,236,0,215,255,228,0,5,0,65, -255,252,0,69,255,255,0,79,255,252,0,85,255,255,0,89,0,2,0,39,0,7,0,15,0,13, -255,177,0,14,255,135,0,67,255,229,0,68,255,229,0,69,255,229,0,79,255,229,0,81, -255,225,0,199,255,210,0,200,255,138,0,205,255,53,0,209,255,138,0,215,0,36,0, -222,255,187,0,223,255,187,0,224,255,69,0,227,255,187,0,228,255,187,0,229,255, -116,0,230,255,187,0,231,255,187,0,232,255,187,0,234,255,154,0,235,255,187,0, -236,255,207,0,237,255,187,0,238,255,185,0,240,255,187,0,241,255,187,0,243,255, -185,0,244,255,172,0,246,255,150,0,247,255,116,0,248,255,187,0,250,255,187,0, -254,255,153,1,8,0,31,1,12,0,31,3,177,0,13,0,8,0,200,0,39,0,205,0,96,0,209,0, -49,0,212,255,195,0,224,0,104,0,229,0,58,0,236,255,194,0,247,0,39,0,14,0,198, -255,218,0,200,0,42,0,205,0,48,0,209,0,42,0,210,0,22,0,212,255,218,0,215,255, -219,0,218,255,242,0,224,0,45,0,229,0,40,0,233,255,223,0,236,255,217,0,239,255, -225,0,247,0,40,0,10,0,7,255,124,0,198,255,65,0,202,255,63,0,212,255,190,0,215, -255,137,0,233,255,158,0,239,255,198,1,8,255,139,1,12,255,139,3,177,255,133,0, -10,0,7,255,131,0,198,255,69,0,202,255,67,0,212,255,194,0,215,255,141,0,233, -255,164,0,239,255,200,1,8,255,145,1,12,255,145,3,177,255,135,0,9,0,198,255, -206,0,200,255,207,0,202,255,205,0,205,255,202,0,206,255,207,0,209,255,207,0, -210,255,217,0,229,255,214,0,247,255,214,0,10,0,198,255,202,0,200,255,206,0, -202,255,202,0,205,255,203,0,206,255,207,0,209,255,206,0,210,255,217,0,224,255, -203,0,229,255,214,0,247,255,214,0,21,0,35,255,250,0,39,255,250,0,47,255,253,0, -49,255,250,0,52,255,214,0,53,255,249,0,54,255,236,0,55,255,243,0,57,255,229,0, -69,255,252,0,79,255,250,0,85,255,253,0,89,0,6,1,66,255,253,1,70,255,249,1,78, -255,249,1,80,255,249,1,83,0,1,1,84,255,253,1,85,0,1,1,88,0,1,0,4,0,224,255, -225,0,225,255,224,0,233,255,223,0,239,255,241,0,8,0,7,255,191,0,225,255,237,0, -233,255,230,0,236,255,238,0,239,255,235,1,8,255,230,1,12,255,230,3,177,255, -190,0,4,0,224,255,132,0,229,255,171,0,246,255,211,0,247,255,171,0,4,0,224,0, -42,0,233,255,219,0,236,255,216,0,239,255,223,0,8,0,7,0,11,0,234,255,236,0,236, -255,245,0,246,255,218,0,254,255,220,1,8,0,11,1,12,0,11,3,177,0,11,0,6,0,7,255, -232,0,233,255,237,0,236,255,240,1,8,255,236,1,12,255,236,3,177,255,232,0,11,0, -221,255,233,0,234,255,224,0,236,255,242,0,246,255,211,0,254,255,213,1,8,0,12, -1,12,0,12,1,66,255,212,1,70,255,208,1,78,255,212,1,80,255,212,0,22,0,7,0,34,0, -70,0,29,0,224,255,133,0,229,255,172,0,234,255,223,0,246,255,211,0,247,255,172, -0,254,255,213,1,8,0,31,1,12,0,31,1,63,255,122,1,66,255,220,1,70,255,216,1,78, -255,218,1,80,255,216,1,82,255,234,1,83,0,29,1,85,0,27,1,86,0,20,1,87,0,8,1,88, -0,27,3,177,0,34,0,7,0,88,255,244,0,90,255,244,0,225,255,236,0,229,255,246,0, -233,255,229,0,239,255,237,0,247,255,246,0,6,0,224,0,37,0,229,0,32,0,233,255, -222,0,236,255,220,0,239,255,224,0,247,0,32,0,8,0,224,0,43,0,229,0,38,0,233, -255,206,0,236,255,203,0,239,255,215,0,242,255,242,0,246,255,224,0,247,0,38,0, -3,0,233,255,122,0,236,255,203,0,239,255,178,0,7,0,7,254,253,0,233,255,118,0, -236,255,202,0,239,255,174,1,8,255,35,1,12,255,39,3,177,255,10,0,5,0,224,255, -218,0,225,255,218,0,229,255,225,0,239,255,222,0,247,255,225,0,5,0,224,255,217, -0,225,255,217,0,226,255,245,0,229,255,223,0,239,255,232,0,4,0,7,255,240,1,8, -255,244,1,12,255,244,3,177,255,240,0,5,0,225,255,232,0,233,255,116,0,234,0,11, -0,236,255,200,0,239,255,172,0,4,0,225,255,236,0,233,255,121,0,236,255,203,0, -239,255,177,0,24,0,33,255,120,0,52,0,12,0,54,0,16,0,55,0,18,0,57,0,9,0,65,255, -225,0,67,255,217,0,68,255,197,0,69,255,217,0,70,0,5,0,71,255,222,0,77,255,247, -0,78,255,247,0,79,255,217,0,81,255,222,0,83,255,237,0,84,0,11,0,85,255,254,0, -86,0,36,0,87,0,32,0,88,0,18,0,89,0,36,0,90,0,8,1,7,255,241,0,7,0,68,255,172,0, -77,255,243,0,82,255,247,0,83,255,216,0,84,0,6,0,86,0,27,1,8,255,245,0,24,0,33, -255,118,0,52,0,9,0,54,0,10,0,55,0,12,0,57,0,7,0,65,255,223,0,67,255,215,0,68, -255,191,0,69,255,215,0,71,255,215,0,77,255,245,0,78,255,245,0,79,255,211,0,80, -255,249,0,81,255,219,0,82,255,245,0,83,255,230,0,84,0,4,0,85,255,252,0,86,0, -27,0,87,0,23,0,88,0,12,0,89,0,27,0,90,0,3,0,9,1,66,255,227,1,70,255,227,1,78, -255,227,1,80,255,227,1,83,255,125,1,84,255,216,1,85,255,139,1,86,255,175,1,88, -255,123,0,4,1,66,255,254,1,70,255,254,1,78,255,254,1,80,255,254,0,2,1,85,255, -220,1,86,255,234,0,2,1,85,0,4,1,88,0,4,0,1,1,63,255,162,0,4,1,66,255,212,1,70, -255,208,1,78,255,212,1,80,255,212,0,10,1,63,0,35,1,66,255,224,1,70,255,220,1, -78,255,222,1,80,255,223,1,83,255,115,1,84,255,215,1,85,255,107,1,86,255,167,1, -88,255,101,0,6,1,63,255,229,1,83,255,219,1,85,255,225,1,86,255,239,1,87,255, -215,1,88,255,211,0,4,1,63,255,168,1,68,255,245,1,71,255,245,1,72,255,245,0,6, -1,63,0,13,1,83,255,208,1,84,255,246,1,85,255,213,1,86,255,226,1,88,255,201,0, -9,1,66,255,252,1,70,255,252,1,78,255,252,1,80,255,252,1,83,255,228,1,84,255, -245,1,85,255,226,1,86,255,233,1,88,255,219,0,11,1,63,255,122,1,66,255,220,1, -70,255,216,1,78,255,218,1,80,255,216,1,82,255,234,1,83,0,29,1,85,0,27,1,86,0, -20,1,87,0,8,1,88,0,27,0,1,1,63,255,221,0,5,1,63,255,140,1,66,255,228,1,70,255, -224,1,78,255,224,1,80,255,224,0,6,1,63,255,182,1,66,255,239,1,70,255,239,1,78, -255,239,1,80,255,239,1,83,0,28,0,4,1,66,255,218,1,70,255,214,1,78,255,214,1, -80,255,214,0,10,1,63,255,124,1,66,255,217,1,70,255,213,1,78,255,213,1,80,255, -213,1,83,0,31,1,85,0,33,1,86,0,27,1,87,0,14,1,88,0,33,0,5,1,63,0,25,1,66,255, -224,1,70,255,224,1,78,255,224,1,80,255,224,0,26,0,9,0,40,0,12,255,76,0,13,255, -181,0,14,255,81,0,26,255,193,0,27,255,193,0,33,255,103,0,35,255,213,0,39,255, -213,0,47,255,210,0,49,255,213,0,61,0,34,0,65,255,161,0,69,255,165,0,79,255, -161,0,82,255,194,0,85,255,198,0,89,255,234,0,93,0,38,1,8,0,12,1,12,0,12,1,63, -255,100,1,66,255,177,1,70,255,177,1,78,255,177,1,80,255,177,0,10,0,12,255,135, -0,14,255,139,0,65,255,226,0,67,255,229,0,68,255,229,0,69,255,229,0,79,255,225, -0,81,255,229,1,8,0,34,1,12,0,34,0,10,0,35,255,253,0,39,255,253,0,47,255,254,0, -49,255,253,0,65,0,8,0,73,255,247,0,82,255,255,0,85,255,252,0,89,0,16,0,90,0,2, -0,2,1,8,255,234,1,12,255,234,0,5,0,65,255,250,0,69,255,246,0,79,255,246,0,85, -255,247,0,89,255,253,0,13,0,35,255,250,0,39,255,250,0,47,255,247,0,49,255,250, -0,73,255,244,0,82,255,250,0,85,255,250,0,89,0,11,0,90,255,247,1,66,255,250,1, -70,255,249,1,78,255,249,1,80,255,250,0,2,1,8,255,246,1,12,255,246,0,2,0,35,0, -8,0,8,0,0,0,16,0,25,0,1,0,33,0,59,0,11,0,65,0,73,0,38,0,75,0,80,0,47,0,82,0, -91,0,53,0,168,0,168,0,63,0,170,0,172,0,64,0,174,0,176,0,67,0,178,0,178,0,70,0, -180,0,184,0,71,0,186,0,188,0,76,0,190,0,190,0,79,0,192,0,193,0,80,0,195,0,198, -0,82,0,200,0,202,0,86,0,204,0,208,0,89,0,210,0,211,0,94,0,214,0,215,0,96,0, -217,0,226,0,98,0,228,0,228,0,108,0,233,0,235,0,109,0,238,0,239,0,112,0,241,0, -243,0,114,0,246,0,248,0,117,1,7,1,8,0,120,1,11,1,11,0,122,1,63,1,63,0,123,1, -66,1,69,0,124,1,74,1,75,0,128,1,78,1,81,0,130,1,83,1,89,0,134,1,111,1,114,0, -141,1,137,1,137,0,145,1,141,1,142,0,146,0,1,0,0,0,10,0,32,0,58,0,1,108,97,116, -110,0,8,0,4,0,0,0,0,255,255,0,2,0,0,0,1,0,2,108,105,103,97,0,14,115,109,99, -112,0,20,0,0,0,1,0,0,0,0,0,1,0,1,0,2,0,6,0,14,0,4,0,0,0,1,0,16,0,1,0,0,0,1,0, -26,0,1,0,148,0,1,0,8,0,1,0,4,0,130,0,2,0,69,0,2,0,136,0,62,1,90,1,91,1,92,1, -93,1,94,1,95,1,96,1,97,1,98,1,99,1,63,1,65,1,66,1,67,1,68,1,69,1,70,1,71,1,72, -1,73,1,74,1,75,1,76,1,77,1,78,1,79,1,80,1,81,1,82,1,83,1,84,1,85,1,86,1,87,1, -88,1,89,1,63,1,65,1,66,1,67,1,68,1,69,1,70,1,71,1,72,1,73,1,74,1,75,1,76,1,77, -1,78,1,79,1,80,1,81,1,82,1,83,1,84,1,85,1,86,1,87,1,88,1,89,0,1,0,1,0,65,0,2, -0,3,0,16,0,25,0,0,0,33,0,58,0,10,0,65,0,90,0,36}; +static const char +default_font_bitmap[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,3,154,0,0,0,14,8,6,0,0,0,78, +234,99,67,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,9,112,72,89,115, +0,0,14,194,0,0,14,194,1,21,40,74,128,0,0,0,25,116,69,88,116,83,111,102,116, +119,97,114,101,0,112,97,105,110,116,46,110,101,116,32,52,46,48,46,50,49,241, +32,105,149,0,0,29,22,73,68,65,84,120,94,237,92,61,168,109,75,82,126,8,134,166, +26,138,32,152,152,60,16,68,12,6,28,159,130,136,129,58,193,168,136,99,96,224,4, +38,47,83,208,64,197,224,129,168,32,19,61,13,12,100,20,20,196,72,196,216,159, +200,68,19,49,209,72,65,20,19,17,217,246,87,95,215,174,175,126,122,239,117,206, +61,87,158,48,181,169,123,86,87,125,93,93,127,221,107,173,125,238,189,31,220, +62,184,221,192,31,20,114,249,164,115,82,204,35,28,232,10,238,10,6,116,21,7, +122,132,123,169,141,43,248,9,247,104,222,132,159,104,194,169,76,229,87,232, +234,188,171,56,208,251,192,42,238,132,125,164,3,93,153,251,104,62,232,165,184, +61,124,74,111,105,247,173,48,78,142,189,106,243,25,206,233,125,224,21,115,5, +183,135,15,73,237,93,153,243,8,127,146,59,61,211,43,93,193,94,193,76,164,243, +174,206,125,41,30,116,117,206,85,92,165,151,204,187,130,123,169,173,183,198, +130,94,138,175,116,117,238,75,214,120,107,155,142,59,97,85,127,194,40,93,197, +190,47,123,255,223,112,239,34,175,58,167,147,254,165,114,167,103,122,208,85, +125,197,60,155,7,58,97,92,94,117,39,185,147,234,79,24,167,215,98,183,40,209, +85,253,30,38,250,44,233,78,228,115,222,199,188,43,24,165,151,226,157,238,243, +238,179,11,87,73,30,5,87,73,30,5,87,201,73,174,60,75,201,251,74,13,236,208,44, +56,149,143,137,169,24,227,219,237,211,197,159,96,164,100,200,140,221,154,32, +67,60,192,108,41,237,63,192,41,65,119,199,125,225,126,5,255,64,159,222,37,87, +109,56,95,141,243,118,251,207,197,95,18,153,95,125,105,241,191,44,254,72,116, +160,143,22,67,14,253,182,58,218,197,218,234,191,243,158,241,152,128,147,57, +199,121,134,186,128,3,25,242,141,177,134,202,184,132,13,73,215,57,153,246,160, +47,186,113,62,200,80,47,199,109,233,153,10,254,157,236,190,22,115,31,9,155,60, +99,111,183,95,76,163,96,236,171,44,225,124,149,40,87,252,201,238,98,179,195, +79,72,39,60,100,85,250,28,71,251,170,87,238,113,53,155,105,254,35,31,186,46, +143,170,190,172,147,248,9,214,124,226,231,136,1,59,37,121,181,13,158,236,203, +120,152,147,71,19,243,19,146,193,63,227,151,246,214,98,211,95,181,15,86,108, +220,35,50,171,31,143,108,213,92,20,172,249,230,227,11,88,208,93,246,0,159,112, +39,214,249,101,173,196,15,112,109,157,215,216,204,81,100,230,39,75,116,148, +237,144,79,53,3,87,123,87,234,187,174,156,18,6,156,113,87,237,129,243,200,185, +198,115,202,97,197,93,93,247,5,254,89,188,252,60,151,187,159,83,61,106,12,29, +51,219,124,34,119,50,237,3,61,200,16,131,254,46,169,62,241,185,235,171,246, +211,101,37,14,167,53,138,185,154,223,154,83,159,95,215,42,118,155,158,188,87, +203,4,185,96,140,183,106,164,132,173,189,48,244,64,26,169,95,213,103,126,56, +170,118,31,205,203,107,102,221,213,245,234,188,194,78,107,148,145,213,230,137, +235,188,136,239,227,197,246,204,63,229,206,214,84,137,114,181,249,12,239,172, +243,170,206,185,74,242,40,184,74,242,40,184,74,110,183,111,177,171,42,87,158, +165,228,125,165,6,44,120,144,73,67,62,54,115,197,24,127,150,95,52,127,198,254, +140,23,185,223,16,221,85,27,206,95,123,209,108,100,200,55,198,26,42,227,18,54, +36,93,231,100,90,215,127,238,126,69,198,56,75,246,172,76,134,122,57,110,75, +207,84,240,239,100,247,181,152,61,66,191,253,215,98,28,166,91,107,31,31,129, +208,155,255,97,87,65,31,167,27,4,56,231,24,125,170,212,241,92,179,18,15,116, +112,173,209,140,255,56,97,136,171,107,35,190,105,47,130,43,246,147,230,39,152, +107,227,129,228,195,197,154,191,121,63,234,126,206,58,191,58,157,3,176,143, +117,162,30,92,163,198,0,106,103,198,146,103,223,163,118,147,239,96,207,233, +148,71,215,225,204,83,13,108,230,135,51,112,212,223,99,80,98,60,189,166,19, +246,211,39,189,5,127,148,162,103,122,252,115,47,64,171,190,240,97,164,246,121, +238,217,217,87,167,220,3,90,223,37,145,156,247,126,9,187,17,71,240,132,71,252, +181,38,192,193,119,91,111,115,239,49,214,33,114,16,56,158,1,129,59,249,132,49, +228,31,10,214,251,164,18,253,113,92,212,16,54,156,24,71,237,11,222,179,29,155, +237,56,19,83,107,50,219,99,125,61,78,16,99,128,141,192,89,157,64,91,18,121, +201,56,183,87,251,240,211,182,238,28,115,206,31,184,219,114,202,251,146,235, +106,190,89,75,237,211,25,199,28,214,56,118,204,38,189,34,143,124,79,231,133, +238,159,169,102,179,205,39,114,39,211,62,208,131,12,81,244,50,3,53,168,123, +169,159,101,148,165,115,21,180,116,97,155,189,135,154,125,210,114,202,121,167, +179,253,247,22,255,214,226,222,3,228,189,90,38,200,5,99,188,85,35,37,44,123,1, +107,195,223,143,90,175,68,143,118,191,217,67,244,21,18,245,131,57,240,30,203, +245,14,57,251,83,115,20,235,193,159,156,7,250,192,61,7,137,174,151,253,244, +125,76,251,148,123,236,49,7,76,223,177,14,40,98,9,121,95,11,204,188,229,179, +170,230,46,143,126,121,49,124,1,127,197,100,213,102,196,0,174,123,62,98,1,206, +81,129,207,92,37,121,20,92,37,252,243,27,23,255,210,226,239,218,227,9,247,23, +139,191,167,201,149,103,41,121,95,169,97,43,16,200,164,33,31,155,185,98,140, +125,211,149,41,134,204,216,173,9,50,196,3,204,150,210,254,3,156,18,116,119,28, +27,6,5,196,38,255,176,52,203,158,209,201,80,129,35,95,141,19,27,43,31,64,170, +173,58,208,243,195,141,184,126,88,146,247,140,199,4,156,204,57,206,51,212,5, +28,200,144,111,140,53,84,198,37,108,72,186,206,201,180,174,231,161,136,220, +242,32,173,249,31,230,131,12,245,114,220,150,158,169,224,223,201,238,107,48, +247,43,246,211,191,46,158,111,38,224,210,155,251,39,110,44,249,197,135,57,246, +195,187,30,232,216,55,245,198,155,111,98,100,224,40,235,123,164,227,123,29,65, +220,35,42,85,220,116,163,11,44,230,158,94,186,238,88,203,105,224,251,126,212, +156,101,157,95,69,47,170,158,246,177,14,111,126,252,201,155,120,189,201,149, +186,152,79,252,76,24,216,112,155,206,88,11,103,34,117,170,1,199,218,113,227, +39,195,38,124,204,190,179,254,240,5,120,228,197,53,192,195,78,127,137,239,241, +250,56,159,245,180,237,118,180,182,142,167,76,111,208,96,175,79,72,48,6,62, +247,87,216,86,63,240,64,24,15,65,244,193,57,234,135,177,218,2,23,189,213,134, +154,222,47,248,226,83,253,10,77,228,198,37,96,250,88,177,136,17,164,117,226, +90,250,197,42,215,2,86,115,130,235,79,6,28,108,33,39,140,81,253,81,108,206,11, +56,112,90,111,226,212,166,227,166,190,0,14,132,254,236,251,4,76,123,136,209, +99,14,123,189,30,88,15,113,2,115,90,87,235,4,142,156,62,239,91,114,237,63,204, +163,143,154,239,222,47,61,135,176,11,251,245,133,20,125,133,252,217,158,95,28, +125,243,28,151,123,129,204,152,249,121,46,215,184,85,78,221,111,46,246,94,65, +188,245,92,156,109,62,145,59,153,246,129,30,100,136,162,223,35,248,197,179,50, +244,32,200,17,79,244,23,123,31,249,2,155,212,236,168,109,214,149,251,166,247, +6,114,206,103,205,44,71,238,32,199,11,73,215,147,187,132,210,166,49,167,14, +148,176,209,35,248,137,117,115,93,216,123,238,91,254,210,162,230,66,251,155, +57,64,159,178,183,181,167,57,47,114,174,54,185,94,228,93,123,146,243,194,166, +174,23,126,178,255,40,245,216,32,39,114,190,7,208,255,243,53,230,212,121,190, +7,127,97,49,112,95,94,156,251,7,107,241,10,235,195,103,196,133,121,244,79,115, +2,102,206,208,31,245,30,9,198,92,236,217,220,83,25,19,92,37,121,20,92,37,252, +243,231,23,255,227,98,212,156,26,197,128,111,183,111,93,252,223,77,174,204,63, +127,120,241,15,236,107,240,183,217,207,61,82,195,187,61,135,205,28,87,193,181, +144,96,223,116,89,218,177,81,152,224,90,140,9,227,246,179,52,143,148,117,93, +54,111,108,126,109,236,71,54,170,95,224,171,113,98,110,158,175,218,110,91,55, +229,99,28,214,238,15,182,192,101,201,204,147,159,170,119,174,235,214,145,242, +85,155,224,138,197,88,245,206,125,253,110,87,49,147,29,93,43,122,128,15,45, +185,7,174,231,225,10,238,132,81,126,75,187,47,197,196,149,223,92,112,40,70, +239,241,227,88,80,237,205,24,43,142,57,70,127,230,131,223,57,251,0,242,131, +188,98,185,199,106,141,10,126,60,175,136,227,30,217,24,144,161,92,207,195,254, +186,159,224,105,109,106,230,253,120,202,81,88,142,94,84,61,237,99,29,172,7,76, +60,44,214,189,83,234,98,62,241,51,97,226,91,244,208,98,30,234,207,30,208,121, +224,136,25,55,90,127,57,128,6,63,33,207,190,179,254,243,249,168,177,168,52, +199,235,82,92,159,94,198,172,174,133,225,15,108,247,223,60,245,57,240,131,121, +87,108,228,34,247,67,217,55,150,99,142,194,142,105,236,227,56,80,210,203,188, +222,47,241,240,17,181,38,135,13,151,128,59,214,235,1,214,220,179,22,243,67,30, +243,69,198,117,206,7,113,181,54,248,137,241,248,155,192,251,72,115,222,207, +224,218,31,97,211,37,96,174,15,158,115,0,158,239,29,92,91,99,6,135,61,231,9, +167,122,248,133,126,96,252,213,30,115,3,189,214,235,180,71,97,131,125,114,194, +173,145,228,48,108,247,117,177,158,246,233,156,31,173,1,57,252,80,156,175,203, +207,115,185,250,166,114,112,206,49,215,87,137,235,115,239,156,229,107,164,100, +218,7,122,144,33,138,126,143,230,62,155,242,130,156,151,60,155,29,181,77,12, +242,59,245,6,108,66,247,232,69,243,43,109,30,217,175,114,223,240,163,184,30, +188,80,194,254,142,253,137,120,248,133,33,198,170,103,44,200,79,223,179,212, +133,47,90,163,58,143,159,58,15,189,153,251,152,186,200,239,35,157,174,199,62, +65,14,225,11,214,197,56,214,247,158,171,125,196,223,46,194,166,227,129,123,92, +95,206,243,61,228,115,122,143,242,12,2,102,162,83,191,249,217,235,177,128,32, +131,63,158,235,184,31,199,108,231,239,94,252,199,77,122,187,253,219,226,31, +219,163,224,60,2,225,207,127,88,252,125,54,186,221,190,121,241,9,215,229,202, +183,219,175,217,159,164,95,89,12,233,191,47,254,38,199,168,1,75,52,200,164,33, +7,225,79,77,228,244,235,99,16,48,254,48,227,212,55,97,52,18,154,222,41,63,228, +16,131,66,84,202,47,154,113,163,81,255,88,92,109,136,110,43,214,155,109,160, +49,185,65,92,235,220,227,68,28,249,175,6,16,247,78,127,117,118,49,214,161,237, +140,235,7,56,229,110,23,135,152,147,111,16,167,233,219,55,95,23,243,188,38, +204,161,226,230,60,209,191,107,54,249,48,51,247,195,243,90,131,185,54,106,3, +91,240,49,242,64,59,234,91,254,107,76,125,141,156,67,173,11,37,113,160,101,28, +242,201,252,100,92,248,219,109,97,109,198,31,227,186,62,236,42,6,177,228,58, +244,181,29,167,107,99,62,236,40,209,174,99,34,43,240,195,237,193,14,248,233, +11,205,226,152,151,113,145,179,45,85,90,146,106,87,215,39,134,154,147,253,132, +55,174,251,142,56,238,17,149,230,243,160,249,153,120,182,217,215,38,115,45, +149,128,53,103,89,231,87,209,35,170,15,223,176,119,80,183,240,145,31,197,166, +186,88,254,206,24,216,209,26,130,145,35,200,249,83,231,129,115,204,209,31,180, +9,249,195,51,204,9,215,139,35,231,121,206,84,139,158,211,130,115,194,245,102, +248,54,157,111,181,23,34,142,124,62,192,247,156,111,112,206,167,174,25,245, +235,56,80,210,203,188,30,27,250,45,226,131,222,53,196,246,47,92,106,206,176, +22,30,82,240,133,0,228,208,71,45,52,39,113,142,99,46,244,96,218,209,124,100, +28,108,194,94,172,153,207,136,184,162,62,206,49,126,168,161,95,240,83,123,48, +242,228,18,242,51,189,97,156,182,36,114,88,251,32,226,1,71,254,116,175,7,198, +115,135,223,96,16,215,251,10,24,61,103,129,59,253,45,12,196,12,189,83,183,151, +71,152,211,123,20,28,47,235,172,3,123,100,250,82,174,246,125,244,131,226,214, +44,203,31,63,207,229,90,67,149,131,35,127,145,95,213,107,125,178,28,53,70,46, +71,223,156,48,22,93,211,131,12,33,122,65,51,103,61,79,222,215,209,95,121,63, +90,158,155,109,212,207,109,214,90,114,126,191,143,184,220,185,214,150,236,87, +225,23,165,29,203,26,79,52,229,151,123,200,125,86,61,99,97,31,65,162,107,69, +46,88,115,141,149,243,162,87,117,30,117,209,115,125,30,124,130,205,199,47,154, +170,139,252,97,77,167,56,107,232,127,127,63,209,216,226,154,121,8,84,175,7, +253,192,243,43,176,156,95,49,209,243,192,226,217,20,185,2,158,62,213,30,208, +124,169,221,240,9,215,196,196,28,191,250,206,197,127,184,248,239,23,255,248, +93,234,124,187,125,126,241,31,217,149,190,112,118,220,143,44,254,171,61,250, +179,197,191,106,215,29,199,171,42,87,190,221,254,103,241,183,239,209,31,64, +176,232,119,23,223,231,169,1,219,72,32,147,134,28,132,160,189,32,209,56,138, +33,14,73,226,139,7,37,248,217,15,15,202,129,139,34,247,98,196,92,74,176,46, +198,121,3,177,41,189,113,92,202,130,233,129,194,195,25,182,216,188,170,11,27, +216,212,104,18,31,51,22,199,57,247,56,49,158,30,6,222,229,69,51,252,153,55, +205,244,96,139,121,190,41,32,65,126,65,192,99,12,253,84,15,207,173,199,239, +227,233,48,98,172,33,197,26,192,78,177,168,77,72,35,166,140,13,191,40,241,56, +114,173,137,197,218,92,207,165,161,131,47,186,94,62,20,162,7,152,251,94,175, +208,81,2,59,176,87,111,150,208,123,157,32,137,121,129,193,92,30,204,148,248, +203,177,247,60,226,200,118,233,31,228,200,19,230,245,131,246,202,218,249,102, +22,120,181,19,135,163,175,135,235,168,101,223,143,176,3,157,82,255,102,84,115, +182,36,149,12,157,241,169,102,134,161,166,199,21,120,165,211,30,69,76,74,140, +43,244,201,207,205,200,133,211,212,123,117,109,165,105,63,70,238,179,206,175, +78,49,186,111,32,248,100,26,203,77,207,95,234,135,11,24,228,197,109,198,250, +148,229,126,228,92,173,15,240,200,55,100,152,3,121,245,189,249,3,194,245,102, +246,155,74,122,45,96,131,123,229,1,78,9,227,197,140,109,62,47,149,124,157,156, +43,158,111,208,129,216,47,208,228,7,11,93,79,243,151,109,129,139,94,230,209, +79,197,198,126,196,250,158,111,48,207,144,26,19,207,10,173,37,174,193,88,139, +117,225,250,60,67,242,126,246,43,207,231,189,199,246,167,226,96,11,113,224, +139,15,218,123,140,101,237,66,19,218,176,101,253,177,57,242,228,18,242,51,189, +98,156,17,11,243,87,207,48,230,216,235,11,162,143,138,227,217,169,125,22,215, +181,6,196,42,99,237,233,57,0,117,209,231,5,216,205,231,17,217,175,162,238,148, +102,123,113,159,80,154,94,160,176,78,93,119,58,47,217,155,117,157,147,92,253, +83,57,56,231,111,250,210,39,116,89,14,31,145,147,108,179,230,88,107,69,54,31, +149,12,33,250,125,21,61,84,109,176,39,225,83,212,35,239,199,121,127,240,188, +128,110,252,210,96,240,229,46,119,50,109,214,107,204,225,23,198,61,246,30,188, +80,194,62,203,99,244,20,226,165,87,174,203,207,10,57,86,230,32,114,164,243, +168,139,253,174,243,184,30,230,33,190,233,183,150,81,47,237,107,234,188,135, +160,7,107,143,195,143,211,47,83,208,95,32,204,197,23,114,196,6,245,58,50,6, +216,198,26,92,167,98,34,183,136,7,140,181,96,27,126,78,47,175,88,211,113,81, +95,202,152,71,174,249,21,153,243,19,139,127,127,49,98,248,185,197,212,184,62, +112,126,245,29,139,255,124,241,223,44,254,98,194,128,111,183,63,93,252,179, +123,244,189,139,241,79,167,190,110,192,241,170,202,149,187,228,235,239,215,91, +162,6,118,123,142,7,11,254,244,100,59,77,15,37,94,56,149,66,86,31,24,128,241, +132,158,214,76,152,205,180,175,146,104,186,74,108,96,199,69,195,240,70,169, +205,18,54,80,104,151,198,6,113,137,115,143,19,243,242,122,196,189,246,69,19, +62,210,30,52,115,163,158,94,52,105,151,146,136,161,142,243,188,138,3,79,185, +158,112,145,187,231,88,200,128,173,113,95,171,53,184,231,94,235,8,251,216,136, +188,137,67,170,7,88,244,0,252,154,254,189,91,232,40,153,99,139,67,217,125,166, +79,122,32,18,3,63,193,176,7,140,31,110,115,30,232,159,199,16,135,167,214,63, +236,250,218,188,214,181,227,42,247,181,218,225,225,232,107,121,223,199,56,219, +3,65,167,245,116,219,15,95,26,42,45,76,181,27,123,103,227,241,51,201,31,224, +141,181,198,129,211,28,145,21,87,252,44,204,122,86,233,180,54,153,107,169,4, +172,57,203,58,191,138,126,83,125,248,230,191,157,138,56,248,81,108,170,139, +229,239,49,6,140,26,227,39,227,36,10,215,211,153,94,99,6,30,243,127,106,49, +228,167,51,236,238,15,8,215,139,35,231,121,142,203,149,250,77,95,231,47,137, +19,174,55,51,158,62,79,123,193,253,135,159,57,87,241,64,229,56,80,251,171,149, +178,38,98,100,253,76,99,31,199,129,146,94,230,209,31,197,198,76,205,95,228, +190,246,56,207,10,96,112,175,192,156,120,49,241,90,146,25,183,238,253,136,19, +126,248,189,198,114,154,112,121,69,207,7,113,212,78,54,177,158,231,154,49,43, +142,53,84,95,193,145,39,151,144,159,233,117,93,228,0,117,189,175,93,98,169, +245,5,211,87,173,111,63,95,163,231,234,153,184,70,78,91,50,251,153,237,129, +231,125,16,254,69,221,49,230,39,112,212,71,15,115,93,238,105,197,177,71,188, +110,32,228,157,185,87,220,142,3,63,69,118,150,107,13,85,14,142,53,25,111,173, +1,239,59,253,204,62,201,163,174,78,245,140,50,31,149,32,187,235,35,167,103, +159,184,6,242,173,117,243,171,208,81,26,26,198,10,155,111,251,162,153,107,166, +212,238,73,219,204,72,5,187,165,36,140,69,7,202,251,50,235,253,10,126,229,243, +149,57,136,115,70,231,81,135,188,241,60,211,121,92,135,123,5,18,173,187,247, +130,238,3,151,112,127,98,45,248,226,82,239,127,124,17,70,155,167,254,34,123, +77,113,15,131,45,196,14,27,136,63,63,111,228,61,9,61,158,203,234,253,11,115, +245,221,72,233,227,161,223,216,51,186,38,53,204,47,175,153,211,152,243,235, +246,39,34,9,75,217,46,56,143,190,127,241,63,45,254,235,36,5,223,110,63,36,35, +240,15,46,254,134,36,1,251,85,149,43,207,82,242,190,82,3,187,5,199,38,68,81, +88,112,50,174,167,135,146,218,0,51,150,24,54,166,115,63,96,58,198,237,171,68, +215,200,216,233,191,76,142,194,230,166,159,108,196,6,113,137,115,143,19,243, +152,159,140,123,205,139,38,54,12,190,93,136,27,73,111,84,230,70,101,148,135, +93,74,34,134,58,206,243,42,14,60,229,122,194,157,106,60,97,195,191,140,189,86, +107,112,207,125,228,134,135,16,24,235,96,227,231,154,68,15,208,7,237,1,176, +234,40,153,99,203,118,226,129,91,123,56,247,27,94,24,224,51,236,210,30,190, +173,170,15,46,156,3,12,106,63,191,104,242,192,244,181,127,116,49,236,95,249, +109,37,244,129,137,7,170,137,114,222,192,244,11,107,210,39,50,235,166,184,176, +91,235,73,238,251,60,246,142,226,220,247,154,163,130,31,207,43,226,238,62,56, +25,202,245,131,159,134,225,53,215,246,145,243,180,54,53,61,15,96,205,89,214, +249,149,247,71,205,117,244,93,244,3,214,56,61,36,221,235,98,62,105,156,3,102, +49,226,139,127,26,16,178,233,76,175,245,113,223,156,243,94,102,94,153,191,144, +58,99,45,196,82,207,31,141,55,52,53,214,199,189,229,121,122,246,111,52,125, +173,158,79,238,45,229,169,126,204,49,71,136,7,122,224,96,167,174,91,243,238, +76,127,84,146,103,122,254,34,143,53,23,244,213,237,35,111,192,122,141,48,199, +231,51,167,234,91,156,77,172,5,49,184,174,15,104,199,88,77,222,109,134,157, +141,1,37,220,92,107,92,67,150,247,65,204,138,181,179,94,207,67,143,197,52,109, +221,192,42,119,187,244,29,182,38,202,53,187,98,15,204,248,188,255,192,145,3, +197,209,94,207,79,141,67,251,130,60,219,139,251,128,51,252,235,231,205,178, +254,48,95,248,169,114,174,199,251,142,202,193,156,227,189,215,109,174,209,139, +214,114,185,115,213,175,81,37,67,184,158,243,243,62,84,61,152,122,228,79,235, +166,136,200,119,63,47,184,199,14,126,153,116,144,59,153,54,235,53,230,240,11, +227,190,6,8,126,77,84,239,95,123,69,18,198,162,211,115,155,125,167,250,232,35, +234,245,89,35,246,125,175,55,117,145,123,157,199,245,98,223,107,108,140,63, +246,18,176,174,211,222,163,196,25,182,64,189,78,100,29,121,156,176,129,251,32, +100,176,11,121,222,187,81,11,224,97,155,177,42,134,177,196,252,192,18,81,125, +161,14,28,185,225,53,206,29,216,232,251,153,127,242,223,101,222,110,255,188, +248,139,38,115,125,198,225,37,242,47,23,255,237,226,159,52,217,140,235,92,37, +39,185,242,44,37,239,43,53,176,91,112,104,66,38,0,201,195,8,63,65,211,67,9, +146,116,191,209,44,6,150,227,140,67,98,33,247,102,193,207,47,23,12,230,198, +195,54,127,98,156,55,16,155,25,69,99,195,82,138,185,249,155,4,226,96,131,7, +109,111,122,248,174,54,96,147,235,59,206,153,216,104,36,174,199,185,25,247,46, +127,117,54,114,167,190,18,135,181,167,7,219,176,75,137,218,203,227,60,175,226, +192,140,81,113,145,39,176,75,79,53,134,77,200,21,203,185,122,112,16,123,173, +214,196,210,47,149,134,142,255,35,24,71,248,201,92,184,62,122,128,242,238,135, +251,12,127,32,193,79,208,163,7,2,124,41,192,24,251,77,200,243,10,140,251,5,44, +198,253,55,47,145,95,196,135,181,217,83,122,8,231,67,31,220,49,140,19,54,180, +159,243,141,42,252,167,239,193,240,147,123,83,165,17,139,199,225,243,115,141, +34,238,90,123,224,49,174,125,18,113,134,116,142,235,132,175,24,226,184,71,214, +200,201,80,174,63,251,9,198,120,234,189,180,182,217,164,230,180,31,35,103,42, +231,218,96,206,235,125,232,185,197,122,144,32,231,216,15,211,111,249,106,93, +122,62,58,198,237,105,220,184,158,206,244,169,62,62,31,185,203,245,100,108, +174,71,124,174,241,92,63,250,235,116,22,175,147,161,20,119,174,153,207,167, +108,190,177,43,30,254,193,70,253,150,29,235,43,110,170,31,125,227,8,118,160,7, +142,222,6,238,116,95,137,181,21,155,237,194,15,96,136,51,173,125,2,223,207, +129,26,31,214,196,189,174,251,22,249,242,250,68,254,114,47,170,79,41,86,147, +103,155,94,23,239,217,96,237,71,158,77,218,83,190,246,248,91,161,125,21,107, +103,125,61,51,179,182,239,3,172,171,56,230,77,99,102,143,41,135,127,125,159, +34,102,232,21,55,253,213,237,154,27,175,111,142,135,185,1,22,118,230,60,131, +117,62,37,115,79,229,88,206,121,118,220,156,175,238,39,115,254,65,203,7,184, +230,175,238,197,243,90,115,12,11,165,132,177,232,154,30,100,8,215,247,126,203, +122,176,230,60,228,180,197,17,124,227,115,163,250,77,219,228,26,143,207,231, +167,201,157,76,155,245,134,217,87,169,23,246,71,113,61,120,161,130,221,82,18, +198,162,243,88,98,31,169,158,53,155,251,39,242,203,243,71,231,81,7,223,121, +134,246,121,145,215,171,186,216,239,92,143,236,190,129,40,175,245,136,243,50, +124,213,53,244,218,145,96,230,3,115,192,184,230,218,138,97,126,16,39,116,176, +133,151,87,216,155,115,173,57,161,93,16,122,31,191,180,192,79,80,190,79,198, +108,240,231,22,255,201,226,233,55,149,248,13,230,223,45,254,233,197,161,81,12, +56,143,130,171,228,36,87,158,165,228,125,165,6,44,41,32,147,134,28,132,4,59, +161,24,108,56,197,16,135,68,251,191,69,3,225,97,35,55,24,152,141,228,9,6,193, +94,46,48,49,186,46,48,88,59,63,0,230,27,174,19,27,73,15,57,54,67,52,147,54,98, +222,72,78,241,141,191,227,156,105,159,27,146,140,88,122,12,239,254,159,1,121, +252,57,102,202,255,239,95,52,231,60,241,70,84,107,28,54,241,159,38,57,49,71, +154,123,240,213,90,131,123,238,195,86,247,45,31,138,221,255,156,195,238,199, +220,235,249,208,98,143,99,204,79,197,192,95,198,93,231,212,60,100,172,251,89, +255,7,53,191,242,253,131,159,185,215,233,15,214,80,226,154,25,195,27,251,146, +216,190,167,6,12,63,114,110,88,79,223,215,78,253,165,33,226,174,181,152,207, +130,136,67,41,234,171,113,61,194,43,134,56,238,145,53,114,90,242,176,21,126, +130,129,83,98,79,43,2,204,181,239,181,52,155,212,112,45,197,130,117,95,101, +185,247,24,215,233,125,224,185,99,109,201,30,119,61,11,166,186,124,117,192, +232,254,158,236,35,7,87,95,52,193,192,247,60,69,94,39,191,184,94,175,105,242, +199,201,80,138,59,247,22,40,246,97,207,231,189,23,132,49,102,92,46,233,251,31, +84,31,204,233,27,71,88,15,121,69,172,244,54,112,167,243,18,52,190,84,137,93, +159,67,255,76,107,159,132,223,87,222,23,90,203,199,243,181,118,49,7,177,32, +135,218,3,234,83,138,213,228,221,230,68,185,71,162,134,138,71,206,123,95,196, +40,214,206,122,208,148,95,16,99,87,44,235,171,235,18,83,206,87,167,45,113,251, +211,111,202,107,143,195,118,143,131,235,122,126,65,243,89,200,126,73,251,205, +252,224,167,218,211,62,61,157,173,213,191,211,254,131,111,124,46,202,114,224, +115,253,40,119,187,253,188,96,125,225,27,99,232,107,33,46,172,85,207,68,248,0, +155,89,190,102,43,97,44,186,166,7,25,194,245,241,98,194,30,179,25,246,241,17, +8,241,192,95,141,147,182,56,10,159,53,199,148,99,222,39,83,239,218,124,126, +154,220,201,180,89,111,152,125,21,126,81,218,176,219,204,72,5,187,165,36,140, +69,231,61,133,122,247,30,166,46,124,209,125,80,231,169,221,152,199,123,143, +230,142,186,232,187,71,58,93,143,123,196,243,174,4,31,84,158,239,147,236,75, +216,140,243,154,236,251,104,222,67,244,69,207,140,254,69,18,109,143,252,36, +215,32,252,84,109,176,214,160,234,200,159,111,146,219,237,183,101,20,92,37, +121,20,92,37,39,185,242,44,37,239,43,53,96,73,1,153,52,228,32,29,145,235,161, +11,102,19,116,174,155,112,42,76,181,119,42,94,95,55,143,148,249,225,168,218, +83,159,102,191,163,41,171,230,20,103,245,13,227,44,243,171,217,246,235,237, +134,60,75,102,158,236,169,222,185,226,78,53,1,107,62,193,122,192,40,14,92,177, +179,93,222,28,170,116,242,213,175,38,157,174,85,215,185,26,95,197,213,81,72, +85,147,117,19,215,60,76,254,131,231,24,112,64,225,80,197,225,202,149,93,115, +178,163,113,20,140,211,93,86,99,190,226,27,57,143,42,95,141,121,177,249,195, +79,72,39,124,245,21,44,56,167,53,82,28,101,62,170,252,196,38,56,205,127,132, +175,186,98,231,37,57,121,106,11,124,5,51,113,157,7,46,115,83,204,224,62,39, +143,38,230,39,36,195,26,160,53,202,184,58,202,140,115,6,15,11,124,96,80,141, +216,55,187,161,201,254,199,222,202,156,235,211,109,220,53,246,9,201,201,30, +184,214,252,145,93,112,181,93,71,207,88,231,151,124,39,206,245,60,250,100,242, +87,218,76,58,101,181,231,18,29,101,59,228,235,235,190,168,190,160,132,1,215, +154,157,214,230,39,36,215,214,29,113,230,199,107,237,93,245,143,247,146,254, +207,20,124,126,205,227,73,14,174,190,85,159,248,92,128,123,123,126,169,61,219, +180,28,56,153,246,129,30,100,8,215,235,179,214,146,52,61,49,208,241,37,42,228, +196,6,10,47,36,231,223,126,215,56,125,62,63,77,238,100,218,172,55,76,147,80, +218,52,219,204,72,5,187,165,36,140,69,231,177,204,47,212,124,89,71,252,124,89, +215,88,227,165,137,47,154,90,63,206,139,231,64,181,201,245,34,239,154,87,206, +11,155,186,94,237,175,19,215,62,186,58,175,214,49,230,113,143,76,152,53,122, +68,134,86,124,216,68,252,250,69,144,19,214,202,243,98,118,230,42,201,163,224, +42,201,163,224,42,57,201,149,103,41,121,95,169,129,157,150,158,152,45,78,84, +49,155,183,54,19,228,130,25,113,134,120,130,1,25,234,2,14,100,200,3,46,233,88, +120,20,151,5,38,163,201,251,95,107,35,111,43,153,32,23,140,225,246,135,227,56, +152,250,161,69,222,150,50,25,170,224,246,71,101,38,191,66,192,201,156,227,60, +67,93,192,129,12,169,88,61,96,150,68,169,97,215,72,105,75,231,23,77,193,134, +164,235,156,76,123,208,23,221,56,31,100,168,151,227,182,244,76,5,127,205,46, +15,246,248,38,245,62,211,62,215,237,28,48,78,5,123,213,230,17,231,100,232,55, +198,27,34,99,174,224,182,116,166,130,125,58,7,58,193,37,60,126,138,236,46,119, +50,237,3,189,146,33,159,96,13,241,4,51,145,205,202,243,158,206,133,94,176,79, +241,32,155,113,97,142,161,174,224,20,1,174,15,25,135,121,32,67,62,193,93,193, +128,10,238,205,176,32,67,191,0,95,201,102,95,152,123,21,7,186,138,125,37,174, +97,77,155,245,13,163,4,157,224,142,88,67,189,63,123,159,125,156,255,85,191, +195,190,49,233,53,249,93,231,132,177,232,64,124,96,215,151,14,242,140,223,114, +39,211,170,62,158,169,130,53,14,127,214,218,186,209,134,190,240,132,220,176, +160,45,113,76,188,38,40,166,218,220,58,147,14,114,39,211,102,125,195,56,65,46, +24,227,173,26,169,96,183,148,132,177,232,52,170,254,75,16,214,12,177,159,190, +212,134,30,148,127,251,29,114,126,249,167,117,137,245,80,27,218,118,9,125,192, +28,62,143,235,122,235,234,10,149,57,239,52,47,141,40,105,152,71,100,232,130, +79,163,19,235,188,170,115,174,146,60,10,174,146,60,10,174,146,147,92,121,150, +146,247,149,26,216,105,233,137,217,226,68,21,179,121,107,51,65,46,152,17,103, +136,39,24,144,161,46,224,64,134,60,224,146,238,11,247,43,52,189,19,155,191,31, +136,224,109,37,19,228,130,49,220,254,112,204,67,15,196,13,121,56,108,43,25, +170,224,246,71,101,38,191,66,192,201,156,227,60,67,93,192,129,12,169,88,30, +204,95,123,209,124,64,5,127,205,110,28,222,143,110,158,38,171,116,5,227,84, +176,87,109,30,113,78,134,126,99,188,33,50,230,10,110,75,103,42,216,167,115, +160,19,92,194,227,167,200,238,114,39,211,62,208,43,25,242,9,214,16,79,48,19, +217,172,60,239,233,92,232,5,251,20,15,178,25,23,230,24,234,2,174,146,205,186, +56,207,144,79,112,87,48,160,130,123,51,44,200,208,47,192,87,178,217,23,230,94, +197,129,174,98,95,137,107,88,211,102,125,195,40,65,39,184,35,214,80,239,207, +222,103,31,199,47,47,63,176,231,32,149,239,249,38,189,38,191,235,156,48,22, +221,171,215,114,50,173,234,243,51,155,83,252,51,6,95,111,177,211,26,85,27,87, +94,52,201,249,153,109,35,206,126,155,116,144,59,153,54,235,27,198,9,114,193, +24,111,213,72,5,187,165,36,140,69,103,250,52,210,56,37,135,198,58,55,158,157, +201,143,230,229,154,103,221,213,245,214,213,21,42,115,222,116,158,33,158,96, +148,12,253,2,188,147,205,242,57,58,91,185,74,242,40,184,74,242,40,184,74,78, +114,229,89,74,182,63,111,183,255,5,75,238,218,119,32,100,170,216,0,0,0,0,73, +69,78,68,174,66,96,130 }; +static const char* +default_charset = R"( abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.!?;:-_/|\!'"+=*()[]{}&%$#@<>^`~)"; +#include "libjin/jin.h" + +static const JinEngine::Graphics::Color default_font_split(255, 0, 255, 255); diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 8bd308b..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifdef _WIN32 -# include <SDL2/SDL_Main.h> -# include <direct.h> -#endif - -#include "lua/modules/luax.h" -#include "lua/modules/jin.h" -#include "libjin/jin.h" -#include <Windows.h> - -using namespace jin::lua; - -int main(int argc, char* argv[]) -{ - lua_State* L = luax_newstate(); - - luax_openlibs(L); - luaopen_jin(L); - - // add args to global field - luax_newtable(L); - for (int i = 0; i < argc; ++i) - luax_setraw_string(L, -2, i + 1, argv[i]); - luax_setfield(L, -2, "_argv"); - - const int BUFFER_SIZE = 512; - char buffer[BUFFER_SIZE]; -#ifdef _WIN32 - _getcwd(buffer, BUFFER_SIZE); -#elif defined __unix__ -#elif defined __APPLE__ -#endif - luax_setfield_string(L, "_dir", buffer); - boot(L); - luax_close(L); - - return 0; -}
\ No newline at end of file |